diff --git a/.travis.yml b/.travis.yml
index 3166ed78..1131bff3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -227,7 +227,6 @@ matrix:
- compiler: clang-3.9
- compiler: clang-4.0
- compiler: clang-5.0
- - compiler: gcc-8
cache:
apt: true
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e141537c..d8194764 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.0)
project(SRB2
- VERSION 2.1.20
+ VERSION 2.1.23
LANGUAGES C)
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})
diff --git a/SRB2_Debug.props b/SRB2_Debug.props
index 8be11c58..74177c6e 100644
--- a/SRB2_Debug.props
+++ b/SRB2_Debug.props
@@ -22,6 +22,7 @@
Debug
+ true
diff --git a/SRB2_Release.props b/SRB2_Release.props
index a216ea45..905dfdcf 100644
--- a/SRB2_Release.props
+++ b/SRB2_Release.props
@@ -24,6 +24,7 @@
DebugFastLink
true
true
+ true
diff --git a/SRB2_common.props b/SRB2_common.props
index 2fb2eb8c..0f80ceb1 100644
--- a/SRB2_common.props
+++ b/SRB2_common.props
@@ -18,7 +18,7 @@
4244;4267
- ws2_32.lib;%(AdditionalDependencies)
+ advapi32.lib;ws2_32.lib;%(AdditionalDependencies)
Windows
false
true
diff --git a/appveyor.yml b/appveyor.yml
index bf7eadd2..e7ce1b2f 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -50,7 +50,7 @@ cache:
- upx391w.zip
- ccache.exe
- C:\Users\appveyor\.ccache
-- assets\deployer\archives
+- C:\Users\appveyor\srb2_cache
install:
- if [%CONFIGURATION%] == [SDL64] ( set "X86_64=1" )
diff --git a/debian/changelog b/debian/changelog
index 855c1c1b..b06a78e2 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,6 +1,6 @@
-srb2 (2.1.21~9) trusty; urgency=high
+srb2 (2.1.23~9) trusty; urgency=high
- * SRB2 v2.1.21 release
+ * SRB2 v2.1.23 release
-- Marco Zafra Mon, 27 Nov 2018 16:45:00 -0500
diff --git a/debian/control b/debian/control
index ce3b33fb..0f2d8062 100644
--- a/debian/control
+++ b/debian/control
@@ -18,7 +18,7 @@ Homepage: http://www.srb2.org
Package: srb2
Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}, srb2-data (>= 2.1.15), srb2-data (<= 2.1.21)
+Depends: ${shlibs:Depends}, ${misc:Depends}, srb2-data (>= 2.1.15), srb2-data (<= 2.1.23)
Description: A cross-platform 3D Sonic fangame
Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog
fangame built using a modified version of the Doom Legacy
@@ -31,7 +31,7 @@ Description: A cross-platform 3D Sonic fangame
Package: srb2-dbg
Architecture: any
# FIXME: should be Depends: ${shlibs:Depends}, ${misc:Depends}, srb2-data (= 2.1.14), srb2 but dh_shlibdeps is being an asshat
-Depends: libc6, ${misc:Depends}, srb2-data (>= 2.1.15), srb2-data (<= 2.1.21), srb2
+Depends: libc6, ${misc:Depends}, srb2-data (>= 2.1.15), srb2-data (<= 2.1.23), srb2
Description: A cross-platform 3D Sonic fangame
Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog
fangame built using a modified version of the Doom Legacy
diff --git a/debian/rules b/debian/rules
index 02e3dc78..ff80d50b 100755
--- a/debian/rules
+++ b/debian/rules
@@ -59,6 +59,7 @@ DBGNAME = debug/$(EXENAME)
PKGDIR = usr/games/SRB2
DBGDIR = usr/lib/debug/$(PKGDIR)
+LINKDIR = usr/games
PIXMAPS_DIR = usr/share/pixmaps
DESKTOP_DIR = usr/share/applications
PREFIX = $(shell test "$(CROSS_COMPILE_BUILD)" != "$(CROSS_COMPILE_HOST)" && echo "PREFIX=$(CROSS_COMPILE_HOST)")
@@ -133,7 +134,7 @@ binary-arch:
# dh_installcron
# dh_installinfo
# dh_installman
- # dh_link
+ dh_link $(PKGDIR)/$(EXENAME) $(LINKDIR)/$(EXENAME)
dh_compress
dh_fixperms
# dh_perl
diff --git a/deployer/appveyor/deployer.bat b/deployer/appveyor/deployer.bat
index 7b1bc68a..fae38859 100644
--- a/deployer/appveyor/deployer.bat
+++ b/deployer/appveyor/deployer.bat
@@ -49,12 +49,14 @@ if [%APPVEYOR_REPO_TAG%] == [true] (
: Get asset archives
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-if [%ASSET_CLEAN%] == [1] (
- echo Cleaning asset archives...
- rmdir /s /q "assets\deployer\archives"
+if exist "C:\Users\appveyor\srb2_cache\archives\" (
+ if [%ASSET_CLEAN%] == [1] (
+ echo Cleaning asset archives...
+ rmdir /s /q "C:\Users\appveyor\srb2_cache\archives"
+ )
)
-if not exist "assets\deployer\archives" mkdir "assets\deployer\archives"
+if not exist "C:\Users\appveyor\srb2_cache\archives\" mkdir "C:\Users\appveyor\srb2_cache\archives"
goto EXTRACT_ARCHIVES
@@ -69,7 +71,7 @@ for %%a in (%archivepath%) do (
set "filename=%%~nxa"
)
-set "localarchivepath=assets\deployer\archives\%filename%"
+set "localarchivepath=C:\Users\appveyor\srb2_cache\archives\%filename%"
goto EOF
@@ -112,20 +114,20 @@ if [%ASSET_FILES_OPTIONAL_GET%] == [1] (
: Build the installers
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-mkdir "assets\deployer\installer"
-mkdir "assets\deployer\patch"
+mkdir "assets\installer"
+mkdir "assets\patch"
-7z x -y "%ASSET_ARCHIVE_PATH_LOCAL%" -o"assets\deployer\installer" >null
-7z x -y "%ASSET_ARCHIVE_PATCH_PATH_LOCAL%" -o"assets\deployer\patch" >null
+7z x -y "%ASSET_ARCHIVE_PATH_LOCAL%" -o"assets\installer" >null
+7z x -y "%ASSET_ARCHIVE_PATCH_PATH_LOCAL%" -o"assets\patch" >null
: Copy optional files to full installer (music.dta)
if [%ASSET_FILES_OPTIONAL_GET%] == [1] (
- 7z x -y "%ASSET_ARCHIVE_OPTIONAL_PATH_LOCAL%" -o"assets\deployer\installer" >null
+ 7z x -y "%ASSET_ARCHIVE_OPTIONAL_PATH_LOCAL%" -o"assets\installer" >null
)
: Copy EXE -- BUILD_PATH is from appveyor.yml
-robocopy /S /ns /nc /nfl /ndl /np /njh /njs "%BUILD_PATH%" "assets\deployer\installer" /XF "*.debug" ".gitignore"
-robocopy /S /ns /nc /nfl /ndl /np /njh /njs "%BUILD_PATH%" "assets\deployer\patch" /XF "*.debug" ".gitignore"
+robocopy /S /ns /nc /nfl /ndl /np /njh /njs "%BUILD_PATH%" "assets\installer" /XF "*.debug" ".gitignore"
+robocopy /S /ns /nc /nfl /ndl /np /njh /njs "%BUILD_PATH%" "assets\patch" /XF "*.debug" ".gitignore"
: Are we building DD? (we were supposed to exit earlier!)
if [%CONFIGURATION%] == [DD] ( set "DPL_INSTALLER_NAME=%DPL_INSTALLER_NAME%-DD" )
@@ -145,16 +147,16 @@ if not [%X86_64%] == [1] ( goto X86_INSTALL )
::::::::::::::::::::::::::::::::
: Extract DLL binaries
-7z x -y "%ASSET_ARCHIVE_X64_PATH_LOCAL%" -o"assets\deployer\installer" >null
+7z x -y "%ASSET_ARCHIVE_X64_PATH_LOCAL%" -o"assets\installer" >null
if [%PACKAGE_PATCH_DLL_GET%] == [1] (
- 7z x -y "!ASSET_ARCHIVE_X64_PATH_LOCAL!" -o"assets\deployer\patch" >null
+ 7z x -y "!ASSET_ARCHIVE_X64_PATH_LOCAL!" -o"assets\patch" >null
)
: Build the installer
-7z a -sfx7z.sfx "%DPL_INSTALLER_NAME%-x64-Installer%INSTALLER_SUFFIX%.exe" .\assets\deployer\installer\*
+7z a -sfx7z.sfx "%DPL_INSTALLER_NAME%-x64-Installer%INSTALLER_SUFFIX%.exe" .\assets\installer\*
: Build the patch
-7z a "%DPL_INSTALLER_NAME%-x64-Patch%INSTALLER_SUFFIX%.zip" .\assets\deployer\patch\*
+7z a "%DPL_INSTALLER_NAME%-x64-Patch%INSTALLER_SUFFIX%.zip" .\assets\patch\*
: Upload artifacts
appveyor PushArtifact "%DPL_INSTALLER_NAME%-x64-Installer%INSTALLER_SUFFIX%.exe"
@@ -168,16 +170,16 @@ goto EOF
::::::::::::::::::::::::::::::::
: Extract DLL binaries
-7z x -y "%ASSET_ARCHIVE_X86_PATH_LOCAL%" -o"assets\deployer\installer" >null
+7z x -y "%ASSET_ARCHIVE_X86_PATH_LOCAL%" -o"assets\installer" >null
if [%PACKAGE_PATCH_DLL_GET%] == [1] (
- 7z x -y "!ASSET_ARCHIVE_X86_PATH_LOCAL!" -o"assets\deployer\patch" >null
+ 7z x -y "!ASSET_ARCHIVE_X86_PATH_LOCAL!" -o"assets\patch" >null
)
: Build the installer
-7z a -sfx7z.sfx "%DPL_INSTALLER_NAME%-Installer%INSTALLER_SUFFIX%.exe" .\assets\deployer\installer\*
+7z a -sfx7z.sfx "%DPL_INSTALLER_NAME%-Installer%INSTALLER_SUFFIX%.exe" .\assets\installer\*
: Build the patch
-7z a "%DPL_INSTALLER_NAME%-Patch%INSTALLER_SUFFIX%.zip" .\assets\deployer\patch\*
+7z a "%DPL_INSTALLER_NAME%-Patch%INSTALLER_SUFFIX%.zip" .\assets\patch\*
: Upload artifacts
appveyor PushArtifact "%DPL_INSTALLER_NAME%-Installer%INSTALLER_SUFFIX%.exe"
diff --git a/libs/SDL2/lib/ARM/SDL2.lib b/libs/SDL2/lib/ARM/SDL2.lib
new file mode 100644
index 00000000..be9d8694
Binary files /dev/null and b/libs/SDL2/lib/ARM/SDL2.lib differ
diff --git a/libs/SDL2/lib/ARM64/SDL2.dll b/libs/SDL2/lib/ARM64/SDL2.dll
new file mode 100644
index 00000000..f9eac1c0
Binary files /dev/null and b/libs/SDL2/lib/ARM64/SDL2.dll differ
diff --git a/libs/SDL2/lib/ARM64/SDL2.lib b/libs/SDL2/lib/ARM64/SDL2.lib
new file mode 100644
index 00000000..40904c30
Binary files /dev/null and b/libs/SDL2/lib/ARM64/SDL2.lib differ
diff --git a/libs/SDL2_mixer/lib/ARM/SDL2_mixer.lib b/libs/SDL2_mixer/lib/ARM/SDL2_mixer.lib
new file mode 100644
index 00000000..3886f3aa
Binary files /dev/null and b/libs/SDL2_mixer/lib/ARM/SDL2_mixer.lib differ
diff --git a/libs/SDL2_mixer/lib/ARM64/SDL2_mixer.dll b/libs/SDL2_mixer/lib/ARM64/SDL2_mixer.dll
new file mode 100644
index 00000000..d5650b0d
Binary files /dev/null and b/libs/SDL2_mixer/lib/ARM64/SDL2_mixer.dll differ
diff --git a/libs/SDL2_mixer/lib/ARM64/SDL2_mixer.lib b/libs/SDL2_mixer/lib/ARM64/SDL2_mixer.lib
new file mode 100644
index 00000000..58c3e696
Binary files /dev/null and b/libs/SDL2_mixer/lib/ARM64/SDL2_mixer.lib differ
diff --git a/libs/libpng-src/projects/visualc10/.gitignore b/libs/libpng-src/projects/visualc10/.gitignore
index 118a15cb..e1bec81f 100644
--- a/libs/libpng-src/projects/visualc10/.gitignore
+++ b/libs/libpng-src/projects/visualc10/.gitignore
@@ -1,3 +1,5 @@
/Win32
/x64
/libpng.vcproj.*.*.user
+/ARM
+/ARM64
diff --git a/libs/libpng-src/projects/visualc10/libpng.vcxproj b/libs/libpng-src/projects/visualc10/libpng.vcxproj
index fb53826e..eaa3d4ff 100644
--- a/libs/libpng-src/projects/visualc10/libpng.vcxproj
+++ b/libs/libpng-src/projects/visualc10/libpng.vcxproj
@@ -1,6 +1,14 @@
+
+ Debug
+ ARM
+
+
+ Debug
+ ARM64
+
Debug
Win32
@@ -9,6 +17,14 @@
Debug
x64
+
+ Release
+ ARM
+
+
+ Release
+ ARM64
+
Release
Win32
@@ -21,7 +37,7 @@
{72B01ACA-7A1A-4F7B-ACEF-2607299CF052}
libpng
- 8.1
+ 10.0.16299.0
@@ -29,21 +45,45 @@
false
v140
+
+ StaticLibrary
+ false
+ v141
+ true
+
StaticLibrary
false
v140
+
+ StaticLibrary
+ false
+ v141
+ true
+
StaticLibrary
false
v140
+
+ StaticLibrary
+ false
+ v141
+ true
+
StaticLibrary
false
v140
+
+ StaticLibrary
+ false
+ v141
+ true
+
@@ -51,29 +91,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<_ProjectFileVersion>10.0.30319.1
$(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
$(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
$(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
$(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
$(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
$(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
$(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
$(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
@@ -107,6 +171,38 @@
$(ProjectDir)$(PlatformName)\$(ConfigurationName)\libpng.bsc
+
+
+ MaxSpeed
+ OnlyExplicitInline
+ ..\..;..\..\..\zlib;%(AdditionalIncludeDirectories)
+ WIN32;NDEBUG;PNG_USE_PNGVCRD;PNG_LIBPNG_SPECIALBUILD;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ true
+ MultiThreadedDLL
+ true
+ $(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
+ Level3
+ true
+ CompileAsC
+ true
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+ 0x0409
+ ..\..;%(AdditionalIncludeDirectories)
+
+
+ $(ProjectDir)$(Platform)\$(Configuration)\libpng.lib
+ true
+ MachineARM
+
+
+ true
+ $(ProjectDir)$(PlatformName)\$(ConfigurationName)\libpng.bsc
+
+
X64
@@ -143,6 +239,40 @@
$(ProjectDir)$(PlatformName)\$(ConfigurationName)\libpng.bsc
+
+
+
+ MaxSpeed
+ OnlyExplicitInline
+ ..\..;..\..\..\zlib;%(AdditionalIncludeDirectories)
+ WIN32;NDEBUG;PNG_USE_PNGVCRD;PNG_LIBPNG_SPECIALBUILD;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ true
+ MultiThreadedDLL
+ true
+ $(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
+ Level3
+ true
+ CompileAsC
+ 4267;%(DisableSpecificWarnings)
+ true
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+ 0x0409
+ ..\..;%(AdditionalIncludeDirectories)
+
+
+ $(ProjectDir)$(Platform)\$(Configuration)\libpng.lib
+ true
+ MachineARM64
+
+
+ true
+ $(ProjectDir)$(PlatformName)\$(ConfigurationName)\libpng.bsc
+
+
Disabled
@@ -174,6 +304,36 @@
$(ProjectDir)$(PlatformName)\$(ConfigurationName)\libpng.bsc
+
+
+ Disabled
+ ..\..;..\..\..\zlib;%(AdditionalIncludeDirectories)
+ WIN32;_DEBUG;DEBUG;PNG_DEBUG=1;PNG_USE_PNGVCRD;PNG_LIBPNG_SPECIALBUILD;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ EnableFastChecks
+ MultiThreadedDebugDLL
+ $(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
+ Level3
+ true
+ ProgramDatabase
+ CompileAsC
+ false
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+ 0x0409
+
+
+ $(ProjectDir)$(Platform)\$(Configuration)\libpng.lib
+ true
+ MachineARM
+
+
+ true
+ $(ProjectDir)$(PlatformName)\$(ConfigurationName)\libpng.bsc
+
+
X64
@@ -209,164 +369,320 @@
$(ProjectDir)$(PlatformName)\$(ConfigurationName)\libpng.bsc
+
+
+
+ Disabled
+ ..\..;..\..\..\zlib;%(AdditionalIncludeDirectories)
+ WIN32;_DEBUG;DEBUG;PNG_DEBUG=1;PNG_USE_PNGVCRD;PNG_LIBPNG_SPECIALBUILD;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ EnableFastChecks
+ MultiThreadedDebugDLL
+ $(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
+ Level3
+ true
+ ProgramDatabase
+ CompileAsC
+ 4267;%(DisableSpecificWarnings)
+ false
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+ 0x0409
+
+
+ $(ProjectDir)$(Platform)\$(Configuration)\libpng.lib
+ true
+ MachineARM64
+
+
+ true
+ $(ProjectDir)$(PlatformName)\$(ConfigurationName)\libpng.bsc
+
+
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(AdditionalIncludeDirectories)
+ %(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
true
+ true
true
+ true
true
+ true
true
+ true
@@ -377,17 +693,29 @@
true
+ true
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
\Oogaland\Projects\orospakr.ca\srb2\tools\libpng-src\scripts;%(AdditionalIncludeDirectories)
+ \Oogaland\Projects\orospakr.ca\srb2\tools\libpng-src\scripts;%(AdditionalIncludeDirectories)
true
+ true
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
\Oogaland\Projects\orospakr.ca\srb2\tools\libpng-src\scripts;%(AdditionalIncludeDirectories)
+ \Oogaland\Projects\orospakr.ca\srb2\tools\libpng-src\scripts;%(AdditionalIncludeDirectories)
true
+ true
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
\Oogaland\Projects\orospakr.ca\srb2\tools\libpng-src\scripts;%(AdditionalIncludeDirectories)
+ \Oogaland\Projects\orospakr.ca\srb2\tools\libpng-src\scripts;%(AdditionalIncludeDirectories)
true
+ true
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
\Oogaland\Projects\orospakr.ca\srb2\tools\libpng-src\scripts;%(AdditionalIncludeDirectories)
+ \Oogaland\Projects\orospakr.ca\srb2\tools\libpng-src\scripts;%(AdditionalIncludeDirectories)
diff --git a/libs/zlib/projects/visualc10/.gitignore b/libs/zlib/projects/visualc10/.gitignore
index 488a5428..1c5340cd 100644
--- a/libs/zlib/projects/visualc10/.gitignore
+++ b/libs/zlib/projects/visualc10/.gitignore
@@ -1,3 +1,5 @@
/Win32
/x64
/zlib.vcproj.*.*.user
+/ARM
+/ARM64
diff --git a/libs/zlib/projects/visualc10/zlib.vcxproj b/libs/zlib/projects/visualc10/zlib.vcxproj
index 814641d3..a7055ddb 100644
--- a/libs/zlib/projects/visualc10/zlib.vcxproj
+++ b/libs/zlib/projects/visualc10/zlib.vcxproj
@@ -1,6 +1,14 @@
+
+ Debug
+ ARM
+
+
+ Debug
+ ARM64
+
Debug
Win32
@@ -9,6 +17,14 @@
Debug
x64
+
+ Release
+ ARM
+
+
+ Release
+ ARM64
+
Release
Win32
@@ -21,7 +37,7 @@
{73A5729C-7323-41D4-AB48-8A03C9F81603}
zlib
- 8.1
+ 10.0.16299.0
@@ -29,21 +45,45 @@
false
v140
+
+ StaticLibrary
+ false
+ v141
+ true
+
StaticLibrary
false
v140
+
+ StaticLibrary
+ false
+ v141
+ true
+
StaticLibrary
false
v140
+ true
+
+
+ StaticLibrary
+ false
+ v141
StaticLibrary
false
v140
+
+ StaticLibrary
+ false
+ v141
+ true
+
@@ -52,29 +92,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<_ProjectFileVersion>10.0.30319.1
$(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
$(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
$(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
$(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
$(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
$(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
$(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
$(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
@@ -106,6 +170,36 @@
$(ProjectDir)$(PlatformName)\$(ConfigurationName)\zlib.bsc
+
+
+ Disabled
+ WIN32;_DEBUG;ASMV;ASMINF;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)
+ Default
+ MultiThreadedDebugDLL
+ $(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
+ Level3
+ true
+ ProgramDatabase
+ CompileAsC
+ false
+ ASMV;ASMINF
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+ 0x0409
+
+
+ $(ProjectDir)$(Platform)\$(Configuration)\zlib.lib
+ true
+ MachineARM
+
+
+ true
+ $(ProjectDir)$(PlatformName)\$(ConfigurationName)\zlib.bsc
+
+
X64
@@ -139,6 +233,36 @@
$(ProjectDir)$(PlatformName)\$(ConfigurationName)\zlib.bsc
+
+
+
+ Disabled
+ WIN32;_DEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)
+ EnableFastChecks
+ MultiThreadedDebugDLL
+ $(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
+ Level3
+ true
+ ProgramDatabase
+ CompileAsC
+ false
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+ 0x0409
+
+
+ $(ProjectDir)$(Platform)\$(Configuration)\zlib.lib
+ true
+ MachineARM64
+
+
+ true
+ $(ProjectDir)$(PlatformName)\$(ConfigurationName)\zlib.bsc
+
+
MaxSpeed
@@ -169,6 +293,37 @@
$(ProjectDir)$(PlatformName)\$(ConfigurationName)\zlib.bsc
+
+
+ MaxSpeed
+ OnlyExplicitInline
+ WIN32;NDEBUG;ASMV;ASMINF;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)
+ true
+ MultiThreadedDLL
+ true
+ $(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
+ Level3
+ true
+ CompileAsC
+ true
+ ASMV;ASMINF
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+ 0x0409
+
+
+ $(ProjectDir)$(Platform)\$(Configuration)\zlib.lib
+ true
+ MachineARM
+
+
+ true
+ $(ProjectDir)$(PlatformName)\$(ConfigurationName)\zlib.bsc
+
+
X64
@@ -202,30 +357,77 @@
$(ProjectDir)$(PlatformName)\$(ConfigurationName)\zlib.bsc
+
+
+
+ MaxSpeed
+ OnlyExplicitInline
+ WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)
+ true
+ MultiThreadedDLL
+ true
+ $(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
+ $(ProjectDir)$(Platform)\$(Configuration)\
+ Level3
+ true
+ CompileAsC
+ true
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+ 0x0409
+
+
+ $(ProjectDir)$(Platform)\$(Configuration)\zlib.lib
+ true
+ MachineARM64
+
+
+ true
+ $(ProjectDir)$(PlatformName)\$(ConfigurationName)\zlib.bsc
+
+
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
@@ -233,60 +435,97 @@
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
true
+ true
../;%(AdditionalIncludeDirectories)
+ ../;%(AdditionalIncludeDirectories)
../..;%(AdditionalIncludeDirectories)
+ ../..;%(AdditionalIncludeDirectories)
true
+ true
../..;%(AdditionalIncludeDirectories)
+ ../..;%(AdditionalIncludeDirectories)
true
+ true
true
+ true
true
+ true
true
+ true
@@ -306,39 +545,67 @@
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
\Oogaland\Projects\orospakr.ca\srb2\tools\zlib\win32;%(AdditionalIncludeDirectories)
+ \Oogaland\Projects\orospakr.ca\srb2\tools\zlib\win32;%(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
\Oogaland\Projects\orospakr.ca\srb2\tools\zlib\win32;%(AdditionalIncludeDirectories)
+ \Oogaland\Projects\orospakr.ca\srb2\tools\zlib\win32;%(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
\Oogaland\Projects\orospakr.ca\srb2\tools\zlib\win32;%(AdditionalIncludeDirectories)
+ \Oogaland\Projects\orospakr.ca\srb2\tools\zlib\win32;%(AdditionalIncludeDirectories)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
\Oogaland\Projects\orospakr.ca\srb2\tools\zlib\win32;%(AdditionalIncludeDirectories)
+ \Oogaland\Projects\orospakr.ca\srb2\tools\zlib\win32;%(AdditionalIncludeDirectories)
true
+ true
true
+ true
+ true
+ true
true
+ true
true
+ true
+ true
+ true
true
+ true
true
+ true
true
+ true
true
+ true
true
+ true
true
+ true
true
+ true
true
+ true
true
+ true
true
+ true
true
+ true
true
+ true
diff --git a/srb2-vc10.sln b/srb2-vc10.sln
index ecceafd5..b4415bfc 100644
--- a/srb2-vc10.sln
+++ b/srb2-vc10.sln
@@ -1,9 +1,9 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 14
-VisualStudioVersion = 14.0.25123.0
+# Visual Studio 15
+VisualStudioVersion = 15.0.28307.136
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Srb2win", "src\win32\Srb2win-vc10.vcxproj", "{0F554F1D-ED49-4D65-A9A7-F63C57F277BE}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Srb2DD", "src\win32\Srb2win-vc10.vcxproj", "{0F554F1D-ED49-4D65-A9A7-F63C57F277BE}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpng", "libs\libpng-src\projects\visualc10\libpng.vcxproj", "{72B01ACA-7A1A-4F7B-ACEF-2607299CF052}"
EndProject
@@ -13,56 +13,104 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "libs\zlib\projects\
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "s_openal", "src\hardware\s_openal\s_openal-vc10.vcxproj", "{E662D0B3-412D-4D55-A5EC-8CBD680DDCBE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Srb2SDL", "src\sdl\Srb2SDL-vc10.vcxproj", "{61BA7D3C-F77D-4D31-B718-1177FE482CF2}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Srb2Win", "src\sdl\Srb2SDL-vc10.vcxproj", "{61BA7D3C-F77D-4D31-B718-1177FE482CF2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|ARM = Debug|ARM
+ Debug|ARM64 = Debug|ARM64
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
+ Release|ARM = Release|ARM
+ Release|ARM64 = Release|ARM64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {0F554F1D-ED49-4D65-A9A7-F63C57F277BE}.Debug|ARM.ActiveCfg = Debug|ARM
+ {0F554F1D-ED49-4D65-A9A7-F63C57F277BE}.Debug|ARM.Build.0 = Debug|ARM
+ {0F554F1D-ED49-4D65-A9A7-F63C57F277BE}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {0F554F1D-ED49-4D65-A9A7-F63C57F277BE}.Debug|ARM64.Build.0 = Debug|ARM64
{0F554F1D-ED49-4D65-A9A7-F63C57F277BE}.Debug|Win32.ActiveCfg = Debug|Win32
{0F554F1D-ED49-4D65-A9A7-F63C57F277BE}.Debug|Win32.Build.0 = Debug|Win32
{0F554F1D-ED49-4D65-A9A7-F63C57F277BE}.Debug|x64.ActiveCfg = Debug|x64
{0F554F1D-ED49-4D65-A9A7-F63C57F277BE}.Debug|x64.Build.0 = Debug|x64
+ {0F554F1D-ED49-4D65-A9A7-F63C57F277BE}.Release|ARM.ActiveCfg = Release|ARM
+ {0F554F1D-ED49-4D65-A9A7-F63C57F277BE}.Release|ARM.Build.0 = Release|ARM
+ {0F554F1D-ED49-4D65-A9A7-F63C57F277BE}.Release|ARM64.ActiveCfg = Release|ARM64
+ {0F554F1D-ED49-4D65-A9A7-F63C57F277BE}.Release|ARM64.Build.0 = Release|ARM64
{0F554F1D-ED49-4D65-A9A7-F63C57F277BE}.Release|Win32.ActiveCfg = Release|Win32
{0F554F1D-ED49-4D65-A9A7-F63C57F277BE}.Release|Win32.Build.0 = Release|Win32
{0F554F1D-ED49-4D65-A9A7-F63C57F277BE}.Release|x64.ActiveCfg = Release|x64
{0F554F1D-ED49-4D65-A9A7-F63C57F277BE}.Release|x64.Build.0 = Release|x64
+ {72B01ACA-7A1A-4F7B-ACEF-2607299CF052}.Debug|ARM.ActiveCfg = Debug|ARM
+ {72B01ACA-7A1A-4F7B-ACEF-2607299CF052}.Debug|ARM.Build.0 = Debug|ARM
+ {72B01ACA-7A1A-4F7B-ACEF-2607299CF052}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {72B01ACA-7A1A-4F7B-ACEF-2607299CF052}.Debug|ARM64.Build.0 = Debug|ARM64
{72B01ACA-7A1A-4F7B-ACEF-2607299CF052}.Debug|Win32.ActiveCfg = Debug|Win32
{72B01ACA-7A1A-4F7B-ACEF-2607299CF052}.Debug|Win32.Build.0 = Debug|Win32
{72B01ACA-7A1A-4F7B-ACEF-2607299CF052}.Debug|x64.ActiveCfg = Debug|x64
{72B01ACA-7A1A-4F7B-ACEF-2607299CF052}.Debug|x64.Build.0 = Debug|x64
+ {72B01ACA-7A1A-4F7B-ACEF-2607299CF052}.Release|ARM.ActiveCfg = Release|ARM
+ {72B01ACA-7A1A-4F7B-ACEF-2607299CF052}.Release|ARM.Build.0 = Release|ARM
+ {72B01ACA-7A1A-4F7B-ACEF-2607299CF052}.Release|ARM64.ActiveCfg = Release|ARM64
+ {72B01ACA-7A1A-4F7B-ACEF-2607299CF052}.Release|ARM64.Build.0 = Release|ARM64
{72B01ACA-7A1A-4F7B-ACEF-2607299CF052}.Release|Win32.ActiveCfg = Release|Win32
{72B01ACA-7A1A-4F7B-ACEF-2607299CF052}.Release|Win32.Build.0 = Release|Win32
{72B01ACA-7A1A-4F7B-ACEF-2607299CF052}.Release|x64.ActiveCfg = Release|x64
{72B01ACA-7A1A-4F7B-ACEF-2607299CF052}.Release|x64.Build.0 = Release|x64
+ {51137D5C-4E81-4955-AACF-EA3092006051}.Debug|ARM.ActiveCfg = Debug|ARM
+ {51137D5C-4E81-4955-AACF-EA3092006051}.Debug|ARM.Build.0 = Debug|ARM
+ {51137D5C-4E81-4955-AACF-EA3092006051}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {51137D5C-4E81-4955-AACF-EA3092006051}.Debug|ARM64.Build.0 = Debug|ARM64
{51137D5C-4E81-4955-AACF-EA3092006051}.Debug|Win32.ActiveCfg = Debug|Win32
{51137D5C-4E81-4955-AACF-EA3092006051}.Debug|Win32.Build.0 = Debug|Win32
{51137D5C-4E81-4955-AACF-EA3092006051}.Debug|x64.ActiveCfg = Debug|x64
{51137D5C-4E81-4955-AACF-EA3092006051}.Debug|x64.Build.0 = Debug|x64
+ {51137D5C-4E81-4955-AACF-EA3092006051}.Release|ARM.ActiveCfg = Release|ARM
+ {51137D5C-4E81-4955-AACF-EA3092006051}.Release|ARM.Build.0 = Release|ARM
+ {51137D5C-4E81-4955-AACF-EA3092006051}.Release|ARM64.ActiveCfg = Release|ARM64
+ {51137D5C-4E81-4955-AACF-EA3092006051}.Release|ARM64.Build.0 = Release|ARM64
{51137D5C-4E81-4955-AACF-EA3092006051}.Release|Win32.ActiveCfg = Release|Win32
{51137D5C-4E81-4955-AACF-EA3092006051}.Release|Win32.Build.0 = Release|Win32
{51137D5C-4E81-4955-AACF-EA3092006051}.Release|x64.ActiveCfg = Release|x64
{51137D5C-4E81-4955-AACF-EA3092006051}.Release|x64.Build.0 = Release|x64
+ {73A5729C-7323-41D4-AB48-8A03C9F81603}.Debug|ARM.ActiveCfg = Debug|ARM
+ {73A5729C-7323-41D4-AB48-8A03C9F81603}.Debug|ARM.Build.0 = Debug|ARM
+ {73A5729C-7323-41D4-AB48-8A03C9F81603}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {73A5729C-7323-41D4-AB48-8A03C9F81603}.Debug|ARM64.Build.0 = Debug|ARM64
{73A5729C-7323-41D4-AB48-8A03C9F81603}.Debug|Win32.ActiveCfg = Debug|Win32
{73A5729C-7323-41D4-AB48-8A03C9F81603}.Debug|Win32.Build.0 = Debug|Win32
{73A5729C-7323-41D4-AB48-8A03C9F81603}.Debug|x64.ActiveCfg = Debug|x64
{73A5729C-7323-41D4-AB48-8A03C9F81603}.Debug|x64.Build.0 = Debug|x64
+ {73A5729C-7323-41D4-AB48-8A03C9F81603}.Release|ARM.ActiveCfg = Release|ARM
+ {73A5729C-7323-41D4-AB48-8A03C9F81603}.Release|ARM.Build.0 = Release|ARM
+ {73A5729C-7323-41D4-AB48-8A03C9F81603}.Release|ARM64.ActiveCfg = Release|ARM64
+ {73A5729C-7323-41D4-AB48-8A03C9F81603}.Release|ARM64.Build.0 = Release|ARM64
{73A5729C-7323-41D4-AB48-8A03C9F81603}.Release|Win32.ActiveCfg = Release|Win32
{73A5729C-7323-41D4-AB48-8A03C9F81603}.Release|Win32.Build.0 = Release|Win32
{73A5729C-7323-41D4-AB48-8A03C9F81603}.Release|x64.ActiveCfg = Release|x64
{73A5729C-7323-41D4-AB48-8A03C9F81603}.Release|x64.Build.0 = Release|x64
+ {E662D0B3-412D-4D55-A5EC-8CBD680DDCBE}.Debug|ARM.ActiveCfg = Debug|ARM
+ {E662D0B3-412D-4D55-A5EC-8CBD680DDCBE}.Debug|ARM64.ActiveCfg = Debug|ARM64
{E662D0B3-412D-4D55-A5EC-8CBD680DDCBE}.Debug|Win32.ActiveCfg = Debug|Win32
{E662D0B3-412D-4D55-A5EC-8CBD680DDCBE}.Debug|x64.ActiveCfg = Debug|x64
+ {E662D0B3-412D-4D55-A5EC-8CBD680DDCBE}.Release|ARM.ActiveCfg = Release|ARM
+ {E662D0B3-412D-4D55-A5EC-8CBD680DDCBE}.Release|ARM64.ActiveCfg = Release|ARM64
{E662D0B3-412D-4D55-A5EC-8CBD680DDCBE}.Release|Win32.ActiveCfg = Release|Win32
{E662D0B3-412D-4D55-A5EC-8CBD680DDCBE}.Release|x64.ActiveCfg = Release|x64
+ {61BA7D3C-F77D-4D31-B718-1177FE482CF2}.Debug|ARM.ActiveCfg = Debug|ARM
+ {61BA7D3C-F77D-4D31-B718-1177FE482CF2}.Debug|ARM.Build.0 = Debug|ARM
+ {61BA7D3C-F77D-4D31-B718-1177FE482CF2}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {61BA7D3C-F77D-4D31-B718-1177FE482CF2}.Debug|ARM64.Build.0 = Debug|ARM64
{61BA7D3C-F77D-4D31-B718-1177FE482CF2}.Debug|Win32.ActiveCfg = Debug|Win32
{61BA7D3C-F77D-4D31-B718-1177FE482CF2}.Debug|Win32.Build.0 = Debug|Win32
{61BA7D3C-F77D-4D31-B718-1177FE482CF2}.Debug|x64.ActiveCfg = Debug|x64
{61BA7D3C-F77D-4D31-B718-1177FE482CF2}.Debug|x64.Build.0 = Debug|x64
+ {61BA7D3C-F77D-4D31-B718-1177FE482CF2}.Release|ARM.ActiveCfg = Release|ARM
+ {61BA7D3C-F77D-4D31-B718-1177FE482CF2}.Release|ARM.Build.0 = Release|ARM
+ {61BA7D3C-F77D-4D31-B718-1177FE482CF2}.Release|ARM64.ActiveCfg = Release|ARM64
+ {61BA7D3C-F77D-4D31-B718-1177FE482CF2}.Release|ARM64.Build.0 = Release|ARM64
{61BA7D3C-F77D-4D31-B718-1177FE482CF2}.Release|Win32.ActiveCfg = Release|Win32
{61BA7D3C-F77D-4D31-B718-1177FE482CF2}.Release|Win32.Build.0 = Release|Win32
{61BA7D3C-F77D-4D31-B718-1177FE482CF2}.Release|x64.ActiveCfg = Release|x64
@@ -71,4 +119,7 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {8C0B5F99-D9B8-4CB2-BA67-5D350E71C6FC}
+ EndGlobalSection
EndGlobal
diff --git a/src/Makefile b/src/Makefile
index 355b8daa..6c686c2d 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -453,6 +453,10 @@ ifdef ZDEBUG
CPPFLAGS+=-DZDEBUG
endif
+ifdef DEVELOP
+ CPPFLAGS+=-DDEVELOP
+endif
+
OPTS+=$(CPPFLAGS)
# default EXENAME if all else fails
diff --git a/src/Makefile.cfg b/src/Makefile.cfg
index cdd4c3c7..1238050b 100644
--- a/src/Makefile.cfg
+++ b/src/Makefile.cfg
@@ -112,9 +112,7 @@ ifndef GCC295
WFLAGS+=-Wno-div-by-zero
endif
#WFLAGS+=-Wsystem-headers
-ifndef ERRORMODE
-#WFLAGS+=-Wfloat-equal
-endif
+WFLAGS+=-Wfloat-equal
#WFLAGS+=-Wtraditional
ifdef VCHELP
WFLAGS+=-Wdeclaration-after-statement
diff --git a/src/am_map.c b/src/am_map.c
index 6b97dd28..5e73d2ec 100644
--- a/src/am_map.c
+++ b/src/am_map.c
@@ -11,8 +11,8 @@
/// \file am_map.c
/// \brief Code for the 'automap', former Doom feature used for DEVMODE testing
-#include "g_game.h"
#include "am_map.h"
+#include "g_game.h"
#include "g_input.h"
#include "p_local.h"
#include "p_slopes.h"
@@ -33,7 +33,6 @@ 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 GREENRANGE = 16;
static const UINT8 DBLACK = 31;
static const UINT8 DWHITE = 0;
@@ -50,8 +49,6 @@ static const UINT8 NOCLIMBYELLOWS = (11*16);
// Automap colors
#define BACKGROUND DBLACK
-#define YOURCOLORS DWHITE
-#define YOURRANGE 0
#define WALLCOLORS (REDS + REDRANGE/2)
#define WALLRANGE (REDRANGE/2)
#define NOCLIMBWALLCOLORS (NOCLIMBREDS + NOCLIMBREDRANGE/2)
@@ -68,31 +65,23 @@ static const UINT8 NOCLIMBYELLOWS = (11*16);
#define CDWALLCOLORS YELLOWS
#define NOCLIMBCDWALLCOLORS NOCLIMBYELLOWS
#define THINGCOLORS GREENS
-#define THINGRANGE GREENRANGE
-#define SECRETWALLCOLORS WALLCOLORS
-#define SECRETWALLRANGE WALLRANGE
#define GRIDCOLORS (GRAYS + GRAYSRANGE/2)
-#define GRIDRANGE 0
#define XHAIRCOLORS GRAYS
-// drawing stuff
-#define FB 0
-
-#define AM_PANDOWNKEY KEY_DOWNARROW
+// controls
#define AM_PANUPKEY KEY_UPARROW
-#define AM_PANRIGHTKEY KEY_RIGHTARROW
+#define AM_PANDOWNKEY KEY_DOWNARROW
#define AM_PANLEFTKEY KEY_LEFTARROW
+#define AM_PANRIGHTKEY KEY_RIGHTARROW
+
#define AM_ZOOMINKEY '='
#define AM_ZOOMOUTKEY '-'
-#define AM_STARTKEY KEY_TAB
-#define AM_ENDKEY KEY_TAB
#define AM_GOBIGKEY '0'
+
#define AM_FOLLOWKEY 'f'
#define AM_GRIDKEY 'g'
-#define AM_MARKKEY 'm'
-#define AM_CLEARMARKKEY 'c'
-#define AM_NUMMARKPOINTS 10
+#define AM_TOGGLEKEY KEY_TAB
// scale on entry
#define INITSCALEMTOF (FRACUNIT/5)
@@ -113,6 +102,9 @@ static const UINT8 NOCLIMBYELLOWS = (11*16);
#define CXMTOF(x) (f_x + MTOF((x)-m_x))
#define CYMTOF(y) (f_y + (f_h - MTOF((y)-m_y)))
+#define MAPBITS (FRACBITS-4)
+#define FRACTOMAPBITS (FRACBITS-MAPBITS)
+
typedef struct
{
fixed_t x, y;
@@ -133,7 +125,10 @@ typedef struct
// A line drawing of the player pointing right,
// starting from the middle.
//
+
+#define PLAYERRADIUS (16*(1<
@@ -166,27 +161,15 @@ static const mline_t thintriangle_guy[] = {
#undef R
#define NUMTHINTRIANGLEGUYLINES (sizeof (thintriangle_guy)/sizeof (mline_t))
-static INT32 bigstate; //added : 24-01-98 : moved here, toggle between
- // user view and large view (full map view)
-
-static INT32 grid = 0;
-
-static INT32 leveljuststarted = 1; // kluge until AM_LevelInit() is called
+static boolean bigstate; // user view and large view (full map view)
+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;
-// location of window on screen
-static INT32 f_x;
-static INT32 f_y;
-
-// size of window on screen
-static INT32 f_w;
-static INT32 f_h;
-
-static INT32 lightlev; // used for funky strobing effect
-static UINT8 *fb; // pseudo-frame buffer
-static INT32 amclock;
+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 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)
@@ -210,11 +193,6 @@ static fixed_t max_y;
static fixed_t max_w; // max_x-min_x,
static fixed_t max_h; // max_y-min_y
-// based on player size
-static fixed_t min_w;
-static fixed_t min_h;
-
-
static fixed_t min_scale_mtof; // used to tell when to stop zooming out
static fixed_t max_scale_mtof; // used to tell when to stop zooming in
@@ -232,13 +210,7 @@ static fixed_t scale_ftom;
static player_t *plr; // the player represented by an arrow
-static patch_t *marknums[10]; // numbers used for marking by the automap
-static mpoint_t markpoints[AM_NUMMARKPOINTS]; // where the points are
-static INT32 markpointnum = 0; // next point to be assigned
-
-static INT32 followplayer = 1; // specifies whether to follow the player around
-
-static boolean stopped = true;
+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);
@@ -277,8 +249,8 @@ static inline void AM_restoreScaleAndLoc(void)
}
else
{
- m_x = plr->mo->x - m_w/2;
- m_y = plr->mo->y - m_h/2;
+ m_x = (plr->mo->x >> FRACTOMAPBITS) - m_w/2;
+ m_y = (plr->mo->y >> FRACTOMAPBITS) - m_h/2;
}
m_x2 = m_x + m_w;
m_y2 = m_y + m_h;
@@ -288,15 +260,6 @@ static inline void AM_restoreScaleAndLoc(void)
scale_ftom = FixedDiv(FRACUNIT, scale_mtof);
}
-/** Adds a marker at the current location.
- */
-static inline void AM_addMark(void)
-{
- markpoints[markpointnum].x = m_x + m_w/2;
- markpoints[markpointnum].y = m_y + m_h/2;
- markpointnum = (markpointnum + 1) % AM_NUMMARKPOINTS;
-}
-
/** Determines the bounding box around all vertices.
* This is used to set global variables controlling the zoom range.
*/
@@ -322,11 +285,8 @@ static void AM_findMinMaxBoundaries(void)
max_y = vertexes[i].y;
}
- max_w = max_x - min_x;
- max_h = max_y - min_y;
-
- min_w = 2*PLAYERRADIUS; // const? never changed?
- min_h = 2*PLAYERRADIUS;
+ max_w = (max_x >>= FRACTOMAPBITS) - (min_x >>= FRACTOMAPBITS);
+ max_h = (max_y >>= FRACTOMAPBITS) - (min_y >>= FRACTOMAPBITS);
a = FixedDiv(f_w<mo->x - m_w/2;
- m_y = plr->mo->y - m_h/2;
+ if (plr != NULL && plr->mo != NULL)
+ {
+ m_x = (plr->mo->x >> FRACTOMAPBITS) - m_w/2;
+ m_y = (plr->mo->y >> FRACTOMAPBITS) - m_h/2;
+ }
AM_changeWindowLoc();
// for saving & restoring
@@ -396,41 +355,21 @@ static void AM_initVariables(void)
old_m_h = m_h;
}
-static const UINT8 *maplump; // pointer to the raw data for the automap background.
-
-/** Clears all map markers.
- */
-static void AM_clearMarks(void)
-{
- INT32 i;
-
- for (i = 0; i < AM_NUMMARKPOINTS; i++)
- markpoints[i].x = -1; // means empty
- markpointnum = 0;
-}
-
//
// should be called at the start of every level
// right now, i figure it out myself
//
static void AM_LevelInit(void)
{
- leveljuststarted = 0;
-
f_x = f_y = 0;
f_w = vid.width;
f_h = vid.height;
- if (rendermode == render_soft)
- AM_drawFline = AM_drawFline_soft;
-#ifdef HWRENDER // not win32 only 19990829 by Kin
- else if (rendermode != render_none)
+ AM_drawFline = AM_drawFline_soft;
+#ifdef HWRENDER
+ if (rendermode == render_opengl)
AM_drawFline = HWR_drawAMline;
#endif
- else
- I_Error("Automap can't run without a render system");
-
- AM_clearMarks();
AM_findMinMaxBoundaries();
scale_mtof = FixedDiv(min_scale_mtof*10, 7*FRACUNIT);
@@ -446,7 +385,7 @@ static void AM_LevelInit(void)
void AM_Stop(void)
{
automapactive = false;
- stopped = true;
+ am_stopped = true;
}
/** Enables automap.
@@ -457,15 +396,14 @@ static inline void AM_Start(void)
{
static INT32 lastlevel = -1;
- if (!stopped)
+ if (!am_stopped)
AM_Stop();
- stopped = false;
+ am_stopped = false;
if (lastlevel != gamemap || am_recalc) // screen size changed
{
- am_recalc = false;
-
AM_LevelInit();
lastlevel = gamemap;
+ am_recalc = false;
}
AM_initVariables();
}
@@ -503,7 +441,7 @@ boolean AM_Responder(event_t *ev)
{
if (!automapactive)
{
- if (ev->type == ev_keydown && ev->data1 == AM_STARTKEY)
+ if (ev->type == ev_keydown && ev->data1 == AM_TOGGLEKEY)
{
//faB: prevent alt-tab in win32 version to activate automap just before
// minimizing the app; doesn't do any harm to the DOS version
@@ -515,10 +453,8 @@ boolean AM_Responder(event_t *ev)
}
}
}
-
else if (ev->type == ev_keydown)
{
-
rc = true;
switch (ev->data1)
{
@@ -554,7 +490,7 @@ boolean AM_Responder(event_t *ev)
mtof_zoommul = M_ZOOMIN;
ftom_zoommul = M_ZOOMOUT;
break;
- case AM_ENDKEY:
+ case AM_TOGGLEKEY:
AM_Stop();
break;
case AM_GOBIGKEY:
@@ -572,13 +508,7 @@ boolean AM_Responder(event_t *ev)
f_oldloc.x = INT32_MAX;
break;
case AM_GRIDKEY:
- grid = !grid;
- break;
- case AM_MARKKEY:
- AM_addMark();
- break;
- case AM_CLEARMARKKEY:
- AM_clearMarks();
+ draw_grid = !draw_grid;
break;
default:
rc = false;
@@ -632,8 +562,8 @@ static inline void AM_doFollowPlayer(void)
{
if (f_oldloc.x != plr->mo->x || f_oldloc.y != plr->mo->y)
{
- m_x = FTOM(MTOF(plr->mo->x)) - m_w/2;
- m_y = FTOM(MTOF(plr->mo->y)) - m_h/2;
+ m_x = FTOM(MTOF(plr->mo->x >> FRACTOMAPBITS)) - m_w/2;
+ m_y = FTOM(MTOF(plr->mo->y >> FRACTOMAPBITS)) - m_h/2;
m_x2 = m_x + m_w;
m_y2 = m_y + m_h;
f_oldloc.x = plr->mo->x;
@@ -651,8 +581,6 @@ void AM_Ticker(void)
if (dedicated || !automapactive)
return;
- amclock++;
-
if (followplayer)
AM_doFollowPlayer();
@@ -671,72 +599,7 @@ void AM_Ticker(void)
*/
static void AM_clearFB(INT32 color)
{
-#ifdef HWRENDER
- if (rendermode != render_soft && rendermode != render_none)
- {
- HWR_clearAutomap();
- return;
- }
-#endif
-
- if (!maplump)
- memset(fb, color, f_w*f_h*vid.bpp);
- else
- {
- INT32 dmapx, dmapy, i, y;
- static INT32 mapxstart, mapystart;
- UINT8 *dest = screens[0];
- const UINT8 *src;
-#define MAPLUMPHEIGHT (200 - 42)
-
- if (followplayer)
- {
- static vertex_t oldplr;
-
- dmapx = MTOF(plr->mo->x) - MTOF(oldplr.x); //fixed point
- dmapy = MTOF(oldplr.y) - MTOF(plr->mo->y);
-
- oldplr.x = plr->mo->x;
- oldplr.y = plr->mo->y;
- mapxstart += dmapx>>1;
- mapystart += dmapy>>1;
-
- while (mapxstart >= BASEVIDWIDTH)
- mapxstart -= BASEVIDWIDTH;
- while (mapxstart < 0)
- mapxstart += BASEVIDWIDTH;
- while (mapystart >= MAPLUMPHEIGHT)
- mapystart -= MAPLUMPHEIGHT;
- while (mapystart < 0)
- mapystart += MAPLUMPHEIGHT;
- }
- else
- {
- mapxstart += (MTOF(m_paninc.x)>>1);
- mapystart -= (MTOF(m_paninc.y)>>1);
- if (mapxstart >= BASEVIDWIDTH)
- mapxstart -= BASEVIDWIDTH;
- if (mapxstart < 0)
- mapxstart += BASEVIDWIDTH;
- if (mapystart >= MAPLUMPHEIGHT)
- mapystart -= MAPLUMPHEIGHT;
- if (mapystart < 0)
- mapystart += MAPLUMPHEIGHT;
- }
-
- //blit the automap background to the screen.
- for (y = 0; y < f_h; y++)
- {
- src = maplump + mapxstart + (y + mapystart)*BASEVIDWIDTH;
- for (i = 0; i < BASEVIDWIDTH*vid.dupx; i++)
- {
- while (src > maplump + BASEVIDWIDTH*MAPLUMPHEIGHT)
- src -= BASEVIDWIDTH*MAPLUMPHEIGHT;
- *dest++ = *src++;
- }
- dest += vid.width - vid.dupx*BASEVIDWIDTH;
- }
- }
+ V_DrawFill(f_x, f_y, f_w, f_h, color|V_NOSCALESTART);
}
/** Performs automap clipping of lines.
@@ -871,7 +734,7 @@ static boolean AM_clipMline(const mline_t *ml, fline_t *fl)
//
static void AM_drawFline_soft(const fline_t *fl, INT32 color)
{
- register INT32 x, y, dx, dy, sx, sy, ax, ay, d;
+ INT32 x, y, dx, dy, sx, sy, ax, ay, d;
#ifdef _DEBUG
static INT32 num = 0;
@@ -887,7 +750,7 @@ static void AM_drawFline_soft(const fline_t *fl, INT32 color)
}
#endif
-#define PUTDOT(xx,yy,cc) fb[(yy)*f_w + (xx)]=(UINT8)(cc)
+ #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);
@@ -905,7 +768,7 @@ static void AM_drawFline_soft(const fline_t *fl, INT32 color)
d = ay - ax/2;
for (;;)
{
- PUTDOT(x, y, color);
+ PUTDOT(x, y, color)
if (x == fl->b.x)
return;
if (d >= 0)
@@ -922,7 +785,7 @@ static void AM_drawFline_soft(const fline_t *fl, INT32 color)
d = ax - ay/2;
for (;;)
{
- PUTDOT(x, y, color);
+ PUTDOT(x, y, color)
if (y == fl->b.y)
return;
if (d >= 0)
@@ -934,6 +797,8 @@ static void AM_drawFline_soft(const fline_t *fl, INT32 color)
d += ax;
}
}
+
+ #undef PUTDOT
}
//
@@ -1004,15 +869,15 @@ static inline void AM_drawWalls(void)
for (i = 0; i < numlines; i++)
{
- l.a.x = lines[i].v1->x;
- l.a.y = lines[i].v1->y;
- l.b.x = lines[i].v2->x;
- l.b.y = lines[i].v2->y;
+ l.a.x = lines[i].v1->x >> FRACTOMAPBITS;
+ l.a.y = lines[i].v1->y >> FRACTOMAPBITS;
+ l.b.x = lines[i].v2->x >> FRACTOMAPBITS;
+ l.b.y = lines[i].v2->y >> FRACTOMAPBITS;
#ifdef ESLOPE
#define SLOPEPARAMS(slope, end1, end2, normalheight) \
if (slope) { \
- end1 = P_GetZAt(slope, l.a.x, l.a.y); \
- end2 = P_GetZAt(slope, l.b.x, l.b.y); \
+ 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;
@@ -1025,17 +890,12 @@ static inline void AM_drawWalls(void)
#undef SLOPEPARAMS
#endif
-// AM_drawMline(&l, GRAYS + 3); // Old, everything-is-gray automap
if (!lines[i].backsector) // 1-sided
{
if (lines[i].flags & ML_NOCLIMB)
- {
- AM_drawMline(&l, NOCLIMBWALLCOLORS+lightlev);
- }
+ AM_drawMline(&l, NOCLIMBWALLCOLORS);
else
- {
- AM_drawMline(&l, WALLCOLORS+lightlev);
- }
+ AM_drawMline(&l, WALLCOLORS);
}
#ifdef ESLOPE
else if ((backf1 == backc1 && backf2 == backc2) // Back is thok barrier
@@ -1052,24 +912,16 @@ static inline void AM_drawWalls(void)
#endif
{
if (lines[i].flags & ML_NOCLIMB)
- {
- AM_drawMline(&l, NOCLIMBTSWALLCOLORS+lightlev);
- }
+ AM_drawMline(&l, NOCLIMBTSWALLCOLORS);
else
- {
- AM_drawMline(&l, TSWALLCOLORS+lightlev);
- }
+ AM_drawMline(&l, TSWALLCOLORS);
}
else
{
if (lines[i].flags & ML_NOCLIMB)
- {
- AM_drawMline(&l, NOCLIMBTHOKWALLCOLORS+lightlev);
- }
+ AM_drawMline(&l, NOCLIMBTHOKWALLCOLORS);
else
- {
- AM_drawMline(&l, THOKWALLCOLORS+lightlev);
- }
+ AM_drawMline(&l, THOKWALLCOLORS);
}
}
else
@@ -1081,7 +933,7 @@ static inline void AM_drawWalls(void)
if (lines[i].backsector->floorheight
!= lines[i].frontsector->floorheight) {
#endif
- AM_drawMline(&l, NOCLIMBFDWALLCOLORS + lightlev); // floor level change
+ AM_drawMline(&l, NOCLIMBFDWALLCOLORS); // floor level change
}
#ifdef ESLOPE
else if (backc1 != frontc1 || backc2 != frontc2) {
@@ -1089,11 +941,10 @@ static inline void AM_drawWalls(void)
else if (lines[i].backsector->ceilingheight
!= lines[i].frontsector->ceilingheight) {
#endif
- AM_drawMline(&l, NOCLIMBCDWALLCOLORS+lightlev); // ceiling level change
- }
- else {
- AM_drawMline(&l, NOCLIMBTSWALLCOLORS+lightlev);
+ AM_drawMline(&l, NOCLIMBCDWALLCOLORS); // ceiling level change
}
+ else
+ AM_drawMline(&l, NOCLIMBTSWALLCOLORS);
}
else
{
@@ -1103,7 +954,7 @@ static inline void AM_drawWalls(void)
if (lines[i].backsector->floorheight
!= lines[i].frontsector->floorheight) {
#endif
- AM_drawMline(&l, FDWALLCOLORS + lightlev); // floor level change
+ AM_drawMline(&l, FDWALLCOLORS); // floor level change
}
#ifdef ESLOPE
else if (backc1 != frontc1 || backc2 != frontc2) {
@@ -1111,11 +962,10 @@ static inline void AM_drawWalls(void)
else if (lines[i].backsector->ceilingheight
!= lines[i].frontsector->ceilingheight) {
#endif
- AM_drawMline(&l, CDWALLCOLORS+lightlev); // ceiling level change
- }
- else {
- AM_drawMline(&l, TSWALLCOLORS+lightlev);
+ AM_drawMline(&l, CDWALLCOLORS); // ceiling level change
}
+ else
+ AM_drawMline(&l, TSWALLCOLORS);
}
}
}
@@ -1176,6 +1026,11 @@ static void AM_drawLineCharacter(const mline_t *lineguy, size_t lineguylines, fi
l.b.x += x;
l.b.y += y;
+ l.a.x >>= FRACTOMAPBITS;
+ l.a.y >>= FRACTOMAPBITS;
+ l.b.x >>= FRACTOMAPBITS;
+ l.b.y >>= FRACTOMAPBITS;
+
AM_drawMline(&l, color);
}
}
@@ -1184,83 +1039,51 @@ static inline void AM_drawPlayers(void)
{
INT32 i;
player_t *p;
- INT32 color;
+ INT32 color = GREENS;
if (!multiplayer)
{
- AM_drawLineCharacter(player_arrow, NUMPLYRLINES, 0,
- plr->mo->angle, DWHITE, plr->mo->x, plr->mo->y);
+ AM_drawLineCharacter(player_arrow, NUMPLYRLINES, 0, plr->mo->angle, DWHITE, plr->mo->x, plr->mo->y);
return;
}
- // multiplayer
+ // multiplayer (how??)
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator)
continue;
p = &players[i];
- if (p->skincolor == 0)
- color = GREENS;
- else
+ if (p->skincolor > 0)
color = R_GetTranslationColormap(TC_DEFAULT, p->skincolor, GTC_CACHE)[GREENS + 8];
- AM_drawLineCharacter(player_arrow, NUMPLYRLINES, 0, 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);
}
}
-static inline void AM_drawThings(INT32 colors, INT32 colorrange)
+static inline void AM_drawThings(UINT8 colors)
{
size_t i;
mobj_t *t;
- (void)colorrange;
for (i = 0; i < numsectors; i++)
{
t = sectors[i].thinglist;
while (t)
{
- AM_drawLineCharacter(thintriangle_guy, NUMTHINTRIANGLEGUYLINES,
- 16<angle, colors + lightlev, t->x, t->y);
+ AM_drawLineCharacter(thintriangle_guy, NUMTHINTRIANGLEGUYLINES, 16<angle, colors, t->x, t->y);
t = t->snext;
}
}
}
-static inline void AM_drawMarks(void)
-{
- INT32 i, fx, fy, w, h;
-
- for (i = 0; i < AM_NUMMARKPOINTS; i++)
- {
- if (markpoints[i].x != -1 && marknums[i])
- {
- // w = SHORT(marknums[i]->width);
- // h = SHORT(marknums[i]->height);
- w = 5; // because something's wrong with the wad, i guess
- h = 6; // because something's wrong with the wad, i guess
- fx = CXMTOF(markpoints[i].x);
- fy = CYMTOF(markpoints[i].y);
- if (fx >= f_x && fx <= f_w - w && fy >= f_y && fy <= f_h - h)
- V_DrawPatch(fx, fy, FB, marknums[i]);
- }
- }
-}
-
/** Draws the crosshair, actually just a dot in software mode.
*
* \param color Color for the crosshair.
*/
-static inline void AM_drawCrosshair(INT32 color)
+static inline void AM_drawCrosshair(UINT8 color)
{
- if (rendermode != render_soft)
- return; // BP: should be putpixel here
-
- if (scr_bpp == 1)
- fb[(f_w*(f_h + 1))/2] = (UINT8)color; // single point for now
- else
- *((INT16 *)(void *)fb + (f_w*(f_h + 1))/2) = (INT16)color;
+ V_DrawFill(f_w/2 + f_x, f_h/2 + f_y, 1, 1, color|V_NOSCALESTART);
}
/** Draws the automap.
@@ -1271,13 +1094,10 @@ void AM_Drawer(void)
return;
AM_clearFB(BACKGROUND);
- if (grid)
- AM_drawGrid(GRIDCOLORS);
+ if (draw_grid) AM_drawGrid(GRIDCOLORS);
AM_drawWalls();
AM_drawPlayers();
- AM_drawThings(THINGCOLORS, THINGRANGE);
+ AM_drawThings(THINGCOLORS);
AM_drawCrosshair(XHAIRCOLORS);
-
- AM_drawMarks();
}
diff --git a/src/command.c b/src/command.c
index 4f824aa3..bb2ea86e 100644
--- a/src/command.c
+++ b/src/command.c
@@ -33,6 +33,7 @@
#include "hu_stuff.h"
#include "p_setup.h"
#include "lua_script.h"
+#include "d_netfil.h" // findfile
//========
// protos.
@@ -50,6 +51,9 @@ static void COM_Wait_f(void);
static void COM_Help_f(void);
static void COM_Toggle_f(void);
+static void CV_EnforceExecVersion(void);
+static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr);
+
static boolean CV_Command(void);
static consvar_t *CV_FindVar(const char *name);
static const char *CV_StringValue(const char *var_name);
@@ -68,6 +72,19 @@ CV_PossibleValue_t kartspeed_cons_t[] = {
{0, "Easy"}, {1, "Normal"}, {2, "Hard"},
{0, NULL}};
+// Filter consvars by EXECVERSION
+// First implementation is 2 (1.0.2), so earlier configs default at 1 (1.0.0)
+// Also set CV_HIDEN during runtime, after config is loaded
+
+static boolean execversion_enabled = false;
+consvar_t cv_execversion = {"execversion","1",CV_CALL,CV_Unsigned, CV_EnforceExecVersion, 0, NULL, NULL, 0, 0, NULL};
+
+// for default joyaxis detection
+#if 0
+static boolean joyaxis_default[4] = {false,false,false,false};
+static INT32 joyaxis_count[4] = {0,0,0,0};
+#endif
+
#define COM_BUF_SIZE 8192 // command buffer size
#define MAX_ALIAS_RECURSION 100 // max recursion allowed for aliases
@@ -635,6 +652,7 @@ static void COM_CEchoDuration_f(void)
static void COM_Exec_f(void)
{
UINT8 *buf = NULL;
+ char filename[256];
if (COM_Argc() < 2 || COM_Argc() > 3)
{
@@ -643,13 +661,23 @@ static void COM_Exec_f(void)
}
// load file
+ // Try with Argv passed verbatim first, for back compat
FIL_ReadFile(COM_Argv(1), &buf);
if (!buf)
{
- if (!COM_CheckParm("-noerror"))
- CONS_Printf(M_GetText("couldn't execute file %s\n"), COM_Argv(1));
- return;
+ // Now try by searching the file path
+ // filename is modified with the full found path
+ strcpy(filename, COM_Argv(1));
+ if (findfile(filename, NULL, true) != FS_NOTFOUND)
+ FIL_ReadFile(filename, &buf);
+
+ if (!buf)
+ {
+ if (!COM_CheckParm("-noerror"))
+ CONS_Printf(M_GetText("couldn't execute file %s\n"), COM_Argv(1));
+ return;
+ }
}
if (!COM_CheckParm("-silent"))
@@ -1129,7 +1157,7 @@ static void Setvalue(consvar_t *var, const char *valstr, boolean stealth)
if (var->flags & CV_FLOAT)
{
double d = atof(valstr);
- if (!d && valstr[0] != '0')
+ if (fpclassify(d) == FP_ZERO && valstr[0] != '0')
v = INT32_MIN;
else
v = (INT32)(d * FRACUNIT);
@@ -1698,6 +1726,108 @@ void CV_AddValue(consvar_t *var, INT32 increment)
var->changed = 1; // user has changed it now
}
+void CV_InitFilterVar(void)
+{
+#if 0
+ UINT8 i;
+ for (i = 0; i < 4; i++)
+ {
+ joyaxis_default[i] = true;
+ joyaxis_count[i] = 0;
+ }
+#endif
+}
+
+void CV_ToggleExecVersion(boolean enable)
+{
+ execversion_enabled = enable;
+}
+
+static void CV_EnforceExecVersion(void)
+{
+ if (!execversion_enabled)
+ CV_StealthSetValue(&cv_execversion, EXECVERSION);
+}
+
+static boolean CV_FilterJoyAxisVars(consvar_t *v, const char *valstr)
+{
+#if 1
+ // We don't have changed axis defaults yet
+ (void)v;
+ (void)valstr;
+#else
+ UINT8 i;
+
+ // If ALL axis settings are previous defaults, set them to the new defaults
+ // EXECVERSION < 26 (2.1.21)
+
+ for (i = 0; i < 4; i++)
+ {
+ if (joyaxis_default[i])
+ {
+ if (!stricmp(v->name, "joyaxis_fire"))
+ {
+ if (joyaxis_count[i] > 7) return false;
+ else if (joyaxis_count[i] == 7) return true;
+
+ if (!stricmp(valstr, "None")) joyaxis_count[i]++;
+ else joyaxis_default[i] = false;
+ }
+ // reset all axis settings to defaults
+ if (joyaxis_count[i] == 7)
+ {
+ switch (i)
+ {
+ default:
+ COM_BufInsertText(va("%s \"%s\"\n", cv_turnaxis.name, cv_turnaxis.defaultvalue));
+ COM_BufInsertText(va("%s \"%s\"\n", cv_moveaxis.name, cv_moveaxis.defaultvalue));
+ COM_BufInsertText(va("%s \"%s\"\n", cv_brakeaxis.name, cv_brakeaxis.defaultvalue));
+ COM_BufInsertText(va("%s \"%s\"\n", cv_aimaxis.name, cv_aimaxis.defaultvalue));
+ COM_BufInsertText(va("%s \"%s\"\n", cv_lookaxis.name, cv_lookaxis.defaultvalue));
+ COM_BufInsertText(va("%s \"%s\"\n", cv_fireaxis.name, cv_fireaxis.defaultvalue));
+ COM_BufInsertText(va("%s \"%s\"\n", cv_driftaxis.name, cv_driftaxis.defaultvalue));
+ break;
+ }
+ joyaxis_count[i]++;
+ return false;
+ }
+ }
+ }
+#endif
+
+ // we haven't reached our counts yet, or we're not default
+ return true;
+}
+
+static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr)
+{
+ // True means allow the CV change, False means block it
+
+ // We only care about CV_SAVE because this filters the user's config files
+ // We do this same check in CV_Command
+ if (!(v->flags & CV_SAVE))
+ return true;
+
+ 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))
+ return false;
+ }
+
+ return true;
+}
+
/** Displays or changes a variable from the console.
* Since the user is presumed to have been directly responsible
* for this change, the variable is marked as changed this game.
@@ -1722,8 +1852,11 @@ static boolean CV_Command(void)
return true;
}
- CV_Set(v, COM_Argv(1));
- v->changed = 1; // now it's been changed by (presumably) the user
+ if (!(v->flags & CV_SAVE) || CV_FilterVarByVersion(v, COM_Argv(1)))
+ {
+ CV_Set(v, COM_Argv(1));
+ v->changed = 1; // now it's been changed by (presumably) the user
+ }
return true;
}
diff --git a/src/command.h b/src/command.h
index 13c0c406..82dfaf8a 100644
--- a/src/command.h
+++ b/src/command.h
@@ -129,6 +129,11 @@ extern CV_PossibleValue_t CV_Natural[];
// SRB2kart
extern CV_PossibleValue_t kartspeed_cons_t[];
+extern consvar_t cv_execversion;
+
+void CV_InitFilterVar(void);
+void CV_ToggleExecVersion(boolean enable);
+
// register a variable for use at the console
void CV_RegisterVar(consvar_t *variable);
diff --git a/src/config.h.in b/src/config.h.in
index ab96b333..dd86966e 100644
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -34,14 +34,16 @@
#else
/* Manually defined asset hashes for non-CMake builds
- * YYYY MM DD
- * Last updated 2018 / 11 / 14
+ * Last updated 2015 / 05 / 03 - SRB2 v2.1.15 - srb2.srb
+ * Last updated 2018 / 12 / 23 - SRB2 v2.1.22 - patch.dta
+ * Last updated 2018 / 11 / 16 - Kart v1.0.0 - Main assets
+ * Last updated 2018 / 12 / 13 - Kart v1.0.2 - patch.kart
*/
// Base SRB2 hashes
#define ASSET_HASH_SRB2_SRB "c1b9577687f8a795104aef4600720ea7"
#ifdef USE_PATCH_DTA
-#define ASSET_HASH_PATCH_DTA "dbbf8bc6121618ee3be2d5b14650429b"
+#define ASSET_HASH_PATCH_DTA "b04fd9624bfd94dc96dcf4f400f7deb4"
#endif
// SRB2Kart-specific hashes
diff --git a/src/console.c b/src/console.c
index d98fe45b..a10d73e7 100644
--- a/src/console.c
+++ b/src/console.c
@@ -59,10 +59,7 @@ static boolean consoleready; // console prompt is ready
INT32 con_destlines; // vid lines used by console at final position
static INT32 con_curlines; // vid lines currently used by console
- INT32 con_clipviewtop; // clip value for planes & sprites, so that the
- // part of the view covered by the console is not
- // drawn when not needed, this must be -1 when
- // console is off
+ INT32 con_clipviewtop; // (useless)
static INT32 con_hudlines; // number of console heads up message lines
static INT32 con_hudtime[MAXHUDLINES]; // remaining time of display for hud msg lines
@@ -285,6 +282,7 @@ void CON_SetupBackColormap(void)
case 18: palindex = 255; shift = 7; break; // Lavender
// Default green
default: palindex = 175; break;
+
}
// setup background colormap
@@ -892,7 +890,7 @@ boolean CON_Responder(event_t *ev)
// ...why shouldn't it eat the key? if it doesn't, it just means you
// can control Sonic from the console, which is silly
- return true; //return false;
+ return true;//return false;
}
// command completion forward (tab) and backward (shift-tab)
@@ -1110,7 +1108,7 @@ boolean CON_Responder(event_t *ev)
// enter a char into the command prompt
if (key < 32 || key > 127)
- return true; // even if key can't be printed, eat it anyway
+ return true;
// add key to cmd line here
if (key >= 'A' && key <= 'Z' && !(shiftdown ^ capslock)) //this is only really necessary for dedicated servers
@@ -1495,7 +1493,7 @@ static void CON_DrawHudlines(void)
return;
if (chat_on && OLDCHAT)
- y = charheight; // leave place for chat input in the first row of text
+ y = charheight; // leave place for chat input in the first row of text (only do it if consolechat is on.)
else
y = 0;
diff --git a/src/d_clisrv.c b/src/d_clisrv.c
index eafc1283..be639034 100644
--- a/src/d_clisrv.c
+++ b/src/d_clisrv.c
@@ -1487,9 +1487,11 @@ static boolean SV_SendServerConfig(INT32 node)
for (i = 0; i < MAXPLAYERS; i++)
{
+ netbuffer->u.servercfg.adminplayers[i] = (SINT8)adminplayers[i];
+
if (!playeringame[i])
continue;
- netbuffer->u.servercfg.adminplayers[i] = (SINT8)adminplayers[i];
+
netbuffer->u.servercfg.playerskins[i] = (UINT8)players[i].skin;
netbuffer->u.servercfg.playercolor[i] = (UINT8)players[i].skincolor;
}
@@ -2774,13 +2776,16 @@ static void Command_Kick(void)
if (pn == -1 || pn == 0)
return;
- // Special case if we are trying to kick a player who is downloading the game state:
- // trigger a timeout instead of kicking them, because a kick would only
- // take effect after they have finished downloading
- if (sendingsavegame[playernode[pn]])
+ if (server)
{
- Net_ConnectionTimeout(playernode[pn]);
- return;
+ // Special case if we are trying to kick a player who is downloading the game state:
+ // trigger a timeout instead of kicking them, because a kick would only
+ // take effect after they have finished downloading
+ if (sendingsavegame[playernode[pn]])
+ {
+ Net_ConnectionTimeout(playernode[pn]);
+ return;
+ }
}
WRITESINT8(p, pn);
@@ -2834,7 +2839,9 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
}
// Is playernum authorized to make this kick?
- if (playernum != serverplayer && !IsPlayerAdmin(playernum))
+ if (playernum != serverplayer && !IsPlayerAdmin(playernum)
+ /*&& !(playerpernode[playernode[playernum]] == 2
+ //&& nodetoplayer2[playernode[playernum]] == pnum)*/)
{
// We received a kick command from someone who isn't the
// server or admin, and who isn't in splitscreen removing
@@ -3306,14 +3313,14 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
if (netgame)
{
- if (server && netgame && cv_showjoinaddress.value)
+ if (server && cv_showjoinaddress.value)
{
const char *address;
if (I_GetNodeAddress && (address = I_GetNodeAddress(node)) != NULL)
HU_AddChatText(va("\x82*Player %d has joined the game (node %d) (%s)", newplayernum+1, node, address), false); // merge join notification + IP to avoid clogging console/chat.
}
else
- HU_AddChatText(va("\x82*Player %d has joined the game (node %d)", newplayernum+1, node), false);
+ HU_AddChatText(va("\x82*Player %d has joined the game (node %d)", newplayernum+1, node), false); // if you don't wanna see the join address.
}
if (server && multiplayer && motd[0] != '\0')
diff --git a/src/d_clisrv.h b/src/d_clisrv.h
index 4207325e..f1abffaf 100644
--- a/src/d_clisrv.h
+++ b/src/d_clisrv.h
@@ -478,9 +478,9 @@ extern doomdata_t *netbuffer;
extern consvar_t cv_showjoinaddress;
extern consvar_t cv_playbackspeed;
-#define BASEPACKETSIZE ((size_t)&(((doomdata_t *)0)->u))
-#define FILETXHEADER ((size_t)((filetx_pak *)0)->data)
-#define BASESERVERTICSSIZE ((size_t)&(((doomdata_t *)0)->u.serverpak.cmds[0]))
+#define BASEPACKETSIZE offsetof(doomdata_t, u)
+#define FILETXHEADER offsetof(filetx_pak, data)
+#define BASESERVERTICSSIZE offsetof(doomdata_t, u.serverpak.cmds[0])
#define KICK_MSG_GO_AWAY 1
#define KICK_MSG_CON_FAIL 2
diff --git a/src/d_main.c b/src/d_main.c
index 6d130d76..2a5993c1 100644
--- a/src/d_main.c
+++ b/src/d_main.c
@@ -188,7 +188,7 @@ void D_PostEvent_end(void) {};
UINT8 shiftdown = 0; // 0x1 left, 0x2 right
UINT8 ctrldown = 0; // 0x1 left, 0x2 right
UINT8 altdown = 0; // 0x1 left, 0x2 right
-boolean capslock = 0; // jeez i wonder what this does.
+boolean capslock = 0; // gee i wonder what this does.
//
// D_ModifierKeyResponder
// Sets global shift/ctrl/alt variables, never actually eats events
@@ -321,7 +321,7 @@ static void D_Display(void)
F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK);
}
- if (wipegamestate == GS_LEVEL && rendermode != render_none)
+ if (gamestate != GS_LEVEL && rendermode != render_none)
{
V_SetPaletteLump("PLAYPAL"); // Reset the palette
R_ReInitColormaps(0, LUMPERROR);
@@ -338,8 +338,7 @@ static void D_Display(void)
if (!gametic)
break;
HU_Erase();
- if (automapactive)
- AM_Drawer();
+ AM_Drawer();
break;
case GS_INTERMISSION:
@@ -412,12 +411,10 @@ static void D_Display(void)
break;
}
- // clean up border stuff
- // see if the border needs to be initially drawn
if (gamestate == GS_LEVEL)
{
// draw the view directly
- if (!automapactive && !dedicated && cv_renderview.value)
+ if (cv_renderview.value && !automapactive)
{
if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD)
{
@@ -536,7 +533,6 @@ static void D_Display(void)
}
ST_Drawer();
-
HU_Drawer();
}
@@ -926,20 +922,20 @@ static void IdentifyVersion(void)
// if you change the ordering of this or add/remove a file, be sure to update the md5
// checking in D_SRB2Main
- // Add the maps
- //D_AddFile(va(pandf,srb2waddir,"zones.dta"));
-
- // Add the players
- //D_AddFile(va(pandf,srb2waddir, "player.dta"));
-
- // Add the weapons
- //D_AddFile(va(pandf,srb2waddir,"rings.dta"));
-
#ifdef USE_PATCH_DTA
// Add our crappy patches to fix our bugs
D_AddFile(va(pandf,srb2waddir,"patch.dta"));
#endif
+ D_AddFile(va(pandf,srb2waddir,"gfx.kart"));
+ D_AddFile(va(pandf,srb2waddir,"textures.kart"));
+ D_AddFile(va(pandf,srb2waddir,"chars.kart"));
+ D_AddFile(va(pandf,srb2waddir,"maps.kart"));
+#ifdef USE_PATCH_KART
+ D_AddFile(va(pandf,srb2waddir,"patch.kart"));
+#endif
+
+#if !defined (HAVE_SDL) || defined (HAVE_MIXER)
#define MUSICTEST(str) \
{\
const char *musicpath = va(pandf,srb2waddir,str);\
@@ -949,21 +945,10 @@ static void IdentifyVersion(void)
else if (ms == 0) \
I_Error("File "str" has been modified with non-music/sound lumps"); \
}
-
- // SRB2kart - Add graphics (temp) // The command for md5 checks is "W_VerifyFileMD5" - looks for ASSET_HASH_SRB2_SRB in config.h.in
- D_AddFile(va(pandf,srb2waddir,"gfx.kart"));
- D_AddFile(va(pandf,srb2waddir,"textures.kart"));
- D_AddFile(va(pandf,srb2waddir,"chars.kart"));
- D_AddFile(va(pandf,srb2waddir,"maps.kart"));
- //D_AddFile(va(pandf,srb2waddir,"sounds.kart"));
MUSICTEST("sounds.kart")
-
-#ifdef USE_PATCH_KART
- D_AddFile(va(pandf,srb2waddir,"patch.kart"));
-#endif
-
- //MUSICTEST("music.dta")
MUSICTEST("music.kart")
+#undef MUSICTEST
+#endif
}
/* ======================================================================== */
@@ -1239,25 +1224,20 @@ void D_SRB2Main(void)
mainwads = 0;
-#ifndef DEVELOP // md5s last updated 12/14/14
-
+#ifndef DEVELOP
// Check MD5s of autoloaded files
- W_VerifyFileMD5(mainwads, ASSET_HASH_SRB2_SRB); // srb2.srb/srb2.wad
+ // Note: Do not add any files that ignore MD5!
+ W_VerifyFileMD5(mainwads, ASSET_HASH_SRB2_SRB); // srb2.srb/srb2.wad
#ifdef USE_PATCH_DTA
- mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_PATCH_DTA); // patch.dta
+ mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_PATCH_DTA); // patch.dta
#endif
- mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_GFX_KART); // gfx.kart
- mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_TEXTURES_KART); // textures.kart
- mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_CHARS_KART); // chars.kart
- mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_MAPS_KART); // maps.kart
- mainwads++; //W_VerifyFileMD5(5, ASSET_HASH_SOUNDS_KART); -- sounds.kart - doesn't trigger modifiedgame, doesn't need an MD5...?
+ mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_GFX_KART); // gfx.kart
+ mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_TEXTURES_KART); // textures.kart
+ mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_CHARS_KART); // chars.kart
+ mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_MAPS_KART); // maps.kart
#ifdef USE_PATCH_KART
- mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_PATCH_KART); // patch.kart
+ mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_PATCH_KART); // patch.kart
#endif
- //mainwads++; // music.dta
- mainwads++; // music.kart
- // don't check music.dta or kart because people like to modify it, and it doesn't matter if they do
- // ...except it does if they slip maps in there, and that's what W_VerifyNMUSlumps is for.
#else
#ifdef USE_PATCH_DTA
mainwads++; // patch.dta
@@ -1266,12 +1246,10 @@ void D_SRB2Main(void)
mainwads++; // textures.kart
mainwads++; // chars.kart
mainwads++; // maps.kart
- mainwads++; // sounds.kart
#ifdef USE_PATCH_KART
mainwads++; // patch.kart
#endif
- //mainwads++; // music.dta
- mainwads++; // music.kart
+
#endif //ifndef DEVELOP
mainwadstally = packetsizetally;
diff --git a/src/d_net.c b/src/d_net.c
index eae921fa..62301dc1 100644
--- a/src/d_net.c
+++ b/src/d_net.c
@@ -27,6 +27,7 @@
#include "d_clisrv.h"
#include "z_zone.h"
#include "i_tcp.h"
+#include "d_main.h" // srb2home
//
// NETWORKING
@@ -1386,12 +1387,12 @@ boolean D_CheckNetGame(void)
{
k++;
sprintf(filename, "debug%d.txt", k);
- debugfile = fopen(filename, "w");
+ debugfile = fopen(va("%s" PATHSEP "%s", srb2home, filename), "w");
}
if (debugfile)
- CONS_Printf(M_GetText("debug output to: %s\n"), filename);
+ CONS_Printf(M_GetText("debug output to: %s\n"), va("%s" PATHSEP "%s", srb2home, filename));
else
- CONS_Alert(CONS_WARNING, M_GetText("cannot debug output to file %s!\n"), filename);
+ CONS_Alert(CONS_WARNING, M_GetText("cannot debug output to file %s!\n"), va("%s" PATHSEP "%s", srb2home, filename));
}
#endif
#endif
diff --git a/src/d_net.h b/src/d_net.h
index 0174ba89..9cc1bbd2 100644
--- a/src/d_net.h
+++ b/src/d_net.h
@@ -22,6 +22,7 @@
#define MAXNETNODES 16
#define BROADCASTADDR MAXNETNODES
#define MAXSPLITSCREENPLAYERS 4 // Max number of players on a single computer
+#define NETSPLITSCREEN // Kart's splitscreen netgame feature
#define STATLENGTH (TICRATE*2)
diff --git a/src/d_netcmd.c b/src/d_netcmd.c
index f2979838..d38a814e 100644
--- a/src/d_netcmd.c
+++ b/src/d_netcmd.c
@@ -272,6 +272,7 @@ INT32 cv_debug;
consvar_t cv_usemouse = {"use_mouse", "Off", CV_SAVE|CV_CALL,usemouse_cons_t, I_StartupMouse, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_usemouse2 = {"use_mouse2", "Off", CV_SAVE|CV_CALL,usemouse_cons_t, I_StartupMouse2, 0, NULL, NULL, 0, 0, NULL};
+#if defined (DC) || defined (_XBOX) || defined (WMINPUT) || defined (_WII) || defined(HAVE_SDL) || defined(_WINDOWS) //joystick 1 and 2
consvar_t cv_usejoystick = {"use_joystick", "1", CV_SAVE|CV_CALL, usejoystick_cons_t,
I_InitJoystick, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_usejoystick2 = {"use_joystick2", "2", CV_SAVE|CV_CALL, usejoystick_cons_t,
@@ -280,6 +281,7 @@ consvar_t cv_usejoystick3 = {"use_joystick3", "3", CV_SAVE|CV_CALL, usejoystick_
I_InitJoystick3, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_usejoystick4 = {"use_joystick4", "4", CV_SAVE|CV_CALL, usejoystick_cons_t,
I_InitJoystick4, 0, NULL, NULL, 0, 0, NULL};
+#endif
#if (defined (LJOYSTICK) || defined (HAVE_SDL))
#ifdef LJOYSTICK
@@ -781,6 +783,7 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_usegamma);
// m_menu.c
+ //CV_RegisterVar(&cv_compactscoreboard);
CV_RegisterVar(&cv_chatheight);
CV_RegisterVar(&cv_chatwidth);
CV_RegisterVar(&cv_chattime);
@@ -835,6 +838,14 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_addons_search_type);
CV_RegisterVar(&cv_addons_search_case);
+ // filesrch.c
+ CV_RegisterVar(&cv_addons_option);
+ CV_RegisterVar(&cv_addons_folder);
+ CV_RegisterVar(&cv_addons_md5);
+ CV_RegisterVar(&cv_addons_showall);
+ CV_RegisterVar(&cv_addons_search_type);
+ CV_RegisterVar(&cv_addons_search_case);
+
// WARNING: the order is important when initialising mouse2
// we need the mouse2port
CV_RegisterVar(&cv_mouse2port);
@@ -3532,12 +3543,6 @@ void SetAdminPlayer(INT32 playernum)
adminplayers[i] = playernum; // Set the player to a free spot
break; // End the loop now. If it keeps going, the same player might get assigned to two slots.
}
-
- /*if (i == 3 && adminplayers[i] != -1) // End of the loop and all slots are full
- {
- adminplayers[0] = playernum; // Overwrite the first slot
- break;
- }*/
}
}
@@ -3709,7 +3714,7 @@ static void Command_MotD_f(void)
}
if ((netgame || multiplayer) && client)
- SendNetXCmd(XD_SETMOTD, mymotd, sizeof(motd));
+ SendNetXCmd(XD_SETMOTD, mymotd, i); // send the actual size of the motd string, not the full buffer's size
else
{
strcpy(motd, mymotd);
@@ -3978,6 +3983,10 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
boolean kick = false;
boolean toomany = false;
INT32 i,j;
+ serverinfo_pak *dummycheck = NULL;
+
+ // Shut the compiler up.
+ (void)dummycheck;
READSTRINGN(*cp, filename, 240);
READMEM(*cp, md5sum, 16);
@@ -4146,6 +4155,52 @@ static void Command_Version_f(void)
#else
CONS_Printf("SRB2Kart %s (%s %s %s)\n", VERSIONSTRING, compdate, comptime, comprevision);
#endif
+
+ // Base library
+#if defined( HAVE_SDL)
+ CONS_Printf("SDL ");
+#elif defined(_WINDOWS)
+ CONS_Printf("DD ");
+#endif
+
+ // OS
+ // Would be nice to use SDL_GetPlatform for this
+#if defined (_WIN32) || defined (_WIN64)
+ CONS_Printf("Windows ");
+#elif defined(__linux__)
+ CONS_Printf("Linux ");
+#elif defined(MACOSX)
+ CONS_Printf("macOS ");
+#elif defined(UNIXCOMMON)
+ CONS_Printf("Unix (Common) ");
+#else
+ CONS_Printf("Other OS ");
+#endif
+
+ // Bitness
+ if (sizeof(void*) == 4)
+ CONS_Printf("32-bit ");
+ else if (sizeof(void*) == 8)
+ CONS_Printf("64-bit ");
+ else // 16-bit? 128-bit?
+ CONS_Printf("Bits Unknown ");
+
+ // No ASM?
+#ifdef NOASM
+ CONS_Printf("\x85" "NOASM " "\x80");
+#endif
+
+ // Debug build
+#ifdef _DEBUG
+ CONS_Printf("\x85" "DEBUG " "\x80");
+#endif
+
+ // DEVELOP build
+#ifdef DEVELOP
+ CONS_Printf("\x87" "DEVELOP " "\x80");
+#endif
+
+ CONS_Printf("\n");
}
#ifdef UPDATE_ALERT
diff --git a/src/dehacked.c b/src/dehacked.c
index 8cb70412..829acbc0 100644
--- a/src/dehacked.c
+++ b/src/dehacked.c
@@ -1261,6 +1261,18 @@ static void readlevelheader(MYFILE *f, INT32 num)
deh_warning("Level header %d: invalid bonus type number %d", num, i);
}
+ else if (fastcmp(word, "SAVEOVERRIDE"))
+ {
+ if (fastcmp(word2, "DEFAULT")) i = SAVE_DEFAULT;
+ else if (fastcmp(word2, "ALWAYS")) i = SAVE_ALWAYS;
+ else if (fastcmp(word2, "NEVER")) i = SAVE_NEVER;
+
+ if (i >= SAVE_NEVER && i <= SAVE_ALWAYS)
+ mapheaderinfo[num-1]->saveoverride = (SINT8)i;
+ else
+ deh_warning("Level header %d: invalid save override number %d", num, i);
+ }
+
else if (fastcmp(word, "LEVELFLAGS"))
mapheaderinfo[num-1]->levelflags = get_number(word2);
else if (fastcmp(word, "MENUFLAGS"))
@@ -2993,7 +3005,7 @@ static void readmaincfg(MYFILE *f)
else if (fastcmp(word, "USENIGHTSSS"))
{
DEH_WriteUndoline(word, va("%d", useNightsSS), UNDO_NONE);
- useNightsSS = (UINT8)(value || word2[0] == 'T' || word2[0] == 'Y');
+ useNightsSS = (value || word2[0] == 'T' || word2[0] == 'Y');
}
else if (fastcmp(word, "REDTEAM"))
{
@@ -3067,7 +3079,7 @@ static void readmaincfg(MYFILE *f)
else if (fastcmp(word, "LOOPTITLE"))
{
DEH_WriteUndoline(word, va("%d", looptitle), UNDO_NONE);
- looptitle = (boolean)(value || word2[0] == 'T' || word2[0] == 'Y');
+ looptitle = (value || word2[0] == 'T' || word2[0] == 'Y');
}
else if (fastcmp(word, "TITLESCROLLSPEED"))
{
@@ -3085,7 +3097,7 @@ static void readmaincfg(MYFILE *f)
else if (fastcmp(word, "DISABLESPEEDADJUST"))
{
DEH_WriteUndoline(word, va("%d", disableSpeedAdjust), UNDO_NONE);
- disableSpeedAdjust = (UINT8)get_number(word2);
+ disableSpeedAdjust = (value || word2[0] == 'T' || word2[0] == 'Y');
}
else if (fastcmp(word, "NUMDEMOS"))
{
@@ -3134,7 +3146,7 @@ static void readmaincfg(MYFILE *f)
strncpy(timeattackfolder, gamedatafilename, filenamelen);
timeattackfolder[min(filenamelen, sizeof (timeattackfolder) - 1)] = '\0';
- strncpy(savegamename, timeattackfolder, strlen(timeattackfolder));
+ strcpy(savegamename, timeattackfolder);
strlcat(savegamename, "%u.ssg", sizeof(savegamename));
// can't use sprintf since there is %u in savegamename
strcatbf(savegamename, srb2home, PATHSEP);
@@ -8441,6 +8453,11 @@ struct {
{"LF2_NIGHTSATTACK",LF2_NIGHTSATTACK},
{"LF2_NOVISITNEEDED",LF2_NOVISITNEEDED},
+ // Save override
+ {"SAVE_NEVER",SAVE_NEVER},
+ {"SAVE_DEFAULT",SAVE_DEFAULT},
+ {"SAVE_ALWAYS",SAVE_ALWAYS},
+
// NiGHTS grades
{"GRADE_F",GRADE_F},
{"GRADE_E",GRADE_E},
@@ -9752,10 +9769,11 @@ static inline int lib_getenum(lua_State *L)
return 0;
LUA_PushUserdata(L, &players[serverplayer], META_PLAYER);
return 1;
- /*} else if (fastcmp(word,"admin")) { // Replaced with IsPlayerAdmin
- if (!playeringame[adminplayer] || IsPlayerAdmin(serverplayer))
+ /*} else if (fastcmp(word,"admin")) {
+ LUA_Deprecated(L, "admin", "IsPlayerAdmin(player)");
+ if (!playeringame[adminplayers[0]] || IsPlayerAdmin(serverplayer))
return 0;
- LUA_PushUserdata(L, &players[adminplayer], META_PLAYER);
+ LUA_PushUserdata(L, &players[adminplayers[0]], META_PLAYER);
return 1;*/
} else if (fastcmp(word,"emeralds")) {
lua_pushinteger(L, emeralds);
@@ -9793,8 +9811,10 @@ static inline int lib_getenum(lua_State *L)
} else if (fastcmp(word,"spbplace")) {
lua_pushinteger(L, spbplace);
return 1;
+ } else if (fastcmp(word,"mapobjectscale")) {
+ lua_pushinteger(L, mapobjectscale);
+ return 1;
}
-
return 0;
}
diff --git a/src/doomdef.h b/src/doomdef.h
index a35f3291..975c920b 100644
--- a/src/doomdef.h
+++ b/src/doomdef.h
@@ -164,6 +164,9 @@ extern FILE *logstream;
// Kart has it's own, as well.
#define USE_PATCH_KART
+// Use .kart extension addons
+#define USE_KART
+
// Modification options
// If you want to take advantage of the Master Server's ability to force clients to update
// to the latest version, fill these out. Otherwise, just comment out UPDATE_ALERT and leave
@@ -220,6 +223,21 @@ extern FILE *logstream;
// Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1".
#define MODVERSION 2
+// Filter consvars by version
+// To version config.cfg, MAJOREXECVERSION is set equal to MODVERSION automatically.
+// Increment MINOREXECVERSION whenever a config change is needed that does not correspond
+// to an increment in MODVERSION. This might never happen in practice.
+// If MODVERSION increases, set MINOREXECVERSION to 0.
+#define MAJOREXECVERSION MODVERSION
+#define MINOREXECVERSION 0
+// (It would have been nice to use VERSION and SUBVERSION but those are zero'd out for DEVELOP builds)
+
+// Macros
+#define GETMAJOREXECVERSION(v) (v & 0xFFFF)
+#define GETMINOREXECVERSION(v) (v >> 16)
+#define GETEXECVERSION(major,minor) (major + (minor << 16))
+#define EXECVERSION GETEXECVERSION(MAJOREXECVERSION, MINOREXECVERSION)
+
// =========================================================================
// The maximum number of players, multiplayer/networking.
@@ -286,7 +304,7 @@ typedef enum
SKINCOLOR_SLATE,
SKINCOLOR_STEEL,
SKINCOLOR_JET,
- SKINCOLOR_SAPPHIRE, // sweet mother, i cannot weave – slender aphrodite has overcome me with longing for a girl
+ SKINCOLOR_SAPPHIRE, // sweet mother, i cannot weave - slender aphrodite has overcome me with longing for a girl
SKINCOLOR_PERIWINKLE,
SKINCOLOR_BLUE,
SKINCOLOR_BLUEBERRY,
@@ -453,6 +471,15 @@ INT32 I_GetKey(void);
#define max(x, y) (((x) > (y)) ? (x) : (y))
#endif
+// Floating point comparison epsilons from float.h
+#ifndef FLT_EPSILON
+#define FLT_EPSILON 1.1920928955078125e-7f
+#endif
+
+#ifndef DBL_EPSILON
+#define DBL_EPSILON 2.2204460492503131e-16
+#endif
+
// An assert-type mechanism.
#ifdef PARANOIA
#define I_Assert(e) ((e) ? (void)0 : I_Error("assert failed: %s, file %s, line %d", #e, __FILE__, __LINE__))
diff --git a/src/doomstat.h b/src/doomstat.h
index 69e2e7cd..6d710e28 100644
--- a/src/doomstat.h
+++ b/src/doomstat.h
@@ -247,6 +247,7 @@ typedef struct
SINT8 unlockrequired; ///< Is an unlockable required to play this level? -1 if no.
UINT8 levelselect; ///< Is this map available in the level select? If so, which map list is it available in?
SINT8 bonustype; ///< What type of bonus does this level have? (-1 for null.)
+ SINT8 saveoverride; ///< Set how the game is allowed to save (1 for always, -1 for never, 0 is 2.1 default)
UINT8 levelflags; ///< LF_flags: merged eight booleans into one UINT8 for space, see below
UINT8 menuflags; ///< LF2_flags: options that affect record attack / nights mode menus
@@ -279,6 +280,11 @@ typedef struct
#define LF2_NIGHTSATTACK 8 ///< Show this map in NiGHTS mode menu
#define LF2_NOVISITNEEDED 16 ///< Available in time attack/nights mode without visiting the level
+// Save override
+#define SAVE_NEVER -1
+#define SAVE_DEFAULT 0
+#define SAVE_ALWAYS 1
+
extern mapheader_t* mapheaderinfo[NUMMAPS];
enum TypeOfLevel
@@ -438,6 +444,7 @@ extern mobj_t *hunt1, *hunt2, *hunt3; // Emerald hunt locations
extern UINT32 countdown, countdown2;
extern fixed_t gravity;
+extern fixed_t mapobjectscale;
//for CTF balancing
extern INT16 autobalance;
diff --git a/src/f_finale.c b/src/f_finale.c
index 24acf2d6..d210b9c8 100644
--- a/src/f_finale.c
+++ b/src/f_finale.c
@@ -175,7 +175,7 @@ static void F_SkyScroll(INT32 scrollspeed)
{
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 120);
- x = -animtimer;
+ x = -((INT32)animtimer);
y = 0;
while (x < w)
{
diff --git a/src/filesrch.c b/src/filesrch.c
index e71b39d9..0276e1c9 100644
--- a/src/filesrch.c
+++ b/src/filesrch.c
@@ -552,7 +552,11 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
char exttable[NUM_EXT_TABLE][7] = { // maximum extension length (currently 4) plus 3 (null terminator, stop, and length including previous two)
"\5.txt", "\5.cfg", // exec
- "\5.wad", "\6.kart", "\5.pk3", "\5.soc", "\5.lua"}; // addfile
+ "\5.wad",
+#ifdef USE_KART
+ "\6.kart",
+#endif
+ "\5.pk3", "\5.soc", "\5.lua"}; // addfile
char filenamebuf[MAX_WADFILES][MAX_WADPATH];
diff --git a/src/filesrch.h b/src/filesrch.h
index 94c43ffa..4186271b 100644
--- a/src/filesrch.h
+++ b/src/filesrch.h
@@ -55,7 +55,9 @@ typedef enum
EXT_CFG,
EXT_LOADSTART,
EXT_WAD = EXT_LOADSTART,
+#ifdef USE_KART
EXT_KART,
+#endif
EXT_PK3,
EXT_SOC,
EXT_LUA, // allowed even if not HAVE_BLUA so that we can yell on load attempt
diff --git a/src/g_game.c b/src/g_game.c
index ac8e27a3..23f41564 100644
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -237,6 +237,7 @@ mobj_t *hunt3;
UINT32 countdown, countdown2; // for racing
fixed_t gravity;
+fixed_t mapobjectscale;
INT16 autobalance; //for CTF team balance
INT16 teamscramble; //for CTF team scramble
@@ -405,6 +406,10 @@ static CV_PossibleValue_t joyaxis_cons_t[] = {{0, "None"},
// don't mind me putting these here, I was lazy to figure out where else I could put those without blowing up the compiler.
+// it automatically becomes compact with 20+ players, but if you like it, I guess you can turn that on!
+// SRB2Kart: irrelevant for us.
+//consvar_t cv_compactscoreboard= {"compactscoreboard", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
+
// chat timer thingy
static CV_PossibleValue_t chattime_cons_t[] = {{5, "MIN"}, {999, "MAX"}, {0, NULL}};
consvar_t cv_chattime = {"chattime", "8", CV_SAVE, chattime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -462,7 +467,7 @@ consvar_t cv_brakeaxis = {"joyaxis_brake", "None", CV_SAVE, joyaxis_cons_t, NULL
consvar_t cv_aimaxis = {"joyaxis_aim", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_lookaxis = {"joyaxis_look", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_fireaxis = {"joyaxis_fire", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
-consvar_t cv_driftaxis = {"joyaxis_drift", "Z-Axis-", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
+consvar_t cv_driftaxis = {"joyaxis_drift", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_turnaxis2 = {"joyaxis2_turn", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_moveaxis2 = {"joyaxis2_move", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -470,7 +475,7 @@ consvar_t cv_brakeaxis2 = {"joyaxis2_brake", "None", CV_SAVE, joyaxis_cons_t, NU
consvar_t cv_aimaxis2 = {"joyaxis2_aim", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_lookaxis2 = {"joyaxis2_look", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_fireaxis2 = {"joyaxis2_fire", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
-consvar_t cv_driftaxis2 = {"joyaxis2_drift", "Z-Axis-", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
+consvar_t cv_driftaxis2 = {"joyaxis2_drift", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_turnaxis3 = {"joyaxis3_turn", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_moveaxis3 = {"joyaxis3_move", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -478,7 +483,7 @@ consvar_t cv_brakeaxis3 = {"joyaxis3_brake", "None", CV_SAVE, joyaxis_cons_t, NU
consvar_t cv_aimaxis3 = {"joyaxis3_aim", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_lookaxis3 = {"joyaxis3_look", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_fireaxis3 = {"joyaxis3_fire", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
-consvar_t cv_driftaxis3 = {"joyaxis3_drift", "Z-Axis-", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
+consvar_t cv_driftaxis3 = {"joyaxis3_drift", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_turnaxis4 = {"joyaxis4_turn", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_moveaxis4 = {"joyaxis4_move", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -486,7 +491,7 @@ consvar_t cv_brakeaxis4 = {"joyaxis4_brake", "None", CV_SAVE, joyaxis_cons_t, NU
consvar_t cv_aimaxis4 = {"joyaxis4_aim", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_lookaxis4 = {"joyaxis4_look", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_fireaxis4 = {"joyaxis4_fire", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
-consvar_t cv_driftaxis4 = {"joyaxis4_drift", "Z-Axis-", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
+consvar_t cv_driftaxis4 = {"joyaxis4_drift", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
#if MAXPLAYERS > 16
@@ -1111,7 +1116,6 @@ static INT32 Joy4Axis(axis_input_e axissel)
return 0;
}
-
if (axisval < 0) //odd -axises
{
axisval = -axisval;
@@ -1659,10 +1663,12 @@ static void Analog_OnChange(void)
// cameras are not initialized at this point
- /*if (!cv_chasecam.value && cv_analog.value) {
+ /*
+ if (!cv_chasecam.value && cv_analog.value) {
CV_SetValue(&cv_analog, 0);
return;
- }*/
+ }
+ */
SendWeaponPref();
}
@@ -1674,10 +1680,12 @@ static void Analog2_OnChange(void)
// cameras are not initialized at this point
- /*if (!cv_chasecam2.value && cv_analog2.value) {
+ /*
+ if (!cv_chasecam2.value && cv_analog2.value) {
CV_SetValue(&cv_analog2, 0);
return;
- }*/
+ }
+ */
SendWeaponPref2();
}
@@ -1689,10 +1697,12 @@ static void Analog3_OnChange(void)
// cameras are not initialized at this point
- /*if (!cv_chasecam3.value && cv_analog3.value) {
+ /*
+ if (!cv_chasecam3.value && cv_analog3.value) {
CV_SetValue(&cv_analog3, 0);
return;
- }*/
+ }
+ */
SendWeaponPref3();
}
@@ -1704,10 +1714,12 @@ static void Analog4_OnChange(void)
// cameras are not initialized at this point
- /*if (!cv_chasecam4.value && cv_analog4.value) {
+ /*
+ if (!cv_chasecam4.value && cv_analog4.value) {
CV_SetValue(&cv_analog4, 0);
return;
- }*/
+ }
+ */
SendWeaponPref4();
}
@@ -4369,7 +4381,7 @@ void G_InitNew(UINT8 pencoremode, const char *mapname, boolean resetplayer, bool
unlocktriggers = 0;
// clear itemfinder, just in case
- if (!dedicated) // except in dedicated servers, where it is not registered and can actually I_Error debug builds
+ if (!dedicated) // except in dedicated servers, where it is not registered and can actually I_Error debug builds
CV_StealthSetValue(&cv_itemfinder, 0);
}
diff --git a/src/g_game.h b/src/g_game.h
index 035a59bd..720d561f 100644
--- a/src/g_game.h
+++ b/src/g_game.h
@@ -54,7 +54,7 @@ extern tic_t timeinmap; // Ticker for time spent in level (used for levelcard di
extern INT16 rw_maximums[NUM_WEAPONS];
// used in game menu
-extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatspamprotection, cv_chatbacktint;
+extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection/*, cv_compactscoreboard*/;
//extern consvar_t cv_crosshair, cv_crosshair2, cv_crosshair3, cv_crosshair4;
extern consvar_t cv_invertmouse/*, cv_alwaysfreelook, cv_chasefreelook, cv_mousemove*/;
extern consvar_t cv_invertmouse2/*, cv_alwaysfreelook2, cv_chasefreelook2, cv_mousemove2*/;
diff --git a/src/g_input.c b/src/g_input.c
index e8b00e9d..d7b7be91 100644
--- a/src/g_input.c
+++ b/src/g_input.c
@@ -103,6 +103,8 @@ void G_MapEventsToControls(event_t *ev)
break;
case ev_mouse: // buttons are virtual keys
+ if (menuactive || CON_Ready() || chat_on)
+ break;
mousex = (INT32)(ev->data2*((cv_mousesens.value*cv_mousesens.value)/110.0f + 0.1f));
mousey = (INT32)(ev->data3*((cv_mousesens.value*cv_mousesens.value)/110.0f + 0.1f));
mlooky = (INT32)(ev->data3*((cv_mouseysens.value*cv_mousesens.value)/110.0f + 0.1f));
@@ -110,7 +112,7 @@ void G_MapEventsToControls(event_t *ev)
case ev_joystick: // buttons are virtual keys
i = ev->data1;
- if (i >= JOYAXISSET)
+ if (i >= JOYAXISSET || menuactive || CON_Ready() || chat_on)
break;
if (ev->data2 != INT32_MAX) joyxmove[i] = ev->data2;
if (ev->data3 != INT32_MAX) joyymove[i] = ev->data3;
@@ -118,7 +120,7 @@ void G_MapEventsToControls(event_t *ev)
case ev_joystick2: // buttons are virtual keys
i = ev->data1;
- if (i >= JOYAXISSET)
+ if (i >= JOYAXISSET || menuactive || CON_Ready() || chat_on)
break;
if (ev->data2 != INT32_MAX) joy2xmove[i] = ev->data2;
if (ev->data3 != INT32_MAX) joy2ymove[i] = ev->data3;
@@ -141,6 +143,8 @@ void G_MapEventsToControls(event_t *ev)
break;
case ev_mouse2: // buttons are virtual keys
+ if (menuactive || CON_Ready() || chat_on)
+ break;
mouse2x = (INT32)(ev->data2*((cv_mousesens2.value*cv_mousesens2.value)/110.0f + 0.1f));
mouse2y = (INT32)(ev->data3*((cv_mousesens2.value*cv_mousesens2.value)/110.0f + 0.1f));
mlook2y = (INT32)(ev->data3*((cv_mouseysens2.value*cv_mousesens2.value)/110.0f + 0.1f));
@@ -1228,6 +1232,16 @@ void G_ClearControlKeys(INT32 (*setupcontrols)[2], INT32 control)
setupcontrols[control][1] = KEY_NULL;
}
+void G_ClearAllControlKeys(void)
+{
+ INT32 i;
+ for (i = 0; i < num_gamecontrols; i++)
+ {
+ G_ClearControlKeys(gamecontrol, i);
+ G_ClearControlKeys(gamecontrolbis, i);
+ }
+}
+
//
// Returns the name of a key (or virtual key for mouse and joy)
// the input value being an keynum
@@ -1314,10 +1328,10 @@ void G_Controldefault(UINT8 player)
gamecontrol[gc_viewpoint ][1] = KEY_JOY1+3; // Y
gamecontrol[gc_pause ][1] = KEY_JOY1+6; // Back
gamecontrol[gc_systemmenu ][0] = KEY_JOY1+7; // Start
- gamecontrol[gc_camtoggle ][1] = KEY_HAT1+0; // D-Pad Up
- gamecontrol[gc_screenshot ][1] = KEY_HAT1+1; // D-Pad Down
- gamecontrol[gc_talkkey ][1] = KEY_HAT1+2; // D-Pad Left
- gamecontrol[gc_scores ][1] = KEY_HAT1+3; // D-Pad Right
+ //gamecontrol[gc_camtoggle ][1] = KEY_HAT1+0; // D-Pad Up
+ //gamecontrol[gc_screenshot ][1] = KEY_HAT1+1; // D-Pad Down // absolutely fucking NOT
+ gamecontrol[gc_talkkey ][1] = KEY_HAT1+1; // D-Pad Down
+ gamecontrol[gc_scores ][1] = KEY_HAT1+0; // D-Pad Up
}
if (player == 0 || player == 2)
@@ -1400,8 +1414,9 @@ void G_SaveKeySetting(FILE *f)
}
}
-void G_CheckDoubleUsage(INT32 keynum)
+INT32 G_CheckDoubleUsage(INT32 keynum, boolean modify)
{
+ INT32 result = gc_null;
if (cv_controlperkey.value == 1)
{
INT32 i, j;
@@ -1409,24 +1424,171 @@ void G_CheckDoubleUsage(INT32 keynum)
{
for (j = 0; j < 2; j++)
{
- if (gamecontrol[i][j] == keynum)
- gamecontrol[i][j] = KEY_NULL;
- if (gamecontrolbis[i][j] == keynum)
- gamecontrolbis[i][j] = KEY_NULL;
- if (gamecontrol3[i][j] == keynum)
- gamecontrol3[i][j] = KEY_NULL;
- if (gamecontrol4[i][j] == keynum)
- gamecontrol4[i][j] = KEY_NULL;
+ if (gamecontrol[i][j] == keynum) {
+ result = i;
+ if (modify) gamecontrol[i][j] = KEY_NULL;
+ }
+ if (gamecontrolbis[i][j] == keynum) {
+ result = i;
+ if (modify) gamecontrolbis[i][j] = KEY_NULL;
+ }
+ if (gamecontrol3[i][j] == keynum) {
+ result = i;
+ if (modify) gamecontrol3[i][j] = KEY_NULL;
+ }
+ if (gamecontrol4[i][j] == keynum) {
+ result = i;
+ if (modify) gamecontrol4[i][j] = KEY_NULL;
+ }
+ if (result && !modify)
+ return result;
}
}
}
+ return result;
}
-static void setcontrol(INT32 (*gc)[2], INT32 na)
+static INT32 G_FilterKeyByVersion(INT32 numctrl, INT32 keyidx, INT32 player, INT32 *keynum1, INT32 *keynum2, boolean *nestedoverride)
+{
+ // Special case: ignore KEY_PAUSE because it's hardcoded
+ if (keyidx == 0 && *keynum1 == KEY_PAUSE)
+ {
+ if (*keynum2 != KEY_PAUSE)
+ {
+ *keynum1 = *keynum2; // shift down keynum2 and continue
+ *keynum2 = 0;
+ }
+ else
+ return -1; // skip setting control
+ }
+ else if (keyidx == 1 && *keynum2 == KEY_PAUSE)
+ return -1; // skip setting control
+
+#if 1
+ // We don't have changed control defaults yet
+ (void)numctrl;
+ (void)player;
+ (void)nestedoverride;
+#else
+#if !defined (DC) && !defined (_PSP) && !defined (GP2X) && !defined (_NDS) && !defined(WMINPUT) && !defined(_WII)
+ if (GETMAJOREXECVERSION(cv_execversion.value) < 27 && ( // v2.1.22
+ numctrl == gc_weaponnext || numctrl == gc_weaponprev || numctrl == gc_tossflag ||
+ numctrl == gc_use || numctrl == gc_camreset || numctrl == gc_jump ||
+ numctrl == gc_pause || numctrl == gc_systemmenu || numctrl == gc_camtoggle ||
+ numctrl == gc_screenshot || numctrl == gc_talkkey || numctrl == gc_scores ||
+ numctrl == gc_centerview
+ ))
+ {
+ INT32 keynum = 0, existingctrl = 0;
+ INT32 defaultkey;
+ boolean defaultoverride = false;
+
+ // get the default gamecontrol
+ if (player == 0 && numctrl == gc_systemmenu)
+ defaultkey = gamecontrol[numctrl][0];
+ else
+ defaultkey = (player == 1 ? gamecontrolbis[numctrl][0] : gamecontrol[numctrl][1]);
+
+ // Assign joypad button defaults if there is an open slot.
+ // At this point, gamecontrol/bis should have the default controls
+ // (unless LOADCONFIG is being run)
+ //
+ // If the player runs SETCONTROL in-game, this block should not be reached
+ // because EXECVERSION is locked onto the latest version.
+ if (keyidx == 0 && !*keynum1)
+ {
+ if (*keynum2) // push keynum2 down; this is an edge case
+ {
+ *keynum1 = *keynum2;
+ *keynum2 = 0;
+ keynum = *keynum1;
+ }
+ else
+ {
+ keynum = defaultkey;
+ defaultoverride = true;
+ }
+ }
+ else if (keyidx == 1 && (!*keynum2 || (!*keynum1 && *keynum2))) // last one is the same edge case as above
+ {
+ keynum = defaultkey;
+ defaultoverride = true;
+ }
+ else // default to the specified keynum
+ keynum = (keyidx == 1 ? *keynum2 : *keynum1);
+
+ // Did our last call override keynum2?
+ if (*nestedoverride)
+ {
+ defaultoverride = true;
+ *nestedoverride = false;
+ }
+
+ // Fill keynum2 with the default control
+ if (keyidx == 0 && !*keynum2)
+ {
+ *keynum2 = defaultkey;
+ // Tell the next call that this is an override
+ *nestedoverride = true;
+
+ // if keynum2 already matches keynum1, we probably recursed
+ // so unset it
+ if (*keynum1 == *keynum2)
+ {
+ *keynum2 = 0;
+ *nestedoverride = false;
+ }
+ }
+
+ // check if the key is being used somewhere else before passing it
+ // pass it through if it's the same numctrl. This is an edge case -- when using
+ // LOADCONFIG, gamecontrol is not reset with default.
+ //
+ // Also, only check if we're actually overriding, to preserve behavior where
+ // config'd keys overwrite default keys.
+ if (defaultoverride)
+ existingctrl = G_CheckDoubleUsage(keynum, false);
+
+ if (keynum && (!existingctrl || existingctrl == numctrl))
+ return keynum;
+ else if (keyidx == 0 && *keynum2)
+ {
+ // try it again and push down keynum2
+ *keynum1 = *keynum2;
+ *keynum2 = 0;
+ return G_FilterKeyByVersion(numctrl, keyidx, player, keynum1, keynum2, nestedoverride);
+ // recursion *should* be safe because we only assign keynum2 to a joy default
+ // and then clear it if we find that keynum1 already has the joy default.
+ }
+ else
+ return 0;
+ }
+#endif
+#endif
+
+ // All's good, so pass the keynum as-is
+ if (keyidx == 1)
+ return *keynum2;
+ else //if (keyidx == 0)
+ return *keynum1;
+}
+
+static void setcontrol(INT32 (*gc)[2])
{
INT32 numctrl;
const char *namectrl;
- INT32 keynum;
+ INT32 keynum, keynum1, keynum2;
+ INT32 player;
+ boolean nestedoverride = false;
+
+ if ((void*)gc == (void*)&gamecontrol4)
+ player = 3;
+ else if ((void*)gc == (void*)&gamecontrol3)
+ player = 2;
+ else if ((void*)gc == (void*)&gamecontrolbis)
+ player = 1;
+ else
+ player = 0;
namectrl = COM_Argv(1);
for (numctrl = 0; numctrl < num_gamecontrols && stricmp(namectrl, gamecontrolname[numctrl]);
@@ -1437,31 +1599,38 @@ static void setcontrol(INT32 (*gc)[2], INT32 na)
CONS_Printf(M_GetText("Control '%s' unknown\n"), namectrl);
return;
}
- keynum = G_KeyStringtoNum(COM_Argv(2));
+ keynum1 = G_KeyStringtoNum(COM_Argv(2));
+ keynum2 = G_KeyStringtoNum(COM_Argv(3));
+ keynum = G_FilterKeyByVersion(numctrl, 0, player, &keynum1, &keynum2, &nestedoverride);
- if (keynum == KEY_PAUSE) // fail silently; pause is hardcoded
+ if (keynum >= 0)
{
- if (na == 4)
+ (void)G_CheckDoubleUsage(keynum, true);
+
+ // if keynum was rejected, try it again with keynum2
+ if (!keynum && keynum2)
{
- na--;
- keynum = G_KeyStringtoNum(COM_Argv(3));
- if (keynum == KEY_PAUSE)
- return;
+ keynum1 = keynum2; // push down keynum2
+ keynum2 = 0;
+ keynum = G_FilterKeyByVersion(numctrl, 0, player, &keynum1, &keynum2, &nestedoverride);
+ if (keynum >= 0)
+ (void)G_CheckDoubleUsage(keynum, true);
}
- else
- return;
}
- G_CheckDoubleUsage(keynum);
- gc[numctrl][0] = keynum;
+ if (keynum >= 0)
+ gc[numctrl][0] = keynum;
- if (na == 4)
+ if (keynum2)
{
- keynum = G_KeyStringtoNum(COM_Argv(3));
- if (keynum != KEY_PAUSE)
- gc[numctrl][1] = keynum;
- else
- gc[numctrl][1] = 0;
+ keynum = G_FilterKeyByVersion(numctrl, 1, player, &keynum1, &keynum2, &nestedoverride);
+ if (keynum >= 0)
+ {
+ if (keynum != gc[numctrl][0])
+ gc[numctrl][1] = keynum;
+ else
+ gc[numctrl][1] = 0;
+ }
}
else
gc[numctrl][1] = 0;
@@ -1479,7 +1648,7 @@ void Command_Setcontrol_f(void)
return;
}
- setcontrol(gamecontrol, na);
+ setcontrol(gamecontrol);
}
void Command_Setcontrol2_f(void)
@@ -1494,7 +1663,7 @@ void Command_Setcontrol2_f(void)
return;
}
- setcontrol(gamecontrolbis, na);
+ setcontrol(gamecontrolbis);
}
void Command_Setcontrol3_f(void)
@@ -1509,7 +1678,7 @@ void Command_Setcontrol3_f(void)
return;
}
- setcontrol(gamecontrol3, na);
+ setcontrol(gamecontrol3);
}
void Command_Setcontrol4_f(void)
@@ -1524,5 +1693,5 @@ void Command_Setcontrol4_f(void)
return;
}
- setcontrol(gamecontrol4, na);
-}
\ No newline at end of file
+ setcontrol(gamecontrol4);
+}
diff --git a/src/g_input.h b/src/g_input.h
index 966e186d..6d0c7e2c 100644
--- a/src/g_input.h
+++ b/src/g_input.h
@@ -161,12 +161,13 @@ INT32 G_KeyStringtoNum(const char *keystr);
// detach any keys associated to the given game control
void G_ClearControlKeys(INT32 (*setupcontrols)[2], INT32 control);
+void G_ClearAllControlKeys(void);
void Command_Setcontrol_f(void);
void Command_Setcontrol2_f(void);
void Command_Setcontrol3_f(void);
void Command_Setcontrol4_f(void);
void G_Controldefault(UINT8 player);
void G_SaveKeySetting(FILE *f);
-void G_CheckDoubleUsage(INT32 keynum);
+INT32 G_CheckDoubleUsage(INT32 keynum, boolean modify);
#endif
diff --git a/src/hardware/hw_bsp.c b/src/hardware/hw_bsp.c
index e02c3ede..48393249 100644
--- a/src/hardware/hw_bsp.c
+++ b/src/hardware/hw_bsp.c
@@ -194,14 +194,14 @@ static polyvertex_t *fracdivline(fdivline_t *bsp, polyvertex_t *v1,
v2dy = bsp->dy;
den = v2dy*v1dx - v2dx*v1dy;
- if (den == 0)
+ if (fabsf((float)den) < 1.0E-36f) // avoid checking exactly for 0.0
return NULL; // parallel
// first check the frac along the polygon segment,
// (do not accept hit with the extensions)
num = (v2x - v1x)*v2dy + (v1y - v2y)*v2dx;
frac = num / den;
- if (frac < 0 || frac > 1)
+ if (frac < 0.0 || frac > 1.0)
return NULL;
// now get the frac along the BSP line
@@ -218,29 +218,6 @@ static polyvertex_t *fracdivline(fdivline_t *bsp, polyvertex_t *v1,
return &pt;
}
-#if 0
-//Hurdler: it's not used anymore
-static boolean NearVertice (polyvertex_t *p1, polyvertex_t *p2)
-{
-#if 1
- float diff;
- diff = p2->x - p1->x;
- if (diff < -1.5f || diff > 1.5f)
- return false;
- diff = p2->y - p1->y;
- if (diff < -1.5f || diff > 1.5f)
- return false;
-#else
- if (p1->x != p2->x)
- return false;
- if (p1->y != p2->y)
- return false;
-#endif
- // p1 and p2 are considered the same vertex
- return true;
-}
-#endif
-
// if two vertice coords have a x and/or y difference
// of less or equal than 1 FRACUNIT, they are considered the same
// point. Note: hardcoded value, 1.0f could be anything else.
@@ -254,11 +231,23 @@ static boolean SameVertice (polyvertex_t *p1, polyvertex_t *p2)
diff = p2->y - p1->y;
if (diff < -1.5f || diff > 1.5f)
return false;
-#else
+#elif 0
if (p1->x != p2->x)
return false;
if (p1->y != p2->y)
return false;
+#elif 0
+ if (fabsf( p2->x - p1->x ) > 1.0E-36f )
+ return false;
+ if (fabsf( p2->y - p1->y ) > 1.0E-36f )
+ return false;
+#else
+#define DIVLINE_VERTEX_DIFF 0.45f
+ float ep = DIVLINE_VERTEX_DIFF;
+ if (fabsf( p2->x - p1->x ) > ep )
+ return false;
+ if (fabsf( p2->y - p1->y ) > ep )
+ return false;
#endif
// p1 and p2 are considered the same vertex
return true;
@@ -295,57 +284,57 @@ static void SplitPoly (fdivline_t *bsp, //splitting parametric line
// start & end points
pv = fracdivline(bsp, &poly->pts[i], &poly->pts[j]);
- if (pv)
+ if (pv == NULL)
+ continue;
+
+ if (ps < 0)
{
- if (ps < 0)
+ // first point
+ ps = i;
+ vs = *pv;
+ fracs = bspfrac;
+ }
+ else
+ {
+ //the partition line traverse a junction between two segments
+ // or the two points are so close, they can be considered as one
+ // thus, don't accept, since split 2 must be another vertex
+ if (SameVertice(pv, &lastpv))
{
- // first point
- ps = i;
- vs = *pv;
- fracs = bspfrac;
- }
- else
- {
- //the partition line traverse a junction between two segments
- // or the two points are so close, they can be considered as one
- // thus, don't accept, since split 2 must be another vertex
- if (SameVertice(pv, &lastpv))
+ if (pe < 0)
{
- if (pe < 0)
- {
- ps = i;
- psonline = 1;
- }
- else
- {
- pe = i;
- peonline = 1;
- }
+ ps = i;
+ psonline = 1;
}
else
{
- if (pe < 0)
- {
- pe = i;
- ve = *pv;
- frace = bspfrac;
- }
- else
- {
- // a frac, not same vertice as last one
- // we already got pt2 so pt 2 is not on the line,
- // so we probably got back to the start point
- // which is on the line
- if (SameVertice(pv, &vs))
- psonline = 1;
- break;
- }
+ pe = i;
+ peonline = 1;
+ }
+ }
+ else
+ {
+ if (pe < 0)
+ {
+ pe = i;
+ ve = *pv;
+ frace = bspfrac;
+ }
+ else
+ {
+ // a frac, not same vertice as last one
+ // we already got pt2 so pt 2 is not on the line,
+ // so we probably got back to the start point
+ // which is on the line
+ if (SameVertice(pv, &vs))
+ psonline = 1;
+ break;
}
}
-
- // remember last point intercept to detect identical points
- lastpv = *pv;
}
+
+ // remember last point intercept to detect identical points
+ lastpv = *pv;
}
// no split: the partition line is either parallel and
@@ -369,7 +358,7 @@ static void SplitPoly (fdivline_t *bsp, //splitting parametric line
return;
}
- if (ps >= 0 && pe < 0)
+ if (pe < 0)
{
//I_Error("SplitPoly: only one point for split line (%d %d)", ps, pe);
*frontpoly = poly;
@@ -388,7 +377,7 @@ static void SplitPoly (fdivline_t *bsp, //splitting parametric line
*backpoly = HWR_AllocPoly(2 + nptback);
else
*backpoly = NULL;
- if (nptfront)
+ if (nptfront > 0)
*frontpoly = HWR_AllocPoly(2 + nptfront);
else
*frontpoly = NULL;
@@ -483,42 +472,42 @@ static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 count, poly_t *poly)
pv = fracdivline(&cutseg, &poly->pts[i], &poly->pts[j]);
- if (pv)
+ if (pv == NULL)
+ continue;
+
+ if (ps < 0)
{
- if (ps < 0)
+ ps = i;
+ vs = *pv;
+ fracs = bspfrac;
+ }
+ else
+ {
+ //frac 1 on previous segment,
+ // 0 on the next,
+ //the split line goes through one of the convex poly
+ // vertices, happens quite often since the convex
+ // poly is already adjacent to the subsector segs
+ // on most borders
+ if (SameVertice(pv, &vs))
+ continue;
+
+ if (fracs <= bspfrac)
{
+ nump = 2 + poly->numpts - (i-ps);
+ pe = ps;
ps = i;
- vs = *pv;
- fracs = bspfrac;
+ ve = *pv;
}
else
{
- //frac 1 on previous segment,
- // 0 on the next,
- //the split line goes through one of the convex poly
- // vertices, happens quite often since the convex
- // poly is already adjacent to the subsector segs
- // on most borders
- if (SameVertice(pv, &vs))
- continue;
-
- if (fracs <= bspfrac)
- {
- nump = 2 + poly->numpts - (i-ps);
- pe = ps;
- ps = i;
- ve = *pv;
- }
- else
- {
- nump = 2 + (i-ps);
- pe = i;
- ve = vs;
- vs = *pv;
- }
- //found 2nd point
- break;
+ nump = 2 + (i-ps);
+ pe = i;
+ ve = vs;
+ vs = *pv;
}
+ //found 2nd point
+ break;
}
}
@@ -582,18 +571,42 @@ static inline void HWR_SubsecPoly(INT32 num, poly_t *poly)
// search for the segs source of this divline
static inline void SearchDivline(node_t *bsp, fdivline_t *divline)
{
-#if 0 // MAR - If you don't use the same partition line that the BSP uses, the front/back polys won't match the subsectors in the BSP!
-#endif
divline->x = FIXED_TO_FLOAT(bsp->x);
divline->y = FIXED_TO_FLOAT(bsp->y);
divline->dx = FIXED_TO_FLOAT(bsp->dx);
divline->dy = FIXED_TO_FLOAT(bsp->dy);
}
+#ifdef HWR_LOADING_SCREEN
//Hurdler: implement a loading status
static size_t ls_count = 0;
static UINT8 ls_percent = 0;
+static void loading_status(void)
+{
+ char s[16];
+ int x, y;
+
+ I_OsPolling();
+ CON_Drawer();
+ sprintf(s, "%d%%", (++ls_percent)<<1);
+ x = BASEVIDWIDTH/2;
+ y = BASEVIDHEIGHT/2;
+ V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); // Black background to match fade in effect
+ //V_DrawPatchFill(W_CachePatchName("SRB2BACK",PU_CACHE)); // SRB2 background, ehhh too bright.
+ M_DrawTextBox(x-58, y-8, 13, 1);
+ V_DrawString(x-50, y, V_YELLOWMAP, "Loading...");
+ V_DrawRightAlignedString(x+50, y, V_YELLOWMAP, s);
+
+ // Is this really necessary at this point..?
+ V_DrawCenteredString(BASEVIDWIDTH/2, 40, V_YELLOWMAP, "OPENGL MODE IS INCOMPLETE AND MAY");
+ V_DrawCenteredString(BASEVIDWIDTH/2, 50, V_YELLOWMAP, "NOT DISPLAY SOME SURFACES.");
+ V_DrawCenteredString(BASEVIDWIDTH/2, 70, V_YELLOWMAP, "USE AT SONIC'S RISK.");
+
+ I_UpdateNoVsync();
+}
+#endif
+
// poly : the convex polygon that encloses all child subsectors
static void WalkBSPNode(INT32 bspnum, poly_t *poly, UINT16 *leafnode, fixed_t *bbox)
{
@@ -631,38 +644,19 @@ static void WalkBSPNode(INT32 bspnum, poly_t *poly, UINT16 *leafnode, fixed_t *b
}
else
{
- HWR_SubsecPoly(bspnum&(~NF_SUBSECTOR), poly);
- //Hurdler: implement a loading status
+ HWR_SubsecPoly(bspnum & ~NF_SUBSECTOR, poly);
+ //Hurdler: implement a loading status
#ifdef HWR_LOADING_SCREEN
if (ls_count-- <= 0)
{
- char s[16];
- int x, y;
-
- I_OsPolling();
ls_count = numsubsectors/50;
- CON_Drawer();
- sprintf(s, "%d%%", (++ls_percent)<<1);
- x = BASEVIDWIDTH/2;
- y = BASEVIDHEIGHT/2;
- V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); // White background to match fade in effect
- //V_DrawPatchFill(W_CachePatchName("SRB2BACK",PU_CACHE)); // SRB2 background, ehhh too bright.
- M_DrawTextBox(x-58, y-8, 13, 1);
- V_DrawString(x-50, y, V_YELLOWMAP, "Loading...");
- V_DrawRightAlignedString(x+50, y, V_YELLOWMAP, s);
-
- // Is this really necessary at this point..?
- V_DrawCenteredString(BASEVIDWIDTH/2, 40, V_YELLOWMAP, "OPENGL MODE IS INCOMPLETE AND MAY");
- V_DrawCenteredString(BASEVIDWIDTH/2, 50, V_YELLOWMAP, "NOT DISPLAY SOME SURFACES.");
- V_DrawCenteredString(BASEVIDWIDTH/2, 70, V_YELLOWMAP, "USE AT SONIC'S RISK.");
-
- I_UpdateNoVsync();
+ loading_status();
}
#endif
}
M_ClearBox(bbox);
- poly = extrasubsectors[bspnum&~NF_SUBSECTOR].planepoly;
+ poly = extrasubsectors[bspnum & ~NF_SUBSECTOR].planepoly;
for (i = 0, pt = poly->pts; i < poly->numpts; i++,pt++)
M_AddToBox(bbox, FLOAT_TO_FIXED(pt->x), FLOAT_TO_FIXED(pt->y));
@@ -694,14 +688,13 @@ static void WalkBSPNode(INT32 bspnum, poly_t *poly, UINT16 *leafnode, fixed_t *b
if (backpoly)
{
// Correct back bbox to include floor/ceiling convex polygon
- WalkBSPNode(bsp->children[1], backpoly, &bsp->children[1],
- bsp->bbox[1]);
+ WalkBSPNode(bsp->children[1], backpoly, &bsp->children[1], bsp->bbox[1]);
- // enlarge bbox with seconde child
+ // enlarge bbox with second child
M_AddToBox(bbox, bsp->bbox[1][BOXLEFT ],
- bsp->bbox[1][BOXTOP ]);
+ bsp->bbox[1][BOXTOP ]);
M_AddToBox(bbox, bsp->bbox[1][BOXRIGHT ],
- bsp->bbox[1][BOXBOTTOM]);
+ bsp->bbox[1][BOXBOTTOM]);
}
}
@@ -781,9 +774,9 @@ static void SearchSegInBSP(INT32 bspnum,polyvertex_t *p,poly_t *poly)
if (bspnum & NF_SUBSECTOR)
{
- if (bspnum!=-1)
+ if (bspnum != -1)
{
- bspnum&=~NF_SUBSECTOR;
+ bspnum &= ~NF_SUBSECTOR;
q = extrasubsectors[bspnum].planepoly;
if (poly == q || !q)
return;
@@ -969,7 +962,9 @@ void HWR_CreatePlanePolygons(INT32 bspnum)
fixed_t rootbbox[4];
CONS_Debug(DBG_RENDER, "Creating polygons, please wait...\n");
+#ifdef HWR_LOADING_SCREEN
ls_count = ls_percent = 0; // reset the loading status
+#endif
CON_Drawer(); //let the user know what we are doing
I_FinishUpdate(); // page flip or blit buffer
diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c
index aeb41492..b39103ee 100644
--- a/src/hardware/hw_draw.c
+++ b/src/hardware/hw_draw.c
@@ -230,14 +230,14 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
Z_Free(realpatch);
}*/
// centre screen
- if ((float)vid.width != (float)BASEVIDWIDTH * dupx)
+ if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f)
{
if (option & V_SNAPTORIGHT)
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
else if (!(option & V_SNAPTOLEFT))
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/2;
}
- if ((float)vid.height != (float)BASEVIDHEIGHT * dupy)
+ if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f)
{
if ((option & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM))
cy += ((float)vid.height/2 - ((float)BASEVIDHEIGHT/2 * dupy));
@@ -378,14 +378,14 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
Z_Free(realpatch);
}*/
// centre screen
- if ((float)vid.width != (float)BASEVIDWIDTH * dupx)
+ if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f)
{
if (option & V_SNAPTORIGHT)
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
else if (!(option & V_SNAPTOLEFT))
cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/2;
}
- if ((float)vid.height != (float)BASEVIDHEIGHT * dupy)
+ if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f)
{
if ((option & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM))
cy += ((float)vid.height/2 - ((float)BASEVIDHEIGHT/2 * dupy));
@@ -777,18 +777,6 @@ void HWR_DrawViewBorder(INT32 clearlines)
// AM_MAP.C DRAWING STUFF
// ==========================================================================
-// Clear the automap part of the screen
-void HWR_clearAutomap(void)
-{
- FRGBAFloat fColor = {0, 0, 0, 1};
-
- // minx,miny,maxx,maxy
- HWD.pfnGClipRect(0, 0, vid.width, vid.height, NZCLIP_PLANE);
- HWD.pfnClearBuffer(true, true, &fColor);
- HWD.pfnGClipRect(0, 0, vid.width, vid.height, NZCLIP_PLANE);
-}
-
-
// -----------------+
// HWR_drawAMline : draw a line of the automap (the clipping is already done in automap code)
// Arg : color is a RGB 888 value
@@ -809,7 +797,6 @@ void HWR_drawAMline(const fline_t *fl, INT32 color)
HWD.pfnDraw2DLine(&v1, &v2, color_rgba);
}
-
// -----------------+
// HWR_DrawFill : draw flat coloured rectangle, with no texture
// -----------------+
@@ -853,14 +840,14 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
fw *= dupx;
fh *= dupy;
- if ((float)vid.width != (float)BASEVIDWIDTH * dupx)
+ if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f)
{
if (color & V_SNAPTORIGHT)
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
else if (!(color & V_SNAPTOLEFT))
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2;
}
- if ((float)vid.height != (float)BASEVIDHEIGHT * dupy)
+ if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f)
{
// same thing here
if (color & V_SNAPTOBOTTOM)
@@ -963,14 +950,14 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32
fw *= dupx;
fh *= dupy;
- if (vid.width != BASEVIDWIDTH * vid.dupx)
+ if (fabsf((float)vid.width - ((float)BASEVIDWIDTH * dupx)) > 1.0E-36f)
{
if (options & V_SNAPTORIGHT)
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
else if (!(options & V_SNAPTOLEFT))
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2;
}
- if (vid.height != BASEVIDHEIGHT * dupy)
+ if (fabsf((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) > 1.0E-36f)
{
// same thing here
if (options & V_SNAPTOBOTTOM)
@@ -1022,7 +1009,7 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32
v[2].sow = v[1].sow = 1.0f;
v[0].tow = v[1].tow = 0.0f;
v[2].tow = v[3].tow = 1.0f;
-
+
Surf.FlatColor.rgba = UINT2RGBA(color);
Surf.FlatColor.s.alpha = 0x80;
@@ -1059,14 +1046,14 @@ void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color)
fw *= dupx;
fh *= dupy;
- if (vid.width != BASEVIDWIDTH * vid.dupx)
+ if (fabsf((float)vid.width - ((float)BASEVIDWIDTH * dupx)) > 1.0E-36f)
{
if (color & V_SNAPTORIGHT)
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
else if (!(color & V_SNAPTOLEFT))
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2;
}
- if (vid.height != BASEVIDHEIGHT * dupy)
+ if (fabsf((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) > 1.0E-36f)
{
// same thing here
if (color & V_SNAPTOBOTTOM)
diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c
index e4c9e833..4d0a7236 100644
--- a/src/hardware/hw_main.c
+++ b/src/hardware/hw_main.c
@@ -4153,7 +4153,7 @@ static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float t
swallVerts[0].z = swallVerts[3].z = spr->z1;
swallVerts[2].z = swallVerts[1].z = spr->z2;
- if (spr->mobj && this_scale != 1.0f)
+ if (spr->mobj && fabsf(this_scale - 1.0f) > 1.0E-36f)
{
// Always a pixel above the floor, perfectly flat.
swallVerts[0].y = swallVerts[1].y = swallVerts[2].y = swallVerts[3].y = spr->ty - gpatch->topoffset * this_scale - (floorheight+3);
@@ -4321,7 +4321,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
wallVerts[1].z = wallVerts[2].z = spr->z2;
wallVerts[2].y = wallVerts[3].y = spr->ty;
- if (spr->mobj && this_scale != 1.0f)
+ if (spr->mobj && fabsf(this_scale - 1.0f) > 1.0E-36f)
wallVerts[0].y = wallVerts[1].y = spr->ty - gpatch->height * this_scale;
else
wallVerts[0].y = wallVerts[1].y = spr->ty - gpatch->height;
@@ -4350,6 +4350,16 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
wallVerts[0].tow = wallVerts[1].tow = gpatch->max_t;
}
+ // if it has a dispoffset, push it a little towards the camera
+ if (spr->dispoffset) {
+ float co = -gr_viewcos*(0.05f*spr->dispoffset);
+ float si = -gr_viewsin*(0.05f*spr->dispoffset);
+ wallVerts[0].z = wallVerts[3].z = wallVerts[0].z+si;
+ wallVerts[1].z = wallVerts[2].z = wallVerts[1].z+si;
+ wallVerts[0].x = wallVerts[3].x = wallVerts[0].x+co;
+ wallVerts[1].x = wallVerts[2].x = wallVerts[1].x+co;
+ }
+
realtop = top = wallVerts[3].y;
realbot = bot = wallVerts[0].y;
towtop = wallVerts[3].tow;
@@ -4602,7 +4612,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
wallVerts[0].x = wallVerts[3].x = spr->x1;
wallVerts[2].x = wallVerts[1].x = spr->x2;
wallVerts[2].y = wallVerts[3].y = spr->ty;
- if (spr->mobj && this_scale != 1.0f)
+ if (spr->mobj && fabsf(this_scale - 1.0f) > 1.0E-36f)
wallVerts[0].y = wallVerts[1].y = spr->ty - gpatch->height * this_scale;
else
wallVerts[0].y = wallVerts[1].y = spr->ty - gpatch->height;
@@ -4652,6 +4662,16 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
HWR_DrawSpriteShadow(spr, gpatch, this_scale);
}
+ // if it has a dispoffset, push it a little towards the camera
+ if (spr->dispoffset) {
+ float co = -gr_viewcos*(0.05f*spr->dispoffset);
+ float si = -gr_viewsin*(0.05f*spr->dispoffset);
+ wallVerts[0].z = wallVerts[3].z = wallVerts[0].z+si;
+ wallVerts[1].z = wallVerts[2].z = wallVerts[1].z+si;
+ wallVerts[0].x = wallVerts[3].x = wallVerts[0].x+co;
+ wallVerts[1].x = wallVerts[2].x = wallVerts[1].x+co;
+ }
+
// This needs to be AFTER the shadows so that the regular sprites aren't drawn completely black.
// sprite lighting by modulating the RGB components
/// \todo coloured
@@ -4848,7 +4868,7 @@ static void HWR_SortVisSprites(void)
best = ds;
}
// order visprites of same scale by dispoffset, smallest first
- else if (ds->tz == bestdist && ds->dispoffset < bestdispoffset)
+ else if (fabsf(ds->tz - bestdist) < 1.0E-36f && ds->dispoffset < bestdispoffset)
{
bestdispoffset = ds->dispoffset;
best = ds;
diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h
index f74814f0..198780f9 100644
--- a/src/hardware/hw_main.h
+++ b/src/hardware/hw_main.h
@@ -31,7 +31,6 @@
void HWR_Startup(void);
void HWR_Shutdown(void);
-void HWR_clearAutomap(void);
void HWR_drawAMline(const fline_t *fl, INT32 color);
void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength);
void HWR_DrawConsoleBack(UINT32 color, INT32 height);
diff --git a/src/hardware/r_opengl/r_opengl-vc10.vcxproj b/src/hardware/r_opengl/r_opengl-vc10.vcxproj
index f04ae320..d1f856e9 100644
--- a/src/hardware/r_opengl/r_opengl-vc10.vcxproj
+++ b/src/hardware/r_opengl/r_opengl-vc10.vcxproj
@@ -1,6 +1,14 @@
+
+ Debug
+ ARM
+
+
+ Debug
+ ARM64
+
Debug
Win32
@@ -9,6 +17,14 @@
Debug
x64
+
+ Release
+ ARM
+
+
+ Release
+ ARM64
+
Release
Win32
@@ -22,7 +38,7 @@
r_opengl
{51137D5C-4E81-4955-AACF-EA3092006051}
r_opengl
- 8.1
+ 10.0.16299.0
@@ -30,21 +46,45 @@
false
v140
+
+ DynamicLibrary
+ false
+ v141
+ true
+
DynamicLibrary
false
v140
+
+ DynamicLibrary
+ false
+ v141
+ true
+
DynamicLibrary
false
v140
+
+ DynamicLibrary
+ false
+ v141
+ true
+
DynamicLibrary
false
v140
+
+ DynamicLibrary
+ false
+ v141
+ true
+
@@ -52,37 +92,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<_ProjectFileVersion>10.0.30319.1
.\..\..\..\bin\VC10\$(Platform)\$(Configuration)\
+ .\..\..\..\bin\VC10\$(Platform)\$(Configuration)\
.\..\..\..\objs\VC10\$(Platform)\$(Configuration)\r_opengl\
+ .\..\..\..\objs\VC10\$(Platform)\$(Configuration)\r_opengl\
true
+ true
true
+ true
.\..\..\..\bin\VC10\$(Platform)\$(Configuration)\
+ .\..\..\..\bin\VC10\$(Platform)\$(Configuration)\
.\..\..\..\objs\VC10\$(Platform)\$(Configuration)\r_opengl\
+ .\..\..\..\objs\VC10\$(Platform)\$(Configuration)\r_opengl\
true
+ true
true
+ true
.\..\..\..\bin\VC10\$(Platform)\$(Configuration)\
+ .\..\..\..\bin\VC10\$(Platform)\$(Configuration)\
.\..\..\..\objs\VC10\$(Platform)\$(Configuration)\r_opengl\
+ .\..\..\..\objs\VC10\$(Platform)\$(Configuration)\r_opengl\
true
+ true
false
+ false
.\..\..\..\bin\VC10\$(Platform)\$(Configuration)\
+ .\..\..\..\bin\VC10\$(Platform)\$(Configuration)\
.\..\..\..\objs\VC10\$(Platform)\$(Configuration)\r_opengl\
+ .\..\..\..\objs\VC10\$(Platform)\$(Configuration)\r_opengl\
true
+ true
false
+ false
@@ -123,6 +195,49 @@
$(IntDir)r_opengl.lib
MachineX86
Windows
+ gdi32.lib;%(AdditionalDependencies)
+
+
+ true
+ $(OutDir)r_opengl.bsc
+
+
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+ true
+ true
+ .\..\..\..\bin\VC10\$(Platform)\$(Configuration)\r_opengl\r_opengl.tlb
+
+
+
+
+ Disabled
+ _DEBUG;WIN32;_WINDOWS;__WIN32__;__MSC__;USE_WGL_SWAP;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ EnableFastChecks
+ MultiThreadedDebug
+ $(IntDir)
+ $(IntDir)r_opengl.pdb
+ true
+ Level4
+ true
+ ProgramDatabase
+ CompileAsC
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+ 0x0409
+
+
+ $(OutDir)r_opengl.dll
+ true
+ true
+ $(OutDir)r_opengl.pdb
+
+
+ $(IntDir)r_opengl.lib
+ Windows
+ gdi32.lib;%(AdditionalDependencies)
true
@@ -168,6 +283,49 @@
$(IntDir)r_opengl.lib
MachineX64
Windows
+ gdi32.lib;%(AdditionalDependencies)
+
+
+ true
+ $(OutDir)r_opengl.bsc
+
+
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+ true
+ true
+ .\..\..\..\bin\VC10\$(Platform)\$(Configuration)\r_opengl\r_opengl.tlb
+
+
+
+
+ Disabled
+ _DEBUG;WIN32;_WINDOWS;__WIN32__;__MSC__;USE_WGL_SWAP;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ EnableFastChecks
+ MultiThreadedDebug
+ $(IntDir)
+ $(IntDir)r_opengl.pdb
+ true
+ Level4
+ true
+ ProgramDatabase
+ CompileAsC
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+ 0x0409
+
+
+ $(OutDir)r_opengl.dll
+ true
+ true
+ $(OutDir)r_opengl.pdb
+
+
+ $(IntDir)r_opengl.lib
+ Windows
+ gdi32.lib;%(AdditionalDependencies)
true
@@ -215,6 +373,52 @@
$(IntDir)r_opengl.lib
MachineX86
Windows
+ gdi32.lib;%(AdditionalDependencies)
+
+
+ true
+ $(OutDir)r_opengl.bsc
+
+
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+ true
+ true
+ .\..\..\..\bin\VC10\$(Platform)\$(Configuration)\r_opengl\r_opengl.tlb
+
+
+
+
+ /MP %(AdditionalOptions)
+ MaxSpeed
+ OnlyExplicitInline
+ NDEBUG;WIN32;_WINDOWS;__WIN32__;__MSC__;USE_WGL_SWAP;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ true
+ MultiThreaded
+ true
+ $(IntDir)
+ $(IntDir)r_opengl.pdb
+ true
+ Level3
+ true
+ ProgramDatabase
+ CompileAsC
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+ 0x0409
+
+
+ $(OutDir)r_opengl.dll
+ true
+ true
+ $(OutDir)r_opengl.pdb
+
+
+ $(IntDir)r_opengl.lib
+ Windows
+ gdi32.lib;%(AdditionalDependencies)
true
@@ -262,6 +466,52 @@
$(IntDir)r_opengl.lib
MachineX64
Windows
+ gdi32.lib;%(AdditionalDependencies)
+
+
+ true
+ $(OutDir)r_opengl.bsc
+
+
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+ true
+ true
+ .\..\..\..\bin\VC10\$(Platform)\$(Configuration)\r_opengl\r_opengl.tlb
+
+
+
+
+ /MP %(AdditionalOptions)
+ MaxSpeed
+ OnlyExplicitInline
+ NDEBUG;WIN32;_WINDOWS;__WIN32__;__MSC__;USE_WGL_SWAP;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ true
+ MultiThreaded
+ true
+ $(IntDir)
+ $(IntDir)r_opengl.pdb
+ true
+ Level3
+ true
+ ProgramDatabase
+ CompileAsC
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+ 0x0409
+
+
+ $(OutDir)r_opengl.dll
+ true
+ true
+ $(OutDir)r_opengl.pdb
+
+
+ $(IntDir)r_opengl.lib
+ Windows
+ gdi32.lib;%(AdditionalDependencies)
true
@@ -271,15 +521,23 @@
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c
index 91578e7f..84835389 100644
--- a/src/hardware/r_opengl/r_opengl.c
+++ b/src/hardware/r_opengl/r_opengl.c
@@ -602,7 +602,8 @@ static void GLPerspective(GLdouble fovy, GLdouble aspect)
const GLdouble deltaZ = zFar - zNear;
GLdouble cotangent;
- if ((deltaZ == 0.0f) || (sine == 0.0f) || (aspect == 0.0f)) {
+ if ((fabsf((float)deltaZ) < 1.0E-36f) || fpclassify(sine) == FP_ZERO || fpclassify(aspect) == FP_ZERO)
+ {
return;
}
cotangent = cos(radians) / sine;
@@ -641,7 +642,7 @@ static void GLProject(GLdouble objX, GLdouble objY, GLdouble objZ,
out[2] * projMatrix[2*4+i] +
out[3] * projMatrix[3*4+i];
}
- if (in[3] == 0.0f) return;
+ if (fpclassify(in[3]) == FP_ZERO) return;
in[0] /= in[3];
in[1] /= in[3];
in[2] /= in[3];
@@ -1989,7 +1990,7 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration,
pglTexCoord2f(s, t);
- if (!nextframe || pol == 0.0f)
+ if (!nextframe || fpclassify(pol) == FP_ZERO)
{
pglNormal3f(frame->vertices[pindex].normal[0],
frame->vertices[pindex].normal[1],
@@ -2058,6 +2059,7 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform)
pglLoadIdentity();
if (stransform)
{
+ boolean fovx90;
// keep a trace of the transformation for md2
memcpy(&md2_transform, stransform, sizeof (md2_transform));
@@ -2074,7 +2076,8 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform)
pglMatrixMode(GL_PROJECTION);
pglLoadIdentity();
- special_splitscreen = (stransform->splitscreen == 1 && stransform->fovxangle == 90.0f);
+ fovx90 = stransform->fovxangle > 0.0f && fabsf(stransform->fovxangle - 90.0f) < 0.5f;
+ special_splitscreen = (stransform->splitscreen == 1 && fovx90);
if (special_splitscreen)
GLPerspective(53.13l, 2*ASPECT_RATIO); // 53.13 = 2*atan(0.5)
else
diff --git a/src/hardware/s_openal/s_openal-vc10.vcxproj b/src/hardware/s_openal/s_openal-vc10.vcxproj
index 8b4f6cbb..5039cd00 100644
--- a/src/hardware/s_openal/s_openal-vc10.vcxproj
+++ b/src/hardware/s_openal/s_openal-vc10.vcxproj
@@ -1,6 +1,14 @@
+
+ Debug
+ ARM
+
+
+ Debug
+ ARM64
+
Debug
Win32
@@ -9,6 +17,14 @@
Debug
x64
+
+ Release
+ ARM
+
+
+ Release
+ ARM64
+
Release
Win32
@@ -22,7 +38,7 @@
s_openal
{E662D0B3-412D-4D55-A5EC-8CBD680DDCBE}
s_openal
- 8.1
+ 10.0.16299.0
@@ -31,22 +47,44 @@
MultiByte
v140
+
+ DynamicLibrary
+ false
+ MultiByte
+ v141
+
DynamicLibrary
false
v140
+
+ DynamicLibrary
+ false
+ v141
+
DynamicLibrary
false
MultiByte
v140
+
+ DynamicLibrary
+ false
+ MultiByte
+ v141
+
DynamicLibrary
false
v140
+
+ DynamicLibrary
+ false
+ v141
+
@@ -54,37 +92,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<_ProjectFileVersion>10.0.30319.1
.\..\..\..\bin\VC10\$(Platform)\$(Configuration)\
+ .\..\..\..\bin\VC10\$(Platform)\$(Configuration)\
.\..\..\..\objs\VC10\$(Platform)\$(Configuration)\s_openal\
+ .\..\..\..\objs\VC10\$(Platform)\$(Configuration)\s_openal\
true
+ true
false
+ false
.\..\..\..\bin\VC10\$(Platform)\$(Configuration)\
+ .\..\..\..\bin\VC10\$(Platform)\$(Configuration)\
.\..\..\..\objs\VC10\$(Platform)\$(Configuration)\s_openal\
+ .\..\..\..\objs\VC10\$(Platform)\$(Configuration)\s_openal\
true
+ true
false
+ false
.\..\..\..\bin\VC10\$(Platform)\$(Configuration)\
+ .\..\..\..\bin\VC10\$(Platform)\$(Configuration)\
.\..\..\..\objs\VC10\$(Platform)\$(Configuration)\s_openal\
+ .\..\..\..\objs\VC10\$(Platform)\$(Configuration)\s_openal\
true
+ true
true
+ true
.\..\..\..\bin\VC10\$(Platform)\$(Configuration)\
+ .\..\..\..\bin\VC10\$(Platform)\$(Configuration)\
.\..\..\..\objs\VC10\$(Platform)\$(Configuration)\s_openal\
+ .\..\..\..\objs\VC10\$(Platform)\$(Configuration)\s_openal\
true
+ true
true
+ true
@@ -132,6 +202,50 @@
$(OutDir)s_openal.bsc
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+ true
+ .\..\..\..\bin\VC10\$(Platform)\$(Configuration)\s_openal\s_openal.tlb
+
+
+
+
+ /MP %(AdditionalOptions)
+ MaxSpeed
+ OnlyExplicitInline
+ WIN32;NDEBUG;_WINDOWS;__WIN32__;__MSC__;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ true
+ MultiThreaded
+ true
+ $(IntDir)
+ $(IntDir)s_openal.pdb
+ true
+ Level3
+ true
+ CompileAsC
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+ 0x0409
+
+
+ OpenAL32.lib;%(AdditionalDependencies)
+ $(OutDir)s_openal.dll
+ true
+ true
+ $(OutDir)s_openal.pdb
+ false
+
+
+ $(IntDir)s_openal.lib
+ Windows
+
+
+ true
+ $(OutDir)s_openal.bsc
+
+
NDEBUG;%(PreprocessorDefinitions)
@@ -178,6 +292,50 @@
$(OutDir)s_openal.bsc
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+ true
+ .\..\..\..\bin\VC10\$(Platform)\$(Configuration)\s_openal\s_openal.tlb
+
+
+
+
+ /MP %(AdditionalOptions)
+ MaxSpeed
+ OnlyExplicitInline
+ WIN32;NDEBUG;_WINDOWS;__WIN32__;__MSC__;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ true
+ MultiThreaded
+ true
+ $(IntDir)
+ $(IntDir)s_openal.pdb
+ true
+ Level3
+ true
+ CompileAsC
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+ 0x0409
+
+
+ OpenAL32.lib;%(AdditionalDependencies)
+ $(OutDir)s_openal.dll
+ true
+ true
+ $(OutDir)s_openal.pdb
+ false
+
+
+ $(IntDir)s_openal.lib
+ Windows
+
+
+ true
+ $(OutDir)s_openal.bsc
+
+
_DEBUG;%(PreprocessorDefinitions)
@@ -225,6 +383,50 @@
$(OutDir)s_openal.bsc
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+ true
+ true
+ .\..\..\..\bin\VC10\$(Platform)\$(Configuration)\s_openal\s_openal.tlb
+
+
+
+
+ /MP /SAFESEH:OFF %(AdditionalOptions)
+ Disabled
+ WIN32;_DEBUG;_WINDOWS;__WIN32__;__MSC__;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ EnableFastChecks
+ MultiThreadedDebug
+ $(IntDir)
+ $(IntDir)s_openal.pdb
+ true
+ Level4
+ true
+ ProgramDatabase
+ CompileAsC
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+ 0x0409
+
+
+ OpenAL32.lib;%(AdditionalDependencies)
+ $(OutDir)s_openal.dll
+ true
+ true
+ $(OutDir)s_openal.pdb
+ false
+
+
+ $(IntDir)s_openal.lib
+ Windows
+
+
+ true
+ $(OutDir)s_openal.bsc
+
+
_DEBUG;%(PreprocessorDefinitions)
@@ -272,12 +474,60 @@
$(OutDir)s_openal.bsc
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+ true
+ true
+ .\..\..\..\bin\VC10\$(Platform)\$(Configuration)\s_openal\s_openal.tlb
+
+
+
+
+ Disabled
+ WIN32;_DEBUG;_WINDOWS;__WIN32__;__MSC__;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ EnableFastChecks
+ MultiThreadedDebug
+ $(IntDir)
+ $(IntDir)s_openal.pdb
+ true
+ Level4
+ true
+ ProgramDatabase
+ CompileAsC
+ /MP /SAFESEH:OFF %(AdditionalOptions)
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+ 0x0409
+
+
+ OpenAL32.lib;%(AdditionalDependencies)
+ $(OutDir)s_openal.dll
+ true
+ true
+ $(OutDir)s_openal.pdb
+ false
+
+
+ $(IntDir)s_openal.lib
+ Windows
+
+
+ true
+ $(OutDir)s_openal.bsc
+
+
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
%(PreprocessorDefinitions)
+ %(PreprocessorDefinitions)
diff --git a/src/hu_stuff.c b/src/hu_stuff.c
index 9bdf9bd7..6e1ef35e 100644
--- a/src/hu_stuff.c
+++ b/src/hu_stuff.c
@@ -76,7 +76,7 @@ patch_t *cred_font[CRED_FONTSIZE];
static player_t *plr;
boolean chat_on; // entering a chat message?
static char w_chat[HU_MAXMSGLEN];
-static UINT32 c_input = 0; // let's try to make the chat input less shitty.
+static size_t c_input = 0; // let's try to make the chat input less shitty.
static boolean headsupactive = false;
boolean hu_showscores; // draw rankings
static char hu_tick;
@@ -342,30 +342,30 @@ static UINT32 chat_nummsg_min = 0;
static UINT32 chat_scroll = 0;
static tic_t chat_scrolltime = 0;
-static UINT32 chat_maxscroll = 0; // how far can we scroll?
+static UINT32 chat_maxscroll = 0; // how far can we scroll?
-//static chatmsg_t chat_mini[CHAT_BUFSIZE]; // Display the last few messages sent.
-//static chatmsg_t chat_log[CHAT_BUFSIZE]; // Keep every message sent to us in memory so we can scroll n shit, it's cool.
+//static chatmsg_t chat_mini[CHAT_BUFSIZE]; // Display the last few messages sent.
+//static chatmsg_t chat_log[CHAT_BUFSIZE]; // Keep every message sent to us in memory so we can scroll n shit, it's cool.
-static char chat_log[CHAT_BUFSIZE][255]; // hold the last 48 or so messages in that log.
-static char chat_mini[8][255]; // display up to 8 messages that will fade away / get overwritten
+static char chat_log[CHAT_BUFSIZE][255]; // hold the last 48 or so messages in that log.
+static char chat_mini[8][255]; // display up to 8 messages that will fade away / get overwritten
static tic_t chat_timers[8];
-static boolean chat_scrollmedown = false; // force instant scroll down on the chat log. Happens when you open it / send a message.
+static boolean chat_scrollmedown = false; // force instant scroll down on the chat log. Happens when you open it / send a message.
// remove text from minichat table
-static INT16 addy = 0; // use this to make the messages scroll smoothly when one fades away
+static INT16 addy = 0; // use this to make the messages scroll smoothly when one fades away
static void HU_removeChatText_Mini(void)
{
// MPC: Don't create new arrays, just iterate through an existing one
- UINT32 i;
+ size_t i;
for(i=0;i= CHAT_BUFSIZE)
+ if (chat_nummsg_log >= CHAT_BUFSIZE) // too many messages!
HU_removeChatText_Log();
strcpy(chat_log[chat_nummsg_log], text);
@@ -402,12 +404,18 @@ void HU_AddChatText(const char *text, boolean playsound)
chat_timers[chat_nummsg_min] = TICRATE*cv_chattime.value;
chat_nummsg_min++;
- if (OLDCHAT) // if we're using oldchat, print directly in console
+ if (OLDCHAT) // if we're using oldchat, print directly in console
CONS_Printf("%s\n", text);
else // if we aren't, still save the message to log.txt
CON_LogMessage(va("%s\n", text));
+#else
+ (void)playsound;
+ CONS_Printf("%s\n", text);
+#endif
}
+#ifndef NONET
+
/** Runs a say command, sending an ::XD_SAY message.
* A say command consists of a signed 8-bit integer for the target, an
* unsigned 8-bit flag variable, and then the message itself.
@@ -426,6 +434,7 @@ void HU_AddChatText(const char *text, boolean playsound)
* \sa Command_Say_f, Command_Sayteam_f, Command_Sayto_f, Got_Saycmd
* \author Graue
*/
+
static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags)
{
XBOXSTATIC char buf[254];
@@ -436,7 +445,7 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags)
numwords = COM_Argc() - usedargs;
I_Assert(numwords > 0);
- if (CHAT_MUTE) // TODO: Per Player mute.
+ if (CHAT_MUTE) // TODO: Per Player mute.
{
HU_AddChatText(va("%s>ERROR: The chat is muted. You can't say anything.", "\x85"), false);
return;
@@ -462,14 +471,15 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags)
strlcat(msg, COM_Argv(ix + usedargs), msgspace);
}
- if (strlen(msg) > 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm
+ if (strlen(msg) > 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm
{
// what we're gonna do now is check if the node exists
// with that logic, characters 4 and 5 are our numbers:
const char *newmsg;
- int spc = 1; // used if nodenum[1] is a space.
+ INT32 spc = 1; // used if nodenum[1] is a space.
char *nodenum = (char*) malloc(3);
- strncpy(nodenum, msg+3, 5);
+
+ strncpy(nodenum, msg+3, 3);
// check for undesirable characters in our "number"
if (((nodenum[0] < '0') || (nodenum[0] > '9')) || ((nodenum[1] < '0') || (nodenum[1] > '9')))
{
@@ -480,6 +490,7 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags)
else
{
HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm \'.", false);
+ free(nodenum);
return;
}
}
@@ -489,24 +500,26 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags)
if (msg[5] != ' ')
{
HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm \'.", false);
+ free(nodenum);
return;
}
}
- target = atoi((const char*) nodenum); // turn that into a number
+ target = atoi((const char*) nodenum); // turn that into a number
+ free(nodenum);
//CONS_Printf("%d\n", target);
// check for target player, if it doesn't exist then we can't send the message!
- if (playeringame[target]) // player exists
- target++; // even though playernums are from 0 to 31, target is 1 to 32, so up that by 1 to have it work!
+ if (target < MAXPLAYERS && playeringame[target]) // player exists
+ target++; // even though playernums are from 0 to 31, target is 1 to 32, so up that by 1 to have it work!
else
{
- HU_AddChatText(va("\x82NOTICE: \x80Player %d does not exist.", target), false); // same
+ HU_AddChatText(va("\x82NOTICE: \x80Player %d does not exist.", target), false); // same
return;
}
buf[0] = target;
newmsg = msg+5+spc;
- memcpy(msg, newmsg, 252);
+ strlcpy(msg, newmsg, 252);
}
SendNetXCmd(XD_SAY, buf, strlen(msg) + 1 + msg-buf);
@@ -595,7 +608,7 @@ static void Command_CSay_f(void)
DoSayCommand(0, 1, HU_CSAY);
}
-static tic_t stop_spamming_you_cunt[MAXPLAYERS];
+static tic_t stop_spamming[MAXPLAYERS];
/** Receives a message, processing an ::XD_SAY command.
* \sa DoSayCommand
@@ -609,7 +622,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
char *msg;
boolean action = false;
char *ptr;
- int spam_eatmsg = 0;
+ INT32 spam_eatmsg = 0;
CONS_Debug(DBG_NETPLAY,"Received SAY cmd from Player %d (%s)\n", playernum+1, player_names[playernum]);
@@ -658,15 +671,15 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
// before we do anything, let's verify the guy isn't spamming, get this easier on us.
- //if (stop_spamming_you_cunt[playernum] != 0 && cv_chatspamprotection.value && !(flags & HU_CSAY))
- if (stop_spamming_you_cunt[playernum] != 0 && consoleplayer != playernum && cv_chatspamprotection.value && !(flags & HU_CSAY))
+ //if (stop_spamming[playernum] != 0 && cv_chatspamprotection.value && !(flags & HU_CSAY))
+ if (stop_spamming[playernum] != 0 && consoleplayer != playernum && cv_chatspamprotection.value && !(flags & HU_CSAY))
{
CONS_Debug(DBG_NETPLAY,"Received SAY cmd too quickly from Player %d (%s), assuming as spam and blocking message.\n", playernum+1, player_names[playernum]);
- stop_spamming_you_cunt[playernum] = 4;
+ stop_spamming[playernum] = 4;
spam_eatmsg = 1;
}
else
- stop_spamming_you_cunt[playernum] = 4; // you can hold off for 4 tics, can you?
+ stop_spamming[playernum] = 4; // you can hold off for 4 tics, can you?
// run the lua hook even if we were supposed to eat the msg, netgame consistency goes first.
@@ -676,7 +689,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
#endif
if (spam_eatmsg)
- return; // don't proceed if we were supposed to eat the message.
+ return; // don't proceed if we were supposed to eat the message.
// If it's a CSAY, just CECHO and be done with it.
if (flags & HU_CSAY)
@@ -726,7 +739,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
cstart = "\x86"; // grey name
textcolor = "\x86";
}
- else if (target == -1) // say team
+ else if (target == -1) // say team
{
if (players[playernum].ctfteam == 1) // red
{
@@ -742,6 +755,9 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
else
{
const UINT8 color = players[playernum].skincolor;
+
+ cstart = "\x83";
+
if (color <= SKINCOLOR_SILVER || color == SKINCOLOR_SLATE)
cstart = "\x80"; // white
else if (color <= SKINCOLOR_BLACK || color == SKINCOLOR_JET)
@@ -823,9 +839,8 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
else if (players[playernum].ctfteam == 2) // blue
prefix = "\x84[TEAM]";
else
- prefix = "\x83"; // makes sure this doesn't implode if you sayteam on non-team gamemodes
+ prefix = "\x83"; // makes sure this doesn't implode if you sayteam on non-team gamemodes
- fmt = "\3%s<%s%s>\x80%s %s%s\n";
fmt2 = "%s<%s%s>\x80%s %s%s";
}*/
@@ -843,7 +858,6 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
CONS_Printf("Dropped chat: %d %d %s\n", playernum, target, msg);
#endif
}
-#endif
// Handles key input and string input
//
@@ -857,25 +871,24 @@ static inline boolean HU_keyInChatString(char *s, char ch)
l = strlen(s);
if (l < HU_MAXMSGLEN - 1)
{
- if (c_input >= strlen(s)) // don't do anything complicated
+ if (c_input >= strlen(s)) // don't do anything complicated
{
s[l++] = ch;
s[l]=0;
}
else
{
-
// move everything past c_input for new characters:
- UINT32 m = HU_MAXMSGLEN-1;
- for (;(m>=c_input);m--)
+ size_t m = HU_MAXMSGLEN-1;
+ while (m>=c_input)
{
if (s[m])
s[m+1] = (s[m]);
-
- if (m < 1)
- break; // fix the chat going ham if your replace the first character. (For whatever reason this didn't happen in vanilla????)
+ if (m == 0) // prevent overflow
+ break;
+ m--;
}
- s[c_input] = ch; // and replace this.
+ s[c_input] = ch; // and replace this.
}
c_input++;
return true;
@@ -884,10 +897,11 @@ static inline boolean HU_keyInChatString(char *s, char ch)
}
else if (ch == KEY_BACKSPACE)
{
- size_t i;
+ size_t i = c_input;
+
if (c_input <= 0)
return false;
- i = c_input;
+
if (!s[i-1])
return false;
@@ -910,6 +924,8 @@ static inline boolean HU_keyInChatString(char *s, char ch)
return true; // ate the key
}
+#endif
+
//
//
void HU_Ticker(void)
@@ -926,10 +942,34 @@ void HU_Ticker(void)
hu_showscores = false;
}
+#ifndef NONET
static boolean teamtalk = false;
+/*static char chatchars[QUEUESIZE];
+static INT32 head = 0, tail = 0;*/
// WHY DO YOU OVERCOMPLICATE EVERYTHING?????????
+// Clear spaces so we don't end up with messages only made out of emptiness
+static boolean HU_clearChatSpaces(void)
+{
+ size_t i = 0; // Used to just check our message
+ char c; // current character we're iterating.
+ boolean nothingbutspaces = true;
+
+ for (; i < strlen(w_chat); i++) // iterate through message and eradicate all spaces that don't belong.
+ {
+ c = w_chat[i];
+ if (!c)
+ break; // if there's nothing, it's safe to assume our message has ended, so let's not waste any more time here.
+
+ if (c != ' ') // Isn't a space
+ {
+ nothingbutspaces = false;
+ }
+ }
+ return nothingbutspaces;
+}
+
//
//
static void HU_queueChatChar(INT32 c)
@@ -938,10 +978,14 @@ static void HU_queueChatChar(INT32 c)
if (c == KEY_ENTER)
{
char buf[2+256];
- size_t ci = 2;
char *msg = &buf[2];
size_t i;
+ size_t ci = 2;
INT32 target = 0;
+
+ if (HU_clearChatSpaces()) // Avoids being able to send empty messages, or something.
+ return; // If this returns true, that means our message was NOTHING but spaces, so don't send it period.
+
do {
c = w_chat[-2+ci++];
if (!c || (c >= ' ' && !(c & 0x80))) // copy printable characters and terminating '\0' only.
@@ -953,6 +997,11 @@ static void HU_queueChatChar(INT32 c)
c_input = 0;
+ for (;(i 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm
+ if (strlen(msg) > 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm
{
- int spc;
- char *nodenum;
+ INT32 spc = 1; // used if nodenum[1] is a space.
+ char *nodenum = (char*) malloc(3);
const char *newmsg;
+
// what we're gonna do now is check if the node exists
// with that logic, characters 4 and 5 are our numbers:
@@ -975,9 +1025,8 @@ static void HU_queueChatChar(INT32 c)
return;
}
- spc = 1; // used if nodenum[1] is a space.
- nodenum = (char*) malloc(3);
- strncpy(nodenum, msg+3, 5);
+ strncpy(nodenum, msg+3, 3);
+
// check for undesirable characters in our "number"
if (((nodenum[0] < '0') || (nodenum[0] > '9')) || ((nodenum[1] < '0') || (nodenum[1] > '9')))
{
@@ -988,6 +1037,7 @@ static void HU_queueChatChar(INT32 c)
else
{
HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm \'.", false);
+ free(nodenum);
return;
}
}
@@ -997,24 +1047,27 @@ static void HU_queueChatChar(INT32 c)
if (msg[5] != ' ')
{
HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm \'.", false);
+ free(nodenum);
return;
}
}
- target = atoi((const char*) nodenum); // turn that into a number
+ target = atoi((const char*) nodenum); // turn that into a number
+ free(nodenum);
//CONS_Printf("%d\n", target);
// check for target player, if it doesn't exist then we can't send the message!
- if (playeringame[target]) // player exists
- target++; // even though playernums are from 0 to 31, target is 1 to 32, so up that by 1 to have it work!
+ if (target < MAXPLAYERS && playeringame[target]) // player exists
+ target++; // even though playernums are from 0 to 31, target is 1 to 32, so up that by 1 to have it work!
else
{
- HU_AddChatText(va("\x82NOTICE: \x80Player %d does not exist.", target), false); // same
+ HU_AddChatText(va("\x82NOTICE: \x80Player %d does not exist.", target), false); // same
return;
}
+
// we need to get rid of the /pm
newmsg = msg+5+spc;
- memcpy(msg, newmsg, 255);
+ strlcpy(msg, newmsg, 255);
}
if (ci > 3) // don't send target+flags+empty message.
{
@@ -1029,18 +1082,23 @@ static void HU_queueChatChar(INT32 c)
return;
}
}
+#endif
void HU_clearChatChars(void)
{
size_t i = 0;
for (;idata1;
// capslock (now handled outside of chat on so that it works everytime......)
- if (c && c == KEY_CAPSLOCK) // it's a toggle.
+ if (c && c == KEY_CAPSLOCK) // it's a toggle.
{
if (capslock)
capslock = false;
@@ -1086,16 +1144,18 @@ boolean HU_Responder(event_t *ev)
return true;
}
+#ifndef NONET
if (!chat_on)
{
// enter chat mode
if ((ev->data1 == gamecontrol[gc_talkkey][0] || ev->data1 == gamecontrol[gc_talkkey][1])
- && netgame && !OLD_MUTE) // check for old chat mute, still let the players open the chat incase they want to scroll otherwise.
+ && netgame && !OLD_MUTE) // check for old chat mute, still let the players open the chat incase they want to scroll otherwise.
{
chat_on = true;
w_chat[0] = 0;
teamtalk = false;
chat_scrollmedown = true;
+ typelines = 1;
return true;
}
if ((ev->data1 == gamecontrol[gc_teamkey][0] || ev->data1 == gamecontrol[gc_teamkey][1])
@@ -1105,6 +1165,7 @@ boolean HU_Responder(event_t *ev)
w_chat[0] = 0;
teamtalk = G_GametypeHasTeams(); // Don't teamtalk if we don't have teams.
chat_scrollmedown = true;
+ typelines = 1;
return true;
}
}
@@ -1151,27 +1212,29 @@ boolean HU_Responder(event_t *ev)
if (chatlen+pastelen > HU_MAXMSGLEN)
return true; // we can't paste this!!
- if (c_input >= strlen(w_chat)) // add it at the end of the string.
+ if (c_input >= strlen(w_chat)) // add it at the end of the string.
{
- memcpy(&w_chat[chatlen], paste, pastelen); // copy all of that.
+ memcpy(&w_chat[chatlen], paste, pastelen); // copy all of that.
c_input += pastelen;
/*size_t i = 0;
for (;i=c_input;i--)
+ while (i >= c_input)
{
if (w_chat[i])
w_chat[i+pastelen] = w_chat[i];
-
+ if (i == 0) // prevent overflow
+ break;
+ i--;
}
- memcpy(&w_chat[c_input], paste, pastelen); // copy all of that.
+ memcpy(&w_chat[c_input], paste, pastelen); // copy all of that.
c_input += pastelen;
return true;
}
@@ -1184,7 +1247,7 @@ boolean HU_Responder(event_t *ev)
if (c == KEY_ENTER)
{
chat_on = false;
- c_input = 0; // reset input cursor
+ c_input = 0; // reset input cursor
chat_scrollmedown = true; // you hit enter, so you might wanna autoscroll to see what you just sent. :)
}
else if (c == KEY_ESCAPE
@@ -1193,9 +1256,9 @@ boolean HU_Responder(event_t *ev)
&& c >= KEY_MOUSE1)) // If it's not a keyboard key, then the chat button is used as a toggle.
{
chat_on = false;
- c_input = 0; // reset input cursor
+ c_input = 0; // reset input cursor
}
- else if ((c == KEY_UPARROW || c == KEY_MOUSEWHEELUP) && chat_scroll > 0 && !OLDCHAT) // CHAT SCROLLING YAYS!
+ else if ((c == KEY_UPARROW || c == KEY_MOUSEWHEELUP) && chat_scroll > 0 && !OLDCHAT) // CHAT SCROLLING YAYS!
{
chat_scroll--;
justscrolledup = true;
@@ -1207,12 +1270,14 @@ boolean HU_Responder(event_t *ev)
justscrolleddown = true;
chat_scrolltime = 4;
}
- else if (c == KEY_LEFTARROW && c_input != 0 && !OLDCHAT) // i said go back
+ else if (c == KEY_LEFTARROW && c_input != 0 && !OLDCHAT) // i said go back
c_input--;
- else if (c == KEY_RIGHTARROW && c_input < strlen(w_chat) && !OLDCHAT) // don't need to check for admin or w/e here since the chat won't ever contain anything if it's muted.
+ else if (c == KEY_RIGHTARROW && c_input < strlen(w_chat) && !OLDCHAT) // don't need to check for admin or w/e here since the chat won't ever contain anything if it's muted.
c_input++;
return true;
}
+#endif
+
return false;
}
@@ -1220,17 +1285,19 @@ boolean HU_Responder(event_t *ev)
// HEADS UP DRAWING
//======================================================================
+#ifndef NONET
+
// Precompile a wordwrapped string to any given width.
// This is a muuuch better method than V_WORDWRAP.
// again stolen and modified a bit from video.c, don't mind me, will need to rearrange this one day.
// this one is simplified for the chat drawer.
static char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string)
{
- int c;
+ INT32 c;
size_t chw, i, lastusablespace = 0;
size_t slen;
char *newstring = Z_StrDup(string);
- INT32 charwidth = 4;
+ INT32 spacewidth = (vid.width < 640) ? 8 : 4, charwidth = (vid.width < 640) ? 8 : 4;
slen = strlen(string);
x = 0;
@@ -1254,7 +1321,7 @@ static char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string)
if (c < 0 || c >= HU_FONTSIZE || !hu_font[c])
{
- chw = charwidth;
+ chw = spacewidth;
lastusablespace = i;
}
else
@@ -1274,9 +1341,10 @@ static char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string)
return newstring;
}
+
// 30/7/18: chaty is now the distance at which the lowest point of the chat will be drawn if that makes any sense.
-INT16 chatx = 13, chaty = 169; // let's use this as our coordinates, shh
+INT16 chatx = 13, chaty = 169; // let's use this as our coordinates, shh
// chat stuff by VincyTM LOL XD!
@@ -1289,14 +1357,14 @@ static void HU_drawMiniChat(void)
INT32 boxw = cv_chatwidth.value;
INT32 dx = 0, dy = 0;
size_t i = chat_nummsg_min;
- boolean prev_linereturn = false; // a hack to prevent double \n while I have no idea why they happen in the first place.
+ boolean prev_linereturn = false; // a hack to prevent double \n while I have no idea why they happen in the first place.
INT32 msglines = 0;
// process all messages once without rendering anything or doing anything fancy so that we know how many lines each message has...
INT32 y;
if (!chat_nummsg_min)
- return; // needless to say it's useless to do anything if we don't have anything to draw.
+ return; // needless to say it's useless to do anything if we don't have anything to draw.
if (splitscreen > 1)
boxw = max(64, boxw/2);
@@ -1307,11 +1375,11 @@ static void HU_drawMiniChat(void)
size_t j = 0;
INT32 linescount = 0;
- while(msg[j]) // iterate through msg
+ while(msg[j]) // iterate through msg
{
- if (msg[j] < HU_FONTSTART) // don't draw
+ if (msg[j] < HU_FONTSTART) // don't draw
{
- if (msg[j] == '\n') // get back down.
+ if (msg[j] == '\n') // get back down.
{
++j;
if (!prev_linereturn)
@@ -1355,28 +1423,27 @@ static void HU_drawMiniChat(void)
if (splitscreen > 1)
y += 16;
}
- else
- y -= (cv_kartspeedometer.value ? 16 : 0);
+ y -= (cv_kartspeedometer.value ? 16 : 0);
dx = 0;
dy = 0;
i = 0;
prev_linereturn = false;
- for (; i<=(chat_nummsg_min-1); i++) // iterate through our hot messages
+ for (; i<=(chat_nummsg_min-1); i++) // iterate through our hot messages
{
INT32 clrflag = 0;
- INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below...
- INT32 transflag = (timer >= 0 && timer <= 9) ? (timer*V_10TRANS) : 0; // you can make bad jokes out of this one.
+ INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below...
+ INT32 transflag = (timer >= 0 && timer <= 9) ? (timer*V_10TRANS) : 0; // you can make bad jokes out of this one.
size_t j = 0;
- const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it.
+ const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it.
UINT8 *colormap = NULL;
- while(msg[j]) // iterate through msg
+ while(msg[j]) // iterate through msg
{
- if (msg[j] < HU_FONTSTART) // don't draw
+ if (msg[j] < HU_FONTSTART) // don't draw
{
- if (msg[j] == '\n') // get back down.
+ if (msg[j] == '\n') // get back down.
{
++j;
if (!prev_linereturn)
@@ -1399,7 +1466,7 @@ static void HU_drawMiniChat(void)
}
else
{
- if (cv_chatbacktint.value) // on request of wolfy
+ if (cv_chatbacktint.value) // on request of wolfy
V_DrawFillConsoleMap(x + dx + 2, y+dy, charwidth, charheight, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT);
V_DrawChatCharacter(x + dx + 2, y+dy, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag, !cv_allcaps.value, colormap);
@@ -1423,7 +1490,6 @@ static void HU_drawMiniChat(void)
}
// HU_DrawChatLog
-// TODO: fix dumb word wrapping issues
static void HU_drawChatLog(INT32 offset)
{
@@ -1439,15 +1505,18 @@ static void HU_drawChatLog(INT32 offset)
if (chat_scroll > chat_maxscroll)
chat_scroll = chat_maxscroll;
+#ifdef NETSPLITSCREEN
if (splitscreen)
{
boxh = max(6, boxh/2);
if (splitscreen > 1)
boxw = max(64, boxw/2);
}
+#endif
y = chaty - offset*charheight - (chat_scroll*charheight) - boxh*charheight - 12;
+#ifdef NETSPLITSCREEN
if (splitscreen)
{
y -= BASEVIDHEIGHT/2;
@@ -1455,24 +1524,26 @@ static void HU_drawChatLog(INT32 offset)
y += 16;
}
else
+#endif
y -= (cv_kartspeedometer.value ? 16 : 0);
+
chat_topy = y + chat_scroll*charheight;
chat_bottomy = chat_topy + boxh*charheight;
- V_DrawFillConsoleMap(chatx, chat_topy, boxw, boxh*charheight +2, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT); // log box
+ V_DrawFillConsoleMap(chatx, chat_topy, boxw, boxh*charheight +2, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT); // log box
- for (i=0; i= chat_topy) && (y+dy < (chat_bottomy)))
V_DrawChatCharacter(x + dx + 2, y+dy+2, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT, !cv_allcaps.value, colormap);
else
- j++; // don't forget to increment this or we'll get stuck in the limbo.
+ j++; // don't forget to increment this or we'll get stuck in the limbo.
}
dx += charwidth;
@@ -1508,14 +1579,15 @@ static void HU_drawChatLog(INT32 offset)
dx = 0;
}
- if (((chat_scroll >= chat_maxscroll) || (chat_scrollmedown)) && !(justscrolleddown || justscrolledup || chat_scrolltime)) // was already at the bottom of the page before new maxscroll calculation and was NOT scrolling.
+
+ if (((chat_scroll >= chat_maxscroll) || (chat_scrollmedown)) && !(justscrolleddown || justscrolledup || chat_scrolltime)) // was already at the bottom of the page before new maxscroll calculation and was NOT scrolling.
{
- atbottom = true; // we should scroll
+ atbottom = true; // we should scroll
}
chat_scrollmedown = false;
// getmaxscroll through a lazy hack. We do all these loops, so let's not do more loops that are gonna lag the game more. :P
- chat_maxscroll = (dy/charheight); // welcome to C, we don't know what min() and max() are.
+ chat_maxscroll = (dy/charheight); // welcome to C, we don't know what min() and max() are.
if (chat_maxscroll <= (UINT32)boxh)
chat_maxscroll = 0;
else
@@ -1526,17 +1598,10 @@ static void HU_drawChatLog(INT32 offset)
chat_scroll = chat_maxscroll;
// draw arrows to indicate that we can (or not) scroll.
-
if (chat_scroll > 0)
- {
- V_DrawCharacter(chatx-9, ((justscrolledup) ? (chat_topy-1) : (chat_topy)),
- '\x1A' | V_SNAPTOBOTTOM | V_SNAPTOLEFT | highlight, false); // up arrow
- }
+ V_DrawThinString(chatx-9, ((justscrolledup) ? (chat_topy-1) : (chat_topy)), V_SNAPTOBOTTOM | V_SNAPTOLEFT | highlight, "\x1A"); // up arrow
if (chat_scroll < chat_maxscroll)
- {
- V_DrawCharacter(chatx-9, chat_bottomy-((justscrolleddown) ? 5 : 6),
- '\x1B' | V_SNAPTOBOTTOM | V_SNAPTOLEFT | highlight, false); // down arrow
- }
+ V_DrawThinString(chatx-9, chat_bottomy-((justscrolleddown) ? 5 : 6), V_SNAPTOBOTTOM | V_SNAPTOLEFT | highlight, "\x1B"); // down arrow
justscrolleddown = false;
justscrolledup = false;
@@ -1548,18 +1613,18 @@ static void HU_drawChatLog(INT32 offset)
// Draw chat input
//
-static INT16 typelines = 1; // number of drawfill lines we need. it's some weird hack and might be one frame off but I'm lazy to make another loop.
static void HU_DrawChat(void)
{
INT32 charwidth = 4, charheight = 6;
INT32 boxw = cv_chatwidth.value;
INT32 t = 0, c = 0, y = chaty - (typelines*charheight);
- UINT32 i = 0, saylen = strlen(w_chat); // You learn new things everyday!
+ UINT32 i = 0, saylen = strlen(w_chat); // You learn new things everyday!
INT32 cflag = 0;
const char *ntalk = "Say: ", *ttalk = "Team: ";
const char *talk = ntalk;
const char *mute = "Chat has been muted.";
+#ifdef NETSPLITSCREEN
if (splitscreen)
{
y -= BASEVIDHEIGHT/2;
@@ -1570,6 +1635,7 @@ static void HU_DrawChat(void)
}
}
else
+#endif
y -= (cv_kartspeedometer.value ? 16 : 0);
if (teamtalk)
@@ -1587,7 +1653,7 @@ static void HU_DrawChat(void)
{
talk = mute;
typelines = 1;
- cflag = V_GRAYMAP; // set text in gray if chat is muted.
+ cflag = V_GRAYMAP; // set text in gray if chat is muted.
}
V_DrawFillConsoleMap(chatx, y-1, boxw, (typelines*charheight), 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT);
@@ -1605,7 +1671,7 @@ static void HU_DrawChat(void)
c += charwidth;
}
- // if chat is muted, just draw the log and get it over with:
+ // if chat is muted, just draw the log and get it over with, no need to draw anything else.
if (CHAT_MUTE)
{
HU_drawChatLog(0);
@@ -1623,17 +1689,16 @@ static void HU_DrawChat(void)
boolean skippedline = false;
if (c_input == (i+1))
{
- int cursorx = (c+charwidth < boxw-charwidth) ? (chatx + 2 + c+charwidth) : (chatx+1); // we may have to go down.
- int cursory = (cursorx != chatx+1) ? (y) : (y+charheight);
+ INT32 cursorx = (c+charwidth < boxw-charwidth) ? (chatx + 2 + c+charwidth) : (chatx+1); // we may have to go down.
+ INT32 cursory = (cursorx != chatx+1) ? (y) : (y+charheight);
if (hu_tick < 4)
V_DrawChatCharacter(cursorx, cursory+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL);
- if (cursorx == chatx+1 && saylen == i) // a weirdo hack
+ if (cursorx == chatx+1 && saylen == i) // a weirdo hack
{
typelines += 1;
skippedline = true;
}
-
}
//Hurdler: isn't it better like that?
@@ -1651,11 +1716,12 @@ static void HU_DrawChat(void)
}
}
- // handle /pm list.
- if (strnicmp(w_chat, "/pm", 3) == 0 && vid.width >= 400 && !teamtalk) // 320x200 unsupported kthxbai
+ // handle /pm list. It's messy, horrible and I don't care.
+ if (strnicmp(w_chat, "/pm", 3) == 0 && vid.width >= 400 && !teamtalk) // 320x200 unsupported kthxbai
{
INT32 count = 0;
INT32 p_dispy = chaty - charheight -1;
+#ifdef NETSPLITSCREEN
if (splitscreen)
{
p_dispy -= BASEVIDHEIGHT/2;
@@ -1663,7 +1729,9 @@ static void HU_DrawChat(void)
p_dispy += 16;
}
else
+#endif
p_dispy -= (cv_kartspeedometer.value ? 16 : 0);
+
i = 0;
for(i=0; (i 0)
- stop_spamming_you_cunt[i]--;
+ if (stop_spamming[i] > 0)
+ stop_spamming[i]--;
}
// handle chat timers
@@ -2096,6 +2164,7 @@ void HU_Drawer(void)
HU_removeChatText_Mini();
}
}
+#endif
if (cechotimer)
HU_DrawCEcho();
@@ -2197,9 +2266,9 @@ void HU_Erase(void)
// clear the message lines that go away, so use _oldclearlines_
bottomline = oldclearlines;
oldclearlines = con_clearlines;
- if (chat_on)
+ if (chat_on && OLDCHAT)
if (bottomline < 8)
- bottomline = 8;
+ bottomline = 8; // only do it for consolechat. consolechat is gay.
if (automapactive || viewwindowx == 0) // hud msgs don't need to be cleared
return;
@@ -2240,11 +2309,12 @@ void HU_Erase(void)
//
void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext)
{
- UINT8 numbars = 1; // how many ping bars do we draw?
- UINT8 barcolor = 128; // color we use for the bars (green, yellow or red)
+ UINT8 numbars = 1; // how many ping bars do we draw?
+ UINT8 barcolor = 128; // color we use for the bars (green, yellow or red)
SINT8 i = 0;
SINT8 yoffset = 6;
- INT32 dx;
+ INT32 dx = x+1 - (V_SmallStringWidth(va("%dms", ping), V_ALLOWLOWERCASE)/2);
+
if (ping < 128)
{
numbars = 3;
@@ -2252,15 +2322,14 @@ void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext)
}
else if (ping < 256)
{
- numbars = 2; // Apparently ternaries w/ multiple statements don't look good in C so I decided against it.
+ numbars = 2; // Apparently ternaries w/ multiple statements don't look good in C so I decided against it.
barcolor = 103;
}
- dx = x+1 - (V_SmallStringWidth(va("%dms", ping), V_ALLOWLOWERCASE)/2);
- if (!notext || vid.width >= 640) // how sad, we're using a shit resolution.
+ if (!notext || vid.width >= 640) // how sad, we're using a shit resolution.
V_DrawSmallString(dx, y+4, V_ALLOWLOWERCASE, va("%dms", ping));
- for (i=0; (i<3); i++) // Draw the ping bar
+ for (i=0; (i<3); i++) // Draw the ping bar
{
V_DrawFill(x+2 *(i-1), y+yoffset-4, 2, 8-yoffset, 31);
if (i < numbars)
@@ -2281,13 +2350,50 @@ void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext)
{
INT32 i,x,y;
INT32 redplayers = 0, blueplayers = 0;
+ boolean smol = false;
const UINT8 *colormap;
char name[MAXPLAYERNAME+1];
+ // before we draw, we must count how many players are in each team. It makes an additional loop, but we need to know if we have to draw a big or a small ranking.
+ for (i = 0; i < MAXPLAYERS; i++)
+ {
+ if (players[tab[i].num].spectator)
+ continue; //ignore them.
+
+ if (tab[i].color == skincolor_redteam) //red
+ {
+ if (redplayers++ > 8)
+ {
+ smol = true;
+ break; // don't make more loops than we need to.
+ }
+ }
+ else if (tab[i].color == skincolor_blueteam) //blue
+ {
+ if (blueplayers++ > 8)
+ {
+ smol = true;
+ break;
+ }
+ }
+ else //er? not on red or blue, so ignore them
+ continue;
+
+ }
+
+ // I'll be blunt with you, this may add more lines, but I'm not adding weird cases for this, so we're executing a separate function.
+ if (smol == true || cv_compactscoreboard.value)
+ {
+ HU_Draw32TeamTabRankings(tab, whiteplayer);
+ return;
+ }
+
V_DrawFill(160, 26, 1, 154, 0); //Draw a vertical line to separate the two teams.
V_DrawFill(1, 26, 318, 1, 0); //And a horizontal line to make a T.
V_DrawFill(1, 180, 318, 1, 0); //And a horizontal line near the bottom.
+ i=0, redplayers=0, blueplayers=0;
+
for (i = 0; i < MAXPLAYERS; i++)
{
if (players[tab[i].num].spectator)
@@ -2310,7 +2416,7 @@ void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext)
else //er? not on red or blue, so ignore them
continue;
- strlcpy(name, tab[i].name, 9);
+ strlcpy(name, tab[i].name, 7);
V_DrawString(x + 20, y,
((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0)
| ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT)
@@ -2350,6 +2456,14 @@ void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext)
if (!(tab[i].num == serverplayer))
HU_drawPing(x+ 113, y+2, playerpingtable[tab[i].num], false);
}
+ V_DrawRightAlignedThinString(x+100, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count));
+ if (!splitscreen)
+ {
+ if (!(tab[i].num == serverplayer))
+ HU_drawPing(x+ 113, y+2, playerpingtable[tab[i].num], false);
+ //else
+ // V_DrawSmallString(x+ 94, y+4, V_YELLOWMAP, "SERVER");
+ }
}
}
@@ -2371,9 +2485,12 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline
if (players[tab[i].num].spectator)
continue; //ignore them.
- strlcpy(name, tab[i].name, 9);
+ strlcpy(name, tab[i].name, 7);
if (!(tab[i].num == serverplayer))
HU_drawPing(x+ 113, y+2, playerpingtable[tab[i].num], false);
+ //else
+ // V_DrawSmallString(x+ 94, y+4, V_YELLOWMAP, "SERVER");
+
V_DrawString(x + 20, y,
((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0)
| ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT)
@@ -2428,15 +2545,15 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline
if (circuitmap)
{
if (players[tab[i].num].exiting)
- V_DrawRightAlignedThinString(x+156, y-1, 0, va("%i:%02i.%02i", G_TicsToMinutes(players[tab[i].num].realtime,true), G_TicsToSeconds(players[tab[i].num].realtime), G_TicsToCentiseconds(players[tab[i].num].realtime)));
+ V_DrawRightAlignedThinString(x+146, y, 0, va("%i:%02i.%02i", G_TicsToMinutes(players[tab[i].num].realtime,true), G_TicsToSeconds(players[tab[i].num].realtime), G_TicsToCentiseconds(players[tab[i].num].realtime)));
else
- V_DrawRightAlignedThinString(x+156, y-1, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count));
+ V_DrawRightAlignedThinString(x+146, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count));
}
else
- V_DrawRightAlignedThinString(x+156, y-1, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count)));
+ V_DrawRightAlignedThinString(x+146, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count)));
}
else
- V_DrawRightAlignedThinString(x+120, y-1, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count));
+ V_DrawRightAlignedThinString(x+100, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count));
y += 16;
if (y > 160)
@@ -2445,7 +2562,108 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline
x += BASEVIDWIDTH/2;
}
}
-}*/
+}
+
+//
+// HU_Draw32TabRankings
+//
+static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer)
+{
+ INT32 i;
+ const UINT8 *colormap;
+ char name[MAXPLAYERNAME+1];
+
+ V_DrawFill(160, 26, 1, 154, 0); //Draw a vertical line to separate the two sides.
+ V_DrawFill(1, 26, 318, 1, 0); //And a horizontal line to make a T.
+ V_DrawFill(1, 180, 318, 1, 0); //And a horizontal line near the bottom.
+
+ for (i = 0; i < scorelines; i++)
+ {
+ if (players[tab[i].num].spectator)
+ continue; //ignore them.
+
+ strlcpy(name, tab[i].name, 7);
+ if (!splitscreen) // don't draw it on splitscreen,
+ {
+ if (!(tab[i].num == serverplayer))
+ HU_drawPing(x+ 135, y+3, playerpingtable[tab[i].num], true);
+ //else
+ // V_DrawSmallString(x+ 129, y+4, V_YELLOWMAP, "HOST");
+ }
+
+ V_DrawString(x + 10, y,
+ ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0)
+ | ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT)
+ | V_ALLOWLOWERCASE, name);
+
+ if (G_GametypeUsesLives()) //show lives
+ V_DrawRightAlignedThinString(x-1, y, V_ALLOWLOWERCASE, va("%d", players[tab[i].num].lives));
+ else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT)
+ V_DrawFixedPatch((x-10)*FRACUNIT, (y)*FRACUNIT, FRACUNIT/4, 0, tagico, 0);
+
+ // Draw emeralds
+ if (!players[tab[i].num].powers[pw_super]
+ || ((leveltime/7) & 1))
+ {
+ HU_Draw32Emeralds(x+60, y+2, tab[i].emeralds);
+ //HU_DrawEmeralds(x-12,y+2,tab[i].emeralds);
+ }
+
+ //V_DrawSmallScaledPatch (x, y-4, 0, livesback);
+ if (tab[i].color == 0)
+ {
+ colormap = colormaps;
+ if (players[tab[i].num].powers[pw_super])
+ V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT/4, 0, superprefix[players[tab[i].num].skin], 0);
+ else
+ {
+ if (players[tab[i].num].health <= 0)
+ V_DrawFixedPatch(x*FRACUNIT, (y)*FRACUNIT, FRACUNIT/4, V_HUDTRANSHALF, faceprefix[players[tab[i].num].skin], 0);
+ else
+ V_DrawFixedPatch(x*FRACUNIT, (y)*FRACUNIT, FRACUNIT/4, 0, faceprefix[players[tab[i].num].skin], 0);
+ }
+ }
+ else
+ {
+ if (players[tab[i].num].powers[pw_super])
+ {
+ colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE);
+ V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT/4, 0, superprefix[players[tab[i].num].skin], colormap);
+ }
+ else
+ {
+ colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE);
+ if (players[tab[i].num].health <= 0)
+ V_DrawFixedPatch(x*FRACUNIT, (y)*FRACUNIT, FRACUNIT/4, V_HUDTRANSHALF, faceprefix[players[tab[i].num].skin], colormap);
+ else
+ V_DrawFixedPatch(x*FRACUNIT, (y)*FRACUNIT, FRACUNIT/4, 0, faceprefix[players[tab[i].num].skin], colormap);
+ }
+ }
+
+ // All data drawn with thin string for space.
+ if (gametype == GT_RACE)
+ {
+ if (circuitmap)
+ {
+ if (players[tab[i].num].exiting)
+ V_DrawRightAlignedThinString(x+128, y, 0, va("%i:%02i.%02i", G_TicsToMinutes(players[tab[i].num].realtime,true), G_TicsToSeconds(players[tab[i].num].realtime), G_TicsToCentiseconds(players[tab[i].num].realtime)));
+ else
+ V_DrawRightAlignedThinString(x+128, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count));
+ }
+ else
+ V_DrawRightAlignedThinString(x+128, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count)));
+ }
+ else
+ V_DrawRightAlignedThinString(x+128, y, ((players[tab[i].num].health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count));
+
+ y += 9;
+ if (i == 16)
+ {
+ y = 32;
+ x += BASEVIDWIDTH/2;
+ }
+ }
+}
//
// HU_DrawEmeralds
@@ -2473,7 +2691,7 @@ void HU_DrawEmeralds(INT32 x, INT32 y, INT32 pemeralds)
if (pemeralds & EMERALD7)
V_DrawSmallScaledPatch(x, y, 0, tinyemeraldpics[6]);
-}
+}*/
//
// HU_DrawSpectatorTicker
diff --git a/src/hu_stuff.h b/src/hu_stuff.h
index ecfdb041..0ca871f0 100644
--- a/src/hu_stuff.h
+++ b/src/hu_stuff.h
@@ -21,7 +21,7 @@
//------------------------------------
// heads up font
//------------------------------------
-#define HU_FONTSTART '\x19' // the first font character
+#define HU_FONTSTART '\x16' // the first font character
#define HU_FONTEND '~'
#define HU_FONTSIZE (HU_FONTEND - HU_FONTSTART + 1)
@@ -62,6 +62,20 @@ typedef struct
// chat stuff
//------------------------------------
#define HU_MAXMSGLEN 224
+#define CHAT_BUFSIZE 64 // that's enough messages, right? We'll delete the older ones when that gets out of hand.
+#ifdef NETSPLITSCREEN
+#define OLDCHAT (cv_consolechat.value == 1 || dedicated || vid.width < 640)
+#else
+#define OLDCHAT (cv_consolechat.value == 1 || dedicated || vid.width < 640 || splitscreen)
+#endif
+#define CHAT_MUTE (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer))) // this still allows to open the chat but not to type. That's used for scrolling and whatnot.
+#define OLD_MUTE (OLDCHAT && cv_mute.value && !(server || IsPlayerAdmin(consoleplayer))) // this is used to prevent oldchat from opening when muted.
+
+// some functions
+void HU_AddChatText(const char *text, boolean playsound);
+
+// set true when entering a chat message
+extern boolean chat_on;
extern patch_t *hu_font[HU_FONTSIZE], *kart_font[KART_FONTSIZE], *tny_font[HU_FONTSIZE]; // SRB2kart
extern patch_t *tallnum[10];
@@ -77,18 +91,6 @@ extern patch_t *bmatcico;
extern patch_t *tagico;
extern patch_t *tallminus;
-#define CHAT_BUFSIZE 64 // that's enough messages, right? We'll delete the older ones when that gets out of hand.
-
-#define OLDCHAT (cv_consolechat.value == 1 || dedicated || vid.width < 640)
-#define CHAT_MUTE (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer))) // this still allows to open the chat but not to type. That's used for scrolling and whatnot.
-#define OLD_MUTE (OLDCHAT && cv_mute.value && !(server || IsPlayerAdmin(consoleplayer))) // this is used to prevent oldchat from opening when muted.
-
-// some functions
-void HU_AddChatText(const char *text, boolean playsound);
-
-// set true when entering a chat message
-extern boolean chat_on;
-
// set true whenever the tab rankings are being shown for any reason
extern boolean hu_showscores;
@@ -101,18 +103,15 @@ void HU_LoadGraphics(void);
void HU_Start(void);
boolean HU_Responder(event_t *ev);
-
void HU_Ticker(void);
void HU_Drawer(void);
char HU_dequeueChatChar(void);
void HU_Erase(void);
void HU_clearChatChars(void);
void HU_drawPing(INT32 x, INT32 y, INT32 ping, boolean notext); // Lat': Ping drawer for scoreboard.
-void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer);
-void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer);
-void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer, INT32 hilicol);
//void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer);
//void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer);
+void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer, INT32 hilicol);
void HU_DrawEmeralds(INT32 x, INT32 y, INT32 pemeralds);
INT32 HU_CreateTeamScoresTbl(playersort_t *tab, UINT32 dmtotals[]);
diff --git a/src/i_tcp.c b/src/i_tcp.c
index 739355cc..f8a65b75 100644
--- a/src/i_tcp.c
+++ b/src/i_tcp.c
@@ -1310,7 +1310,7 @@ void I_ShutdownTcpDriver(void)
static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
{
SINT8 newnode = -1;
- struct my_addrinfo *ai, *runp, hints;
+ struct my_addrinfo *ai = NULL, *runp, hints;
int gaie;
if (!port || !port[0])
diff --git a/src/k_kart.c b/src/k_kart.c
index 2a152162..44c490ed 100644
--- a/src/k_kart.c
+++ b/src/k_kart.c
@@ -648,7 +648,7 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed)
{
secondist = P_AproxDistance(P_AproxDistance(players[first].mo->x - players[second].mo->x,
players[first].mo->y - players[second].mo->y),
- players[first].mo->z - players[second].mo->z) / mapheaderinfo[gamemap-1]->mobj_scale;
+ players[first].mo->z - players[second].mo->z) / mapobjectscale;
if (franticitems)
secondist = (15*secondist/14);
if (pingame < 8 && !G_BattleGametype())
@@ -809,7 +809,7 @@ static INT32 K_FindUseodds(player_t *player, fixed_t mashed, INT32 pingame, INT3
&& players[i].kartstuff[k_position] < player->kartstuff[k_position])
pdis += P_AproxDistance(P_AproxDistance(players[i].mo->x - player->mo->x,
players[i].mo->y - player->mo->y),
- players[i].mo->z - player->mo->z) / mapheaderinfo[gamemap-1]->mobj_scale
+ players[i].mo->z - player->mo->z) / mapobjectscale
* (pingame - players[i].kartstuff[k_position])
/ max(1, ((pingame - 1) * (pingame + 1) / 3));
}
@@ -1121,13 +1121,13 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid)
momdify = mobj1->momy - mobj2->momy;
// if the speed difference is less than this let's assume they're going proportionately faster from each other
- if (P_AproxDistance(momdifx, momdify) < (25*mapheaderinfo[gamemap-1]->mobj_scale))
+ if (P_AproxDistance(momdifx, momdify) < (25*mapobjectscale))
{
fixed_t momdiflength = P_AproxDistance(momdifx, momdify);
fixed_t normalisedx = FixedDiv(momdifx, momdiflength);
fixed_t normalisedy = FixedDiv(momdify, momdiflength);
- momdifx = FixedMul((25*mapheaderinfo[gamemap-1]->mobj_scale), normalisedx);
- momdify = FixedMul((25*mapheaderinfo[gamemap-1]->mobj_scale), normalisedy);
+ momdifx = FixedMul((25*mapobjectscale), normalisedx);
+ momdify = FixedMul((25*mapobjectscale), normalisedy);
}
// Adds the OTHER player's momentum, so that it reduces the chance of you being "inside" the other object
@@ -1433,10 +1433,10 @@ void K_RespawnChecker(player_t *player)
{
if (player->kartstuff[k_growshrinktimer] < 0)
{
- player->mo->scalespeed = mapheaderinfo[gamemap-1]->mobj_scale/TICRATE;
- player->mo->destscale = 6*(mapheaderinfo[gamemap-1]->mobj_scale)/8;
+ player->mo->scalespeed = mapobjectscale/TICRATE;
+ player->mo->destscale = (6*mapobjectscale)/8;
if (cv_kartdebugshrink.value && !modeattacking && !player->bot)
- player->mo->destscale = 6*player->mo->destscale/8;
+ player->mo->destscale = (6*player->mo->destscale)/8;
}
if (!P_IsObjectOnGround(player->mo) && !mapreset)
@@ -1728,7 +1728,7 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower)
fixed_t finalspeed;
if (doboostpower && !player->kartstuff[k_pogospring] && !P_IsObjectOnGround(player->mo))
- return (75*mapheaderinfo[gamemap-1]->mobj_scale); // air speed cap
+ return (75*mapobjectscale); // air speed cap
switch (gamespeed)
{
@@ -1793,7 +1793,7 @@ fixed_t K_3dKartMovement(player_t *player, boolean onground, fixed_t forwardmove
if (player->kartstuff[k_pogospring]) // Pogo Spring minimum/maximum thrust
{
- const fixed_t hscale = mapheaderinfo[gamemap-1]->mobj_scale /*+ (mapheaderinfo[gamemap-1]->mobj_scale - player->mo->scale)*/;
+ const fixed_t hscale = mapobjectscale /*+ (mapobjectscale - player->mo->scale)*/;
const fixed_t minspeed = 24*hscale;
const fixed_t maxspeed = 28*hscale;
@@ -1994,10 +1994,10 @@ static void K_RemoveGrowShrink(player_t *player)
player->kartstuff[k_growshrinktimer] = 0;
if (player->kartstuff[k_invincibilitytimer] == 0)
player->mo->color = player->skincolor;
- player->mo->scalespeed = mapheaderinfo[gamemap-1]->mobj_scale/TICRATE;
- player->mo->destscale = mapheaderinfo[gamemap-1]->mobj_scale;
+ player->mo->scalespeed = mapobjectscale/TICRATE;
+ player->mo->destscale = mapobjectscale;
if (cv_kartdebugshrink.value && !modeattacking && !player->bot)
- player->mo->destscale = 6*player->mo->destscale/8;
+ player->mo->destscale = (6*player->mo->destscale)/8;
P_RestoreMusic(player);
}
@@ -2161,7 +2161,7 @@ void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor) // A b
if (source && source != player->mo && source->player)
K_PlayHitEmSound(source);
- player->mo->momz = 18*(mapheaderinfo[gamemap-1]->mobj_scale);
+ player->mo->momz = 18*mapobjectscale;
player->mo->momx = player->mo->momy = 0;
player->kartstuff[k_sneakertimer] = 0;
@@ -2813,7 +2813,7 @@ void K_DriftDustHandling(mobj_t *spawner)
{
if (spawner->player->pflags & PF_SKIDDOWN)
{
- anglediff = abs(spawner->angle - spawner->player->frameangle);
+ anglediff = abs((signed)(spawner->angle - spawner->player->frameangle));
if (leveltime % 6 == 0)
S_StartSound(spawner, sfx_screec); // repeated here because it doesn't always happen to be within the range when this is the case
}
@@ -2827,7 +2827,7 @@ void K_DriftDustHandling(mobj_t *spawner)
if (spawner->player->cmd.forwardmove < 0)
playerangle += ANGLE_180;
- anglediff = abs(playerangle - R_PointToAngle2(0, 0, spawner->player->rmomx, spawner->player->rmomy));
+ anglediff = abs((signed)(playerangle - R_PointToAngle2(0, 0, spawner->player->rmomx, spawner->player->rmomy)));
}
}
else
@@ -2835,7 +2835,7 @@ void K_DriftDustHandling(mobj_t *spawner)
if (P_AproxDistance(spawner->momx, spawner->momy) < 5<angle - R_PointToAngle2(0, 0, spawner->momx, spawner->momy));
+ anglediff = abs((signed)(spawner->angle - R_PointToAngle2(0, 0, spawner->momx, spawner->momy)));
}
if (anglediff > ANGLE_180)
@@ -2899,20 +2899,20 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map
PROJSPEED = FixedMul(PROJSPEED, FRACUNIT-FRACUNIT/4);
else if (gamespeed == 2)
PROJSPEED = FixedMul(PROJSPEED, FRACUNIT+FRACUNIT/4);
- PROJSPEED = FixedMul(PROJSPEED, mapheaderinfo[gamemap-1]->mobj_scale);
+ PROJSPEED = FixedMul(PROJSPEED, mapobjectscale);
}
else
{
switch (gamespeed)
{
case 0:
- PROJSPEED = 68*(mapheaderinfo[gamemap-1]->mobj_scale); // Avg Speed is 34
+ PROJSPEED = 68*mapobjectscale; // Avg Speed is 34
break;
case 2:
- PROJSPEED = 96*(mapheaderinfo[gamemap-1]->mobj_scale); // Avg Speed is 48
+ PROJSPEED = 96*mapobjectscale; // Avg Speed is 48
break;
default:
- PROJSPEED = 82*(mapheaderinfo[gamemap-1]->mobj_scale); // Avg Speed is 41
+ PROJSPEED = 82*mapobjectscale; // Avg Speed is 41
break;
}
}
@@ -3000,7 +3000,7 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map
if (mo)
{
angle_t fa = player->mo->angle>>ANGLETOFINESHIFT;
- INT32 HEIGHT = (20 + (dir*10))*(mapheaderinfo[gamemap-1]->mobj_scale) + player->mo->momz;
+ INT32 HEIGHT = (20 + (dir*10))*mapobjectscale + player->mo->momz;
mo->momx = player->mo->momx + FixedMul(FINECOSINE(fa), (altthrow == 2 ? 2*PROJSPEED/3 : PROJSPEED));
mo->momy = player->mo->momy + FixedMul(FINESINE(fa), (altthrow == 2 ? 2*PROJSPEED/3 : PROJSPEED));
@@ -3290,10 +3290,10 @@ static void K_DoShrink(player_t *user)
{
// Start shrinking!
K_DropItems(&players[i]);
- players[i].mo->scalespeed = mapheaderinfo[gamemap-1]->mobj_scale/TICRATE;
- players[i].mo->destscale = 6*(mapheaderinfo[gamemap-1]->mobj_scale)/8;
+ players[i].mo->scalespeed = mapobjectscale/TICRATE;
+ players[i].mo->destscale = (6*mapobjectscale)/8;
if (cv_kartdebugshrink.value && !modeattacking && !players[i].bot)
- players[i].mo->destscale = 6*players[i].mo->destscale/8;
+ players[i].mo->destscale = (6*players[i].mo->destscale)/8;
players[i].kartstuff[k_growshrinktimer] = -(200+(40*(MAXPLAYERS-players[i].kartstuff[k_position])));
}
@@ -3310,7 +3310,7 @@ static void K_DoShrink(player_t *user)
void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound)
{
- const fixed_t vscale = mapheaderinfo[gamemap-1]->mobj_scale + (mo->scale - mapheaderinfo[gamemap-1]->mobj_scale);
+ const fixed_t vscale = mapobjectscale + (mo->scale - mapobjectscale);
if (mo->player && mo->player->spectator)
return;
@@ -3508,8 +3508,8 @@ void K_DropHnextList(player_t *player)
dropwork->z += flip;
dropwork->momx = player->mo->momx>>1;
dropwork->momy = player->mo->momy>>1;
- dropwork->momz = 3*flip*mapheaderinfo[gamemap-1]->mobj_scale;
- P_Thrust(dropwork, work->angle - ANGLE_90, 6*(mapheaderinfo[gamemap-1]->mobj_scale));
+ dropwork->momz = 3*flip*mapobjectscale;
+ P_Thrust(dropwork, work->angle - ANGLE_90, 6*mapobjectscale);
dropwork->movecount = 2;
dropwork->movedir = work->angle - ANGLE_90;
P_SetMobjState(dropwork, dropwork->info->deathstate);
@@ -3565,8 +3565,8 @@ void K_DropItems(player_t *player)
drop->angle = player->mo->angle + ANGLE_90;
P_Thrust(drop,
FixedAngle(P_RandomFixed()*180) + player->mo->angle + ANGLE_90,
- 16*(mapheaderinfo[gamemap-1]->mobj_scale));
- drop->momz = P_MobjFlip(player->mo)*3*(mapheaderinfo[gamemap-1]->mobj_scale);
+ 16*mapobjectscale);
+ drop->momz = P_MobjFlip(player->mo)*3*mapobjectscale;
drop->threshold = (thunderhack ? KITEM_THUNDERSHIELD : player->kartstuff[k_itemtype]);
drop->movecount = player->kartstuff[k_itemamount];
@@ -4023,7 +4023,7 @@ static void K_UpdateEngineSounds(player_t *player, ticcmd_t *cmd)
if ((leveltime >= starttime-(2*TICRATE) && leveltime <= starttime) || (player->kartstuff[k_respawn] == 1)) // Startup boosts
targetsnd = ((cmd->buttons & BT_ACCELERATE) ? 12 : 0);
else
- targetsnd = (((6*cmd->forwardmove)/25) + ((player->speed / mapheaderinfo[gamemap-1]->mobj_scale)/5))/2;
+ targetsnd = (((6*cmd->forwardmove)/25) + ((player->speed / mapobjectscale)/5))/2;
if (targetsnd < 0)
targetsnd = 0;
@@ -4060,7 +4060,7 @@ static void K_UpdateEngineSounds(player_t *player, ticcmd_t *cmd)
dist = P_AproxDistance(P_AproxDistance(player->mo->x-players[i].mo->x,
player->mo->y-players[i].mo->y), player->mo->z-players[i].mo->z) / 2;
- dist = FixedDiv(dist, mapheaderinfo[gamemap-1]->mobj_scale);
+ dist = FixedDiv(dist, mapobjectscale);
if (dist > 1536<y - players[i].mo->y),
mo->z - players[i].mo->z) / FRACUNIT;
- if (mo->health == player->starpostnum)
+ if (mo->health == player->starpostnum && (!mo->movecount || mo->movecount == player->laps+1))
{
player->kartstuff[k_prevcheck] += pmo;
ppcd++;
}
- if (mo->health == (player->starpostnum + 1))
+ if (mo->health == (player->starpostnum + 1) && (!mo->movecount || mo->movecount == player->laps+1))
{
player->kartstuff[k_nextcheck] += pmo;
pncd++;
}
- if (mo->health == players[i].starpostnum)
+ if (mo->health == players[i].starpostnum && (!mo->movecount || mo->movecount == players[i].laps+1))
{
players[i].kartstuff[k_prevcheck] += imo;
ipcd++;
}
- if (mo->health == (players[i].starpostnum + 1))
+ if (mo->health == (players[i].starpostnum + 1) && (!mo->movecount || mo->movecount == players[i].laps+1))
{
players[i].kartstuff[k_nextcheck] += imo;
incd++;
@@ -5248,10 +5248,10 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
&& player->kartstuff[k_growshrinktimer] <= 0) // Grow holds the item box hostage
{
K_PlayPowerGloatSound(player->mo);
- player->mo->scalespeed = mapheaderinfo[gamemap-1]->mobj_scale/TICRATE;
- player->mo->destscale = 3*(mapheaderinfo[gamemap-1]->mobj_scale)/2;
+ player->mo->scalespeed = mapobjectscale/TICRATE;
+ player->mo->destscale = (3*mapobjectscale)/2;
if (cv_kartdebugshrink.value && !modeattacking && !player->bot)
- player->mo->destscale = 6*player->mo->destscale/8;
+ player->mo->destscale = (6*player->mo->destscale)/8;
player->kartstuff[k_growshrinktimer] = itemtime+(4*TICRATE); // 12 seconds
P_RestoreMusic(player);
if (!P_IsLocalPlayer(player))
@@ -5495,10 +5495,10 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
// Increase your size while charging your engine.
if (leveltime < starttime+10)
{
- player->mo->scalespeed = mapheaderinfo[gamemap-1]->mobj_scale/12;
- player->mo->destscale = (mapheaderinfo[gamemap-1]->mobj_scale) + (player->kartstuff[k_boostcharge]*131);
+ player->mo->scalespeed = mapobjectscale/12;
+ player->mo->destscale = mapobjectscale + (player->kartstuff[k_boostcharge]*131);
if (cv_kartdebugshrink.value && !modeattacking && !player->bot)
- player->mo->destscale = 6*player->mo->destscale/8;
+ player->mo->destscale = (6*player->mo->destscale)/8;
}
// Determine the outcome of your charge.
@@ -7083,17 +7083,17 @@ static void K_drawKartSpeedometer(void)
if (cv_kartspeedometer.value == 1) // Kilometers
{
- convSpeed = FixedDiv(FixedMul(stplyr->speed, 142371), mapheaderinfo[gamemap-1]->mobj_scale)/FRACUNIT; // 2.172409058
+ convSpeed = FixedDiv(FixedMul(stplyr->speed, 142371), mapobjectscale)/FRACUNIT; // 2.172409058
V_DrawKartString(SPDM_X, SPDM_Y, V_HUDTRANS|splitflags, va("%3d km/h", convSpeed));
}
else if (cv_kartspeedometer.value == 2) // Miles
{
- convSpeed = FixedDiv(FixedMul(stplyr->speed, 88465), mapheaderinfo[gamemap-1]->mobj_scale)/FRACUNIT; // 1.349868774
+ convSpeed = FixedDiv(FixedMul(stplyr->speed, 88465), mapobjectscale)/FRACUNIT; // 1.349868774
V_DrawKartString(SPDM_X, SPDM_Y, V_HUDTRANS|splitflags, va("%3d mph", convSpeed));
}
else if (cv_kartspeedometer.value == 3) // Fracunits
{
- convSpeed = FixedDiv(stplyr->speed, mapheaderinfo[gamemap-1]->mobj_scale)/FRACUNIT;
+ convSpeed = FixedDiv(stplyr->speed, mapobjectscale)/FRACUNIT;
V_DrawKartString(SPDM_X, SPDM_Y, V_HUDTRANS|splitflags, va("%3d fu/t", convSpeed));
}
}
@@ -7916,7 +7916,7 @@ static void K_drawLapStartAnim(void)
{
V_DrawFixedPatch((BASEVIDWIDTH/2 + (32*max(0, stplyr->kartstuff[k_lapanimation]-76)))*FRACUNIT,
(48 - (32*max(0, progress-76))
- + 4 - abs((leveltime % 8) - 4))*FRACUNIT,
+ + 4 - abs((signed)((leveltime % 8) - 4)))*FRACUNIT,
FRACUNIT, V_SNAPTOTOP|V_HUDTRANS,
kp_lapanim_hand[stplyr->kartstuff[k_laphand]-1], NULL);
}
diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 4d630d9e..6f542fae 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -23,7 +23,7 @@
#include "m_random.h"
#include "s_sound.h"
#include "g_game.h"
-#include "hu_stuff.h"
+#include "hu_stuff.h" // HU_AddChatText
#include "console.h"
#include "k_kart.h" // SRB2Kart
#include "d_netcmd.h" // IsPlayerAdmin
@@ -96,16 +96,16 @@ static int lib_print(lua_State *L)
static int lib_chatprint(lua_State *L)
{
const char *str = luaL_checkstring(L, 1); // retrieve string
- boolean sound = luaL_checkboolean(L, 2); // retrieve sound boolean
- int len;
+ boolean sound = lua_optboolean(L, 2); // retrieve sound boolean
+ int len = strlen(str);
+
if (str == NULL) // error if we don't have a string!
return luaL_error(L, LUA_QL("tostring") " must return a string to " LUA_QL("chatprint"));
- len = strlen(str);
+
if (len > 255) // string is too long!!!
return luaL_error(L, "String exceeds the 255 characters limit of the chat buffer.");
HU_AddChatText(str, sound);
-
return 0;
}
@@ -113,10 +113,11 @@ static int lib_chatprint(lua_State *L)
static int lib_chatprintf(lua_State *L)
{
int n = lua_gettop(L); /* number of arguments */
+ const char *str = luaL_checkstring(L, 2); // retrieve string
+ boolean sound = lua_optboolean(L, 3); // sound?
+ int len = strlen(str);
player_t *plr;
- const char *str;
- boolean sound = luaL_checkboolean(L, 3);
- int len;
+
if (n < 2)
return luaL_error(L, "chatprintf requires at least two arguments: player and text.");
@@ -126,15 +127,13 @@ static int lib_chatprintf(lua_State *L)
if (plr != &players[consoleplayer])
return 0;
- str = luaL_checkstring(L, 2); // retrieve string
if (str == NULL) // error if we don't have a string!
return luaL_error(L, LUA_QL("tostring") " must return a string to " LUA_QL("chatprintf"));
- len = strlen(str);
+
if (len > 255) // string is too long!!!
return luaL_error(L, "String exceeds the 255 characters limit of the chat buffer.");
HU_AddChatText(str, sound);
-
return 0;
}
@@ -1767,7 +1766,7 @@ static int lib_sStartSound(lua_State *L)
const void *origin = NULL;
sfxenum_t sound_id = luaL_checkinteger(L, 2);
player_t *player = NULL;
- NOHUD
+ //NOHUD // kys @whoever did this.
if (sound_id >= NUMSFX)
return luaL_error(L, "sfx %d out of range (0 - %d)", sound_id, NUMSFX-1);
if (!lua_isnil(L, 1))
@@ -1783,7 +1782,12 @@ static int lib_sStartSound(lua_State *L)
return LUA_ErrInvalid(L, "player_t");
}
if (!player || P_IsLocalPlayer(player))
+ {
+ if (hud_running)
+ origin = NULL; // HUD rendering startsound shouldn't have an origin, just remove it instead of having a retarded error.
+
S_StartSound(origin, sound_id);
+ }
return 0;
}
@@ -1985,28 +1989,45 @@ static int lib_gDoReborn(lua_State *L)
return 0;
}
-static int lib_gExitLevel(lua_State *L)
+// Another Lua function that doesn't actually exist!
+// Sets nextmapoverride & skipstats without instantly ending the level, for instances where other sources should be exiting the level, like normal signposts.
+static int lib_gSetCustomExitVars(lua_State *L)
{
int n = lua_gettop(L); // Num arguments
NOHUD
// LUA EXTENSION: Custom exit like support
// Supported:
- // G_ExitLevel(); [no modifications]
- // G_ExitLevel(int) [nextmap override only]
- // G_ExitLevel(bool) [skipstats only]
- // G_ExitLevel(int, bool) [both of the above]
+ // G_SetCustomExitVars(); [reset to defaults]
+ // G_SetCustomExitVars(int) [nextmap override only]
+ // G_SetCustomExitVars(bool) [skipstats only]
+ // G_SetCustomExitVars(int, bool) [both of the above]
if (n >= 1)
{
if (lua_isnumber(L, 1) || n >= 2)
{
nextmapoverride = (INT16)luaL_checknumber(L, 1);
- lua_pop(L, 1); // pop nextmapoverride; skipstats now 1 if available
+ lua_remove(L, 1); // remove nextmapoverride; skipstats now 1 if available
}
skipstats = lua_optboolean(L, 1);
}
+ else
+ {
+ nextmapoverride = 0;
+ skipstats = false;
+ }
// ---
+ return 0;
+}
+
+static int lib_gExitLevel(lua_State *L)
+{
+ int n = lua_gettop(L); // Num arguments
+ NOHUD
+ // Moved this bit to G_SetCustomExitVars
+ if (n >= 1) // Don't run the reset to defaults option
+ lib_gSetCustomExitVars(L);
G_ExitLevel();
return 0;
}
@@ -2655,6 +2676,7 @@ static luaL_Reg lib[] = {
// g_game
{"G_BuildMapName",lib_gBuildMapName},
{"G_DoReborn",lib_gDoReborn},
+ {"G_SetCustomExitVars",lib_gSetCustomExitVars},
{"G_ExitLevel",lib_gExitLevel},
{"G_IsSpecialStage",lib_gIsSpecialStage},
{"G_GametypeUsesLives",lib_gGametypeUsesLives},
diff --git a/src/lua_maplib.c b/src/lua_maplib.c
index 4dbdcf20..7599b261 100644
--- a/src/lua_maplib.c
+++ b/src/lua_maplib.c
@@ -1090,6 +1090,7 @@ static int ffloor_get(lua_State *L)
{
ffloor_t *ffloor = *((ffloor_t **)luaL_checkudata(L, 1, META_FFLOOR));
enum ffloor_e field = luaL_checkoption(L, 2, ffloor_opt[0], ffloor_opt);
+ INT16 i;
if (!ffloor)
{
@@ -1109,11 +1110,11 @@ static int ffloor_get(lua_State *L)
lua_pushfixed(L, *ffloor->topheight);
return 1;
case ffloor_toppic: { // toppic
- levelflat_t *levelflat;
- INT16 i;
- for (i = 0, levelflat = levelflats; i != *ffloor->toppic; i++, levelflat++)
- ;
- lua_pushlstring(L, levelflat->name, 8);
+ levelflat_t *levelflat = &levelflats[*ffloor->toppic];
+ for (i = 0; i < 8; i++)
+ if (!levelflat->name[i])
+ break;
+ lua_pushlstring(L, levelflat->name, i);
return 1;
}
case ffloor_toplightlevel:
@@ -1123,11 +1124,11 @@ static int ffloor_get(lua_State *L)
lua_pushfixed(L, *ffloor->bottomheight);
return 1;
case ffloor_bottompic: { // bottompic
- levelflat_t *levelflat;
- INT16 i;
- for (i = 0, levelflat = levelflats; i != *ffloor->bottompic; i++, levelflat++)
- ;
- lua_pushlstring(L, levelflat->name, 8);
+ levelflat_t *levelflat = &levelflats[*ffloor->bottompic];
+ for (i = 0; i < 8; i++)
+ if (!levelflat->name[i])
+ break;
+ lua_pushlstring(L, levelflat->name, i);
return 1;
}
#ifdef ESLOPE
@@ -1506,6 +1507,8 @@ static int mapheaderinfo_get(lua_State *L)
lua_pushinteger(L, header->levelselect);
else if (fastcmp(field,"bonustype"))
lua_pushinteger(L, header->bonustype);
+ else if (fastcmp(field,"saveoverride"))
+ lua_pushinteger(L, header->saveoverride);
else if (fastcmp(field,"levelflags"))
lua_pushinteger(L, header->levelflags);
else if (fastcmp(field,"menuflags"))
diff --git a/src/m_menu.c b/src/m_menu.c
index a925e95a..d8b59676 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -67,6 +67,13 @@
// And just some randomness for the exits.
#include "m_random.h"
+#if defined(HAVE_SDL)
+#include "SDL.h"
+#if SDL_VERSION_ATLEAST(2,0,0)
+#include "sdl/sdlmain.h" // JOYSTICK_HOTPLUG
+#endif
+#endif
+
#ifdef PC_DOS
#include // for snprintf
int snprintf(char *str, size_t n, const char *fmt, ...);
@@ -541,26 +548,26 @@ typedef enum
// ---------------------
static menuitem_t MPauseMenu[] =
{
- {IT_STRING | IT_CALL, NULL, "Add-ons...", M_Addons, 8},
- {IT_STRING | IT_SUBMENU, NULL, "Scramble Teams...", &MISC_ScrambleTeamDef, 16},
- {IT_STRING | IT_CALL, NULL, "Switch Map..." , M_MapChange, 24},
+ {IT_STRING | IT_CALL, NULL, "Add-ons...", M_Addons, 8},
+ {IT_STRING | IT_SUBMENU, NULL, "Scramble Teams...", &MISC_ScrambleTeamDef, 16},
+ {IT_STRING | IT_CALL, NULL, "Switch Map..." , M_MapChange, 24},
- {IT_CALL | IT_STRING, NULL, "Continue", M_SelectableClearMenus,40},
- {IT_CALL | IT_STRING, NULL, "P1 Setup...", M_SetupMultiPlayer, 48}, // splitscreen
- {IT_CALL | IT_STRING, NULL, "P2 Setup...", M_SetupMultiPlayer2, 56}, // splitscreen
- {IT_CALL | IT_STRING, NULL, "P3 Setup...", M_SetupMultiPlayer3, 64}, // splitscreen
- {IT_CALL | IT_STRING, NULL, "P4 Setup...", M_SetupMultiPlayer4, 72}, // splitscreen
+ {IT_CALL | IT_STRING, NULL, "Continue", M_SelectableClearMenus, 40},
+ {IT_CALL | IT_STRING, NULL, "P1 Setup...", M_SetupMultiPlayer, 48}, // splitscreen
+ {IT_CALL | IT_STRING, NULL, "P2 Setup...", M_SetupMultiPlayer2, 56}, // splitscreen
+ {IT_CALL | IT_STRING, NULL, "P3 Setup...", M_SetupMultiPlayer3, 64}, // splitscreen
+ {IT_CALL | IT_STRING, NULL, "P4 Setup...", M_SetupMultiPlayer4, 72}, // splitscreen
- {IT_STRING | IT_CALL, NULL, "Spectate", M_ConfirmSpectate, 48}, // alone
- {IT_STRING | IT_CALL, NULL, "Enter Game", M_ConfirmEnterGame, 48}, // alone
- {IT_STRING | IT_CALL, NULL, "Cancel Join", M_ConfirmSpectate, 48}, // alone
- {IT_STRING | IT_SUBMENU, NULL, "Switch Team...", &MISC_ChangeTeamDef, 48},
- {IT_STRING | IT_SUBMENU, NULL, "Enter/Spectate...", &MISC_ChangeSpectateDef,48},
- {IT_CALL | IT_STRING, NULL, "Player Setup...", M_SetupMultiPlayer, 56}, // alone
- {IT_CALL | IT_STRING, NULL, "Options", M_Options, 64},
+ {IT_STRING | IT_CALL, NULL, "Spectate", M_ConfirmSpectate, 48}, // alone
+ {IT_STRING | IT_CALL, NULL, "Enter Game", M_ConfirmEnterGame, 48}, // alone
+ {IT_STRING | IT_CALL, NULL, "Cancel Join", M_ConfirmSpectate, 48}, // alone
+ {IT_STRING | IT_SUBMENU, NULL, "Switch Team...", &MISC_ChangeTeamDef, 48},
+ {IT_STRING | IT_SUBMENU, NULL, "Enter/Spectate...", &MISC_ChangeSpectateDef,48},
+ {IT_CALL | IT_STRING, NULL, "Player Setup...", M_SetupMultiPlayer, 56}, // alone
+ {IT_CALL | IT_STRING, NULL, "Options", M_Options, 64},
- {IT_CALL | IT_STRING, NULL, "Return to Title", M_EndGame, 80},
- {IT_CALL | IT_STRING, NULL, "Quit Game", M_QuitSRB2, 88},
+ {IT_CALL | IT_STRING, NULL, "Return to Title", M_EndGame, 80},
+ {IT_CALL | IT_STRING, NULL, "Quit Game", M_QuitSRB2, 88},
};
typedef enum
@@ -1343,7 +1350,7 @@ static menuitem_t OP_SoundOptionsMenu[] =
{IT_STRING|IT_CVAR, NULL, "Reverse L/R Channels", &stereoreverse, 50},
{IT_STRING|IT_CVAR, NULL, "Surround Sound", &surround, 60},
- {IT_STRING|IT_CVAR, NULL, "Chat sounds", &cv_chatnotifications, 75},
+ {IT_STRING|IT_CVAR, NULL, "Chat Notifications", &cv_chatnotifications, 75},
{IT_STRING|IT_CVAR, NULL, "Character voices", &cv_kartvoices, 85},
{IT_STRING|IT_CVAR, NULL, "Powerup Warning", &cv_kartinvinsfx, 95},
@@ -1439,13 +1446,16 @@ static menuitem_t OP_HUDOptionsMenu[] =
static menuitem_t OP_ChatOptionsMenu[] =
{
// will ANYONE who doesn't know how to use the console want to touch this one?
- {IT_STRING | IT_CVAR, NULL, "Chat mode", &cv_consolechat, 10}, // nonetheless...
+ {IT_STRING | IT_CVAR, NULL, "Chat Mode", &cv_consolechat, 10}, // nonetheless...
+
{IT_STRING | IT_CVAR | IT_CV_SLIDER,
- NULL, "Window width", &cv_chatwidth, 25},
+ NULL, "Chat Box Width", &cv_chatwidth, 25},
{IT_STRING | IT_CVAR | IT_CV_SLIDER,
- NULL, "Window height", &cv_chatheight, 35},
- {IT_STRING | IT_CVAR, NULL, "Message fadeout time", &cv_chattime, 50},
- {IT_STRING | IT_CVAR, NULL, "Show tint behind messages",&cv_chatbacktint, 60},
+ NULL, "Chat Box Height", &cv_chatheight, 35},
+
+ {IT_STRING | IT_CVAR, NULL, "Chat Background Tint", &cv_chatbacktint, 50},
+ {IT_STRING | IT_CVAR, NULL, "Message Fadeout Time", &cv_chattime, 60},
+ {IT_STRING | IT_CVAR, NULL, "Spam Protection", &cv_chatspamprotection, 70},
};
static menuitem_t OP_GameOptionsMenu[] =
@@ -1459,12 +1469,12 @@ static menuitem_t OP_GameOptionsMenu[] =
{IT_STRING | IT_CVAR, NULL, "Number of Laps", &cv_basenumlaps, 70},
{IT_STRING | IT_CVAR, NULL, "Exit Countdown Timer", &cv_countdowntime, 80},
- //{IT_STRING | IT_CVAR, NULL, "Time Limit", &cv_timelimit, 100},
- {IT_STRING | IT_CVAR, NULL, "Starting Bumpers", &cv_kartbumpers, 100},
- {IT_STRING | IT_CVAR, NULL, "Karma Comeback", &cv_kartcomeback, 110},
+ {IT_STRING | IT_CVAR, NULL, "Time Limit", &cv_timelimit, 100},
+ {IT_STRING | IT_CVAR, NULL, "Starting Bumpers", &cv_kartbumpers, 110},
+ {IT_STRING | IT_CVAR, NULL, "Karma Comeback", &cv_kartcomeback, 120},
- {IT_STRING | IT_CVAR, NULL, "Force Character #", &cv_forceskin, 130},
- {IT_STRING | IT_CVAR, NULL, "Restrict Character Changes", &cv_restrictskinchange, 140},
+ {IT_STRING | IT_CVAR, NULL, "Force Character", &cv_forceskin, 140},
+ {IT_STRING | IT_CVAR, NULL, "Restrict Character Changes", &cv_restrictskinchange, 150},
};
static menuitem_t OP_ServerOptionsMenu[] =
@@ -2000,6 +2010,7 @@ menu_t OP_AdvServerOptionsDef = DEFAULTMENUSTYLE("M_SERVER", OP_AdvServerOptions
//menu_t OP_NetgameOptionsDef = DEFAULTMENUSTYLE("M_SERVER", OP_NetgameOptionsMenu, &OP_ServerOptionsDef, 30, 30);
//menu_t OP_GametypeOptionsDef = DEFAULTMENUSTYLE("M_SERVER", OP_GametypeOptionsMenu, &OP_ServerOptionsDef, 30, 30);
+//menu_t OP_ChatOptionsDef = DEFAULTMENUSTYLE("M_GAME", OP_ChatOptionsMenu, &OP_GameOptionsDef, 30, 30);
menu_t OP_MonitorToggleDef =
{
"M_GAME",
@@ -2461,44 +2472,42 @@ boolean M_Responder(event_t *ev)
// (but still allow shift keyup so caps doesn't get stuck)
return false;
}
+ else if (ev->type == ev_keydown)
+ {
+ ch = ev->data1;
+
+ // added 5-2-98 remap virtual keys (mouse & joystick buttons)
+ switch (ch)
+ {
+ case KEY_MOUSE1:
+ //case KEY_JOY1:
+ //case KEY_JOY1 + 2:
+ ch = KEY_ENTER;
+ break;
+ /*case KEY_JOY1 + 3: // Brake can function as 'n' for message boxes now.
+ ch = 'n';
+ break;*/
+ case KEY_MOUSE1 + 1:
+ //case KEY_JOY1 + 1:
+ ch = KEY_BACKSPACE;
+ break;
+ case KEY_HAT1:
+ ch = KEY_UPARROW;
+ break;
+ case KEY_HAT1 + 1:
+ ch = KEY_DOWNARROW;
+ break;
+ case KEY_HAT1 + 2:
+ ch = KEY_LEFTARROW;
+ break;
+ case KEY_HAT1 + 3:
+ ch = KEY_RIGHTARROW;
+ break;
+ }
+ }
else if (menuactive)
{
- if (ev->type == ev_keydown)
- {
- ch = ev->data1;
-
- // added 5-2-98 remap virtual keys (mouse & joystick buttons)
- switch (ch)
- {
- case KEY_MOUSE1:
- case KEY_JOY1:
- ch = KEY_ENTER;
- break;
- case KEY_JOY1 + 3:
- ch = 'n';
- break;
- case KEY_MOUSE1 + 1:
- case KEY_JOY1 + 1:
- ch = KEY_ESCAPE;
- break;
- case KEY_JOY1 + 2:
- ch = KEY_BACKSPACE;
- break;
- case KEY_HAT1:
- ch = KEY_UPARROW;
- break;
- case KEY_HAT1 + 1:
- ch = KEY_DOWNARROW;
- break;
- case KEY_HAT1 + 2:
- ch = KEY_LEFTARROW;
- break;
- case KEY_HAT1 + 3:
- ch = KEY_RIGHTARROW;
- break;
- }
- }
- else if (ev->type == ev_joystick && ev->data1 == 0 && joywait < I_GetTime())
+ if (ev->type == ev_joystick && ev->data1 == 0 && joywait < I_GetTime())
{
const INT32 jdeadzone = JOYAXISRANGE/4;
if (ev->data3 != INT32_MAX)
@@ -2579,6 +2588,8 @@ boolean M_Responder(event_t *ev)
return false;
else if (ch == gamecontrol[gc_systemmenu][0] || ch == gamecontrol[gc_systemmenu][1]) // allow remappable ESC key
ch = KEY_ESCAPE;
+ else if (ch == gamecontrol[gc_accelerate][0] || ch == gamecontrol[gc_accelerate][1])
+ ch = KEY_ENTER;
// F-Keys
if (!menuactive)
@@ -2655,6 +2666,9 @@ boolean M_Responder(event_t *ev)
return false;
}
+ if (ch == gamecontrol[gc_brake][0] || ch == gamecontrol[gc_brake][1]) // do this here, otherwise brake opens the menu mid-game
+ ch = KEY_ESCAPE;
+
routine = currentMenu->menuitems[itemOn].itemaction;
// Handle menuitems which need a specific key handling
@@ -2789,6 +2803,7 @@ boolean M_Responder(event_t *ev)
return true;
case KEY_ESCAPE:
+ //case KEY_JOY1 + 2:
noFurtherInput = true;
currentMenu->lastOn = itemOn;
if (currentMenu->prevMenu)
@@ -4451,7 +4466,9 @@ static void M_Addons(INT32 choice)
addonsp[EXT_TXT] = W_CachePatchName("M_FTXT", PU_STATIC);
addonsp[EXT_CFG] = W_CachePatchName("M_FCFG", PU_STATIC);
addonsp[EXT_WAD] = W_CachePatchName("M_FWAD", PU_STATIC);
+#ifdef USE_KART
addonsp[EXT_KART] = W_CachePatchName("M_FKART", PU_STATIC);
+#endif
addonsp[EXT_PK3] = W_CachePatchName("M_FPK3", PU_STATIC);
addonsp[EXT_SOC] = W_CachePatchName("M_FSOC", PU_STATIC);
addonsp[EXT_LUA] = W_CachePatchName("M_FLUA", PU_STATIC);
@@ -4584,10 +4601,6 @@ static boolean M_AddonsRefresh(void)
return false;
}
-#ifdef FIXUPO0
-#pragma GCC optimize ("0")
-#endif
-
static void M_DrawAddons(void)
{
INT32 x, y;
@@ -4658,16 +4671,14 @@ static void M_DrawAddons(void)
if (m > (ssize_t)sizedirmenu)
m = sizedirmenu;
- // then top...
- i = m - (2*numaddonsshown + 1);
-
- // then adjust!
- if (i < 0)
+ // then compute top and adjust bottom if needed!
+ if (m < (2*numaddonsshown + 1))
{
- if ((m -= i) > (ssize_t)sizedirmenu)
- m = sizedirmenu;
+ m = min(sizedirmenu, 2*numaddonsshown + 1);
i = 0;
}
+ else
+ i = m - (2*numaddonsshown + 1);
if (i != 0)
V_DrawString(19, y+4 - (skullAnimCounter/5), highlightflags, "\x1A");
@@ -4732,10 +4743,6 @@ static void M_DrawAddons(void)
V_DrawSmallScaledPatch(x, y + 4, 0, addonsp[NUM_EXT+2]);
}
-#ifdef FIXUPO0
-#pragma GCC reset_options
-#endif
-
static void M_AddonExec(INT32 ch)
{
if (ch != 'y' && ch != KEY_ENTER)
@@ -4891,13 +4898,15 @@ static void M_HandleAddons(INT32 choice)
case EXT_LUA:
#ifndef HAVE_BLUA
S_StartSound(NULL, sfx_s26d);
- M_StartMessage(va("%c%s\x80\nThis copy of SRB2Kart was compiled\nwithout support for .lua files.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), dirmenu[dir_on[menudepthleft]]+DIR_STRING),NULL,MM_NOTHING);
+ M_StartMessage(va("%c%s\x80\nThis version of SRB2Kart does not\nhave support for .lua files.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), dirmenu[dir_on[menudepthleft]]+DIR_STRING),NULL,MM_NOTHING);
break;
#endif
// else intentional fallthrough
case EXT_SOC:
case EXT_WAD:
+#ifdef USE_KART
case EXT_KART:
+#endif
case EXT_PK3:
COM_BufAddText(va("addfile \"%s%s\"", menupath, dirmenu[dir_on[menudepthleft]]+DIR_STRING));
break;
@@ -8566,7 +8575,7 @@ static void M_ScreenshotOptions(INT32 choice)
static void M_DrawJoystick(void)
{
- INT32 i;
+ INT32 i, compareval4, compareval3, compareval2, compareval;
M_DrawGenericMenu();
@@ -8575,17 +8584,44 @@ static void M_DrawJoystick(void)
M_DrawTextBox(OP_JoystickSetDef.x-8, OP_JoystickSetDef.y+LINEHEIGHT*i-12, 28, 1);
//M_DrawSaveLoadBorder(OP_JoystickSetDef.x, OP_JoystickSetDef.y+LINEHEIGHT*i);
- if ((setupcontrolplayer == 4 && (i == cv_usejoystick4.value))
- || (setupcontrolplayer == 3 && (i == cv_usejoystick3.value))
- || (setupcontrolplayer == 2 && (i == cv_usejoystick2.value))
- || (setupcontrolplayer == 1 && (i == cv_usejoystick.value)))
- V_DrawString(OP_JoystickSetDef.x, OP_JoystickSetDef.y+LINEHEIGHT*i-4,recommendedflags,joystickInfo[i]);
+#ifdef JOYSTICK_HOTPLUG
+ if (atoi(cv_usejoystick4.string) > I_NumJoys())
+ compareval4 = atoi(cv_usejoystick4.string);
+ else
+ compareval4 = cv_usejoystick4.value;
+
+ if (atoi(cv_usejoystick3.string) > I_NumJoys())
+ compareval3 = atoi(cv_usejoystick3.string);
+ else
+ compareval3 = cv_usejoystick3.value;
+
+ if (atoi(cv_usejoystick2.string) > I_NumJoys())
+ compareval2 = atoi(cv_usejoystick2.string);
+ else
+ compareval2 = cv_usejoystick2.value;
+
+ if (atoi(cv_usejoystick.string) > I_NumJoys())
+ compareval = atoi(cv_usejoystick.string);
+ else
+ compareval = cv_usejoystick.value;
+#else
+ compareval4 = cv_usejoystick4.value;
+ compareval3 = cv_usejoystick3.value;
+ compareval2 = cv_usejoystick2.value;
+ compareval = cv_usejoystick.value
+#endif
+
+ if ((setupcontrolplayer == 4 && (i == compareval4))
+ || (setupcontrolplayer == 3 && (i == compareval3))
+ || (setupcontrolplayer == 2 && (i == compareval2))
+ || (setupcontrolplayer == 1 && (i == compareval)))
+ V_DrawString(OP_JoystickSetDef.x, OP_JoystickSetDef.y+LINEHEIGHT*i-4,V_GREENMAP,joystickInfo[i]);
else
V_DrawString(OP_JoystickSetDef.x, OP_JoystickSetDef.y+LINEHEIGHT*i-4,0,joystickInfo[i]);
}
}
-static void M_SetupJoystickMenu(INT32 choice)
+void M_SetupJoystickMenu(INT32 choice)
{
INT32 i = 0;
const char *joyNA = "Unavailable";
@@ -8600,6 +8636,25 @@ static void M_SetupJoystickMenu(INT32 choice)
strncpy(joystickInfo[i], I_GetJoyName(i), 28);
else
strcpy(joystickInfo[i], joyNA);
+
+#ifdef JOYSTICK_HOTPLUG
+ // We use cv_usejoystick.string as the USER-SET var
+ // and cv_usejoystick.value as the INTERNAL var
+ //
+ // In practice, if cv_usejoystick.string == 0, this overrides
+ // cv_usejoystick.value and always disables
+ //
+ // Update cv_usejoystick.string here so that the user can
+ // properly change this value.
+ if (i == cv_usejoystick.value)
+ CV_SetValue(&cv_usejoystick, i);
+ if (i == cv_usejoystick2.value)
+ CV_SetValue(&cv_usejoystick2, i);
+ if (i == cv_usejoystick3.value)
+ CV_SetValue(&cv_usejoystick3, i);
+ if (i == cv_usejoystick4.value)
+ CV_SetValue(&cv_usejoystick4, i);
+#endif
}
M_SetupNextMenu(&OP_JoystickSetDef);
@@ -8628,21 +8683,147 @@ static void M_Setup3PJoystickMenu(INT32 choice)
static void M_Setup4PJoystickMenu(INT32 choice)
{
- setupcontrolplayer = 3;
+ setupcontrolplayer = 4;
OP_JoystickSetDef.prevMenu = &OP_Joystick4Def;
M_SetupJoystickMenu(choice);
}
static void M_AssignJoystick(INT32 choice)
{
+#ifdef JOYSTICK_HOTPLUG
+ INT32 oldchoice, oldstringchoice;
+ INT32 numjoys = I_NumJoys();
+
+ if (setupcontrolplayer == 4)
+ {
+ oldchoice = oldstringchoice = atoi(cv_usejoystick4.string) > numjoys ? atoi(cv_usejoystick4.string) : cv_usejoystick4.value;
+ CV_SetValue(&cv_usejoystick4, choice);
+
+ // Just in case last-minute changes were made to cv_usejoystick.value,
+ // update the string too
+ // But don't do this if we're intentionally setting higher than numjoys
+ if (choice <= numjoys)
+ {
+ CV_SetValue(&cv_usejoystick4, cv_usejoystick4.value);
+
+ // reset this so the comparison is valid
+ if (oldchoice > numjoys)
+ oldchoice = cv_usejoystick4.value;
+
+ if (oldchoice != choice)
+ {
+ if (choice && oldstringchoice > numjoys) // if we did not select "None", we likely selected a used device
+ CV_SetValue(&cv_usejoystick4, (oldstringchoice > numjoys ? oldstringchoice : oldchoice));
+
+ if (oldstringchoice ==
+ (atoi(cv_usejoystick4.string) > numjoys ? atoi(cv_usejoystick4.string) : cv_usejoystick4.value))
+ M_StartMessage("This joystick is used by another\n"
+ "player. Reset the joystick\n"
+ "for that player first.\n\n"
+ "(Press a key)\n", NULL, MM_NOTHING);
+ }
+ }
+ }
+ else if (setupcontrolplayer == 3)
+ {
+ oldchoice = oldstringchoice = atoi(cv_usejoystick3.string) > numjoys ? atoi(cv_usejoystick3.string) : cv_usejoystick3.value;
+ CV_SetValue(&cv_usejoystick3, choice);
+
+ // Just in case last-minute changes were made to cv_usejoystick.value,
+ // update the string too
+ // But don't do this if we're intentionally setting higher than numjoys
+ if (choice <= numjoys)
+ {
+ CV_SetValue(&cv_usejoystick3, cv_usejoystick3.value);
+
+ // reset this so the comparison is valid
+ if (oldchoice > numjoys)
+ oldchoice = cv_usejoystick3.value;
+
+ if (oldchoice != choice)
+ {
+ if (choice && oldstringchoice > numjoys) // if we did not select "None", we likely selected a used device
+ CV_SetValue(&cv_usejoystick3, (oldstringchoice > numjoys ? oldstringchoice : oldchoice));
+
+ if (oldstringchoice ==
+ (atoi(cv_usejoystick3.string) > numjoys ? atoi(cv_usejoystick3.string) : cv_usejoystick3.value))
+ M_StartMessage("This joystick is used by another\n"
+ "player. Reset the joystick\n"
+ "for that player first.\n\n"
+ "(Press a key)\n", NULL, MM_NOTHING);
+ }
+ }
+ }
+ else if (setupcontrolplayer == 2)
+ {
+ oldchoice = oldstringchoice = atoi(cv_usejoystick2.string) > numjoys ? atoi(cv_usejoystick2.string) : cv_usejoystick2.value;
+ CV_SetValue(&cv_usejoystick2, choice);
+
+ // Just in case last-minute changes were made to cv_usejoystick.value,
+ // update the string too
+ // But don't do this if we're intentionally setting higher than numjoys
+ if (choice <= numjoys)
+ {
+ CV_SetValue(&cv_usejoystick2, cv_usejoystick2.value);
+
+ // reset this so the comparison is valid
+ if (oldchoice > numjoys)
+ oldchoice = cv_usejoystick2.value;
+
+ if (oldchoice != choice)
+ {
+ if (choice && oldstringchoice > numjoys) // if we did not select "None", we likely selected a used device
+ CV_SetValue(&cv_usejoystick2, (oldstringchoice > numjoys ? oldstringchoice : oldchoice));
+
+ if (oldstringchoice ==
+ (atoi(cv_usejoystick2.string) > numjoys ? atoi(cv_usejoystick2.string) : cv_usejoystick2.value))
+ M_StartMessage("This joystick is used by another\n"
+ "player. Reset the joystick\n"
+ "for that player first.\n\n"
+ "(Press a key)\n", NULL, MM_NOTHING);
+ }
+ }
+ }
+ else if (setupcontrolplayer == 1)
+ {
+ oldchoice = oldstringchoice = atoi(cv_usejoystick.string) > numjoys ? atoi(cv_usejoystick.string) : cv_usejoystick.value;
+ CV_SetValue(&cv_usejoystick, choice);
+
+ // Just in case last-minute changes were made to cv_usejoystick.value,
+ // update the string too
+ // But don't do this if we're intentionally setting higher than numjoys
+ if (choice <= numjoys)
+ {
+ CV_SetValue(&cv_usejoystick, cv_usejoystick.value);
+
+ // reset this so the comparison is valid
+ if (oldchoice > numjoys)
+ oldchoice = cv_usejoystick.value;
+
+ if (oldchoice != choice)
+ {
+ if (choice && oldstringchoice > numjoys) // if we did not select "None", we likely selected a used device
+ CV_SetValue(&cv_usejoystick, (oldstringchoice > numjoys ? oldstringchoice : oldchoice));
+
+ if (oldstringchoice ==
+ (atoi(cv_usejoystick.string) > numjoys ? atoi(cv_usejoystick.string) : cv_usejoystick.value))
+ M_StartMessage("This joystick is used by another\n"
+ "player. Reset the joystick\n"
+ "for that player first.\n\n"
+ "(Press a key)\n", NULL, MM_NOTHING);
+ }
+ }
+ }
+#else
if (setupcontrolplayer == 4)
CV_SetValue(&cv_usejoystick4, choice);
else if (setupcontrolplayer == 3)
CV_SetValue(&cv_usejoystick3, choice);
else if (setupcontrolplayer == 2)
CV_SetValue(&cv_usejoystick2, choice);
- else
+ else if (setupcontrolplayer == 1)
CV_SetValue(&cv_usejoystick, choice);
+#endif
}
// =============
@@ -8894,7 +9075,7 @@ static void M_DrawControl(void)
#undef controlheight
static INT32 controltochange;
-static char controltochangetext[55];
+static char controltochangetext[33];
static void M_ChangecontrolResponse(event_t *ev)
{
@@ -8965,14 +9146,15 @@ static void M_ChangecontrolResponse(event_t *ev)
found = 0;
setupcontrols[control][1] = KEY_NULL; //replace key 1,clear key2
}
- G_CheckDoubleUsage(ch);
+ (void)G_CheckDoubleUsage(ch, true);
setupcontrols[control][found] = ch;
}
S_StartSound(NULL, sfx_s221);
}
else if (ch == KEY_PAUSE)
{
- static char tmp[155];
+ // This buffer assumes a 125-character message plus a 32-character control name (per controltochangetext buffer size)
+ static char tmp[158];
menu_t *prev = currentMenu->prevMenu;
if (controltochange == gc_pause)
@@ -8996,12 +9178,14 @@ static void M_ChangecontrolResponse(event_t *ev)
static void M_ChangeControl(INT32 choice)
{
- static char tmp[55];
+ // This buffer assumes a 35-character message (per below) plus a max control name limit of 32 chars (per controltochangetext)
+ // If you change the below message, then change the size of this buffer!
+ static char tmp[68];
controltochange = currentMenu->menuitems[choice].alphaKey;
sprintf(tmp, M_GetText("Hit the new key for\n%s\nESC for Cancel"),
currentMenu->menuitems[choice].text);
- strncpy(controltochangetext, currentMenu->menuitems[choice].text, 55);
+ strlcpy(controltochangetext, currentMenu->menuitems[choice].text, 33);
M_StartMessage(tmp, M_ChangecontrolResponse, MM_EVENTHANDLER);
}
diff --git a/src/m_menu.h b/src/m_menu.h
index 79e14d4b..9509004b 100644
--- a/src/m_menu.h
+++ b/src/m_menu.h
@@ -69,7 +69,6 @@ void M_QuitResponse(INT32 ch);
// Determines whether to show a level in the list
boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt);
-
// flags for items in the menu
// menu handle (what we do when key is pressed
#define IT_TYPE 14 // (2+4+8)
@@ -173,6 +172,10 @@ extern menu_t *currentMenu;
extern menu_t MainDef;
extern menu_t SP_LoadDef;
+// Call upon joystick hotplug
+void M_SetupJoystickMenu(INT32 choice);
+extern menu_t OP_JoystickSetDef;
+
// Stuff for customizing the player select screen
typedef struct
{
diff --git a/src/m_misc.c b/src/m_misc.c
index 003bf925..0586f6e5 100644
--- a/src/m_misc.c
+++ b/src/m_misc.c
@@ -37,6 +37,7 @@
#include "d_main.h"
#include "m_argv.h"
#include "i_system.h"
+#include "command.h" // cv_execversion
#include "m_anigif.h"
@@ -440,7 +441,22 @@ void Command_LoadConfig_f(void)
strcpy(configfile, COM_Argv(1));
FIL_ForceExtension(configfile, ".cfg");
+
+ // load default control
+ G_ClearAllControlKeys();
+ G_Controldefault(0);
+
+ // temporarily reset execversion to default
+ CV_ToggleExecVersion(true);
+ COM_BufInsertText(va("%s \"%s\"\n", cv_execversion.name, cv_execversion.defaultvalue));
+ CV_InitFilterVar();
+
+ // exec the config
COM_BufInsertText(va("exec \"%s\"\n", configfile));
+
+ // don't filter anymore vars and don't let this convsvar be changed
+ COM_BufInsertText(va("%s \"%d\"\n", cv_execversion.name, EXECVERSION));
+ CV_ToggleExecVersion(false);
}
/** Saves the current configuration and loads another.
@@ -477,10 +493,23 @@ void M_FirstLoadConfig(void)
// load default control
G_Controldefault(0);
+ // register execversion here before we load any configs
+ CV_RegisterVar(&cv_execversion);
+
+ // temporarily reset execversion to default
+ // we shouldn't need to do this, but JUST in case...
+ CV_ToggleExecVersion(true);
+ COM_BufInsertText(va("%s \"%s\"\n", cv_execversion.name, cv_execversion.defaultvalue));
+ CV_InitFilterVar();
+
// load config, make sure those commands doesnt require the screen...
COM_BufInsertText(va("exec \"%s\"\n", configfile));
// no COM_BufExecute() needed; that does it right away
+ // don't filter anymore vars and don't let this convsvar be changed
+ COM_BufInsertText(va("%s \"%d\"\n", cv_execversion.name, EXECVERSION));
+ CV_ToggleExecVersion(false);
+
// make sure I_Quit() will write back the correct config
// (do not write back the config if it crash before)
gameconfig_loaded = true;
@@ -493,6 +522,7 @@ void M_FirstLoadConfig(void)
void M_SaveConfig(const char *filename)
{
FILE *f;
+ char *filepath;
// make sure not to write back the config until it's been correctly loaded
if (!gameconfig_loaded)
@@ -507,13 +537,20 @@ void M_SaveConfig(const char *filename)
return;
}
- f = fopen(filename, "w");
+ // append srb2home to beginning of filename
+ // but check if srb2home isn't already there, first
+ if (!strstr(filename, srb2home))
+ filepath = va(pandf,srb2home, filename);
+ else
+ filepath = Z_StrDup(filename);
+
+ f = fopen(filepath, "w");
// change it only if valid
if (f)
- strcpy(configfile, filename);
+ strcpy(configfile, filepath);
else
{
- CONS_Alert(CONS_ERROR, M_GetText("Couldn't save game config file %s\n"), filename);
+ CONS_Alert(CONS_ERROR, M_GetText("Couldn't save game config file %s\n"), filepath);
return;
}
}
@@ -536,6 +573,10 @@ void M_SaveConfig(const char *filename)
// header message
fprintf(f, "// SRB2Kart configuration file.\n");
+ // print execversion FIRST, because subsequent consvars need to be filtered
+ // always print current EXECVERSION
+ fprintf(f, "%s \"%d\"\n", cv_execversion.name, EXECVERSION);
+
// FIXME: save key aliases if ever implemented..
CV_SaveVariables(f);
diff --git a/src/p_enemy.c b/src/p_enemy.c
index 3fb3aca6..fc3ae9d9 100644
--- a/src/p_enemy.c
+++ b/src/p_enemy.c
@@ -3971,7 +3971,7 @@ static inline boolean PIT_GrenadeRing(mobj_t *thing)
void A_GrenadeRing(mobj_t *actor)
{
INT32 bx, by, xl, xh, yl, yh;
- explodedist = FixedMul(actor->info->painchance, mapheaderinfo[gamemap-1]->mobj_scale);
+ explodedist = FixedMul(actor->info->painchance, mapobjectscale);
#ifdef HAVE_BLUA
if (LUA_CallAction("A_GrenadeRing", actor))
return;
@@ -4039,7 +4039,7 @@ void A_MineExplode(mobj_t *actor)
INT32 d;
INT32 locvar1 = var1;
mobjtype_t type;
- explodedist = FixedMul((3*actor->info->painchance)/2, mapheaderinfo[gamemap-1]->mobj_scale);
+ explodedist = FixedMul((3*actor->info->painchance)/2, mapobjectscale);
#ifdef HAVE_BLUA
if (LUA_CallAction("A_MineExplode", actor))
return;
@@ -4060,7 +4060,7 @@ void A_MineExplode(mobj_t *actor)
P_BlockThingsIterator(bx, by, PIT_MineExplode);
for (d = 0; d < 16; d++)
- K_SpawnKartExplosion(actor->x, actor->y, actor->z, explodedist + 32*mapheaderinfo[gamemap-1]->mobj_scale, 32, type, d*(ANGLE_45/4), true, false, actor->target); // 32 <-> 64
+ K_SpawnKartExplosion(actor->x, actor->y, actor->z, explodedist + 32*mapobjectscale, 32, type, d*(ANGLE_45/4), true, false, actor->target); // 32 <-> 64
if (actor->target && actor->target->player)
K_SpawnMineExplosion(actor, actor->target->player->skincolor);
@@ -10382,7 +10382,7 @@ void A_SetScale(mobj_t *actor)
return;
}
- locvar1 = FixedMul(locvar1, mapheaderinfo[gamemap-1]->mobj_scale); // SRB2Kart
+ locvar1 = FixedMul(locvar1, mapobjectscale); // SRB2Kart
target->destscale = locvar1; // destination scale
if (!(locvar2 & 65535))
diff --git a/src/p_floor.c b/src/p_floor.c
index 752a66b7..e11fe403 100644
--- a/src/p_floor.c
+++ b/src/p_floor.c
@@ -3009,7 +3009,7 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover)
fixed_t topz;
fixed_t a, b, c;
mobjtype_t type = MT_ROCKCRUMBLE1;
- const fixed_t spacing = 48*mapheaderinfo[gamemap-1]->mobj_scale;
+ const fixed_t spacing = 48*mapobjectscale;
// If the control sector has a special
// of Section3:7-15, use the custom debris.
diff --git a/src/p_inter.c b/src/p_inter.c
index fce8ccd5..4fedcea8 100644
--- a/src/p_inter.c
+++ b/src/p_inter.c
@@ -366,7 +366,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
P_SetTarget(&special->tracer, toucher);
special->flags2 |= MF2_NIGHTSPULL;
- special->destscale = mapheaderinfo[gamemap-1]->mobj_scale>>4;
+ special->destscale = mapobjectscale>>4;
special->scalespeed <<= 1;
special->flags &= ~MF_SPECIAL;
diff --git a/src/p_local.h b/src/p_local.h
index ddcfd75e..0b64307d 100644
--- a/src/p_local.h
+++ b/src/p_local.h
@@ -41,9 +41,6 @@
// Convenience macro to fix issue with collision along bottom/left edges of blockmap -Red
#define BMBOUNDFIX(xl, xh, yl, yh) {if (xl > xh) xl = 0; if (yl > yh) yl = 0;}
-// player radius used only in am_map.c
-#define PLAYERRADIUS (16*FRACUNIT)
-
// MAXRADIUS is for precalculated sector block boxes
// the spider demon is larger,
// but we do not have any moving sectors nearby
diff --git a/src/p_map.c b/src/p_map.c
index 115ea665..c307e572 100644
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -116,8 +116,8 @@ boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
boolean P_DoSpring(mobj_t *spring, mobj_t *object)
{
//INT32 pflags;
- const fixed_t hscale = mapheaderinfo[gamemap-1]->mobj_scale + (mapheaderinfo[gamemap-1]->mobj_scale - object->scale);
- const fixed_t vscale = mapheaderinfo[gamemap-1]->mobj_scale + (object->scale - mapheaderinfo[gamemap-1]->mobj_scale);
+ const fixed_t hscale = mapobjectscale + (mapobjectscale - object->scale);
+ const fixed_t vscale = mapobjectscale + (object->scale - mapobjectscale);
fixed_t offx, offy;
fixed_t vertispeed = spring->info->mass;
fixed_t horizspeed = spring->info->damage;
@@ -1424,9 +1424,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
&& !(thing->z + thing->height < tmthing->z || thing->z > tmthing->z + tmthing->height))
{
- if (tmthing->scale > thing->scale + (mapheaderinfo[gamemap-1]->mobj_scale/8)) // SRB2kart - Handle squishes first!
+ if (tmthing->scale > thing->scale + (mapobjectscale/8)) // SRB2kart - Handle squishes first!
K_SquishPlayer(thing->player, tmthing, tmthing);
- else if (thing->scale > tmthing->scale + (mapheaderinfo[gamemap-1]->mobj_scale/8))
+ else if (thing->scale > tmthing->scale + (mapobjectscale/8))
K_SquishPlayer(tmthing->player, thing, tmthing);
else if (tmthing->player->kartstuff[k_invincibilitytimer] && !thing->player->kartstuff[k_invincibilitytimer]) // SRB2kart - Then invincibility!
P_DamageMobj(thing, tmthing, tmthing, 1);
@@ -1523,9 +1523,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
return true; // underneath
if (thing->player->kartstuff[k_squishedtimer] || thing->player->kartstuff[k_hyudorotimer]
- || thing->player->kartstuff[k_justbumped] || thing->scale > tmthing->scale + (mapheaderinfo[gamemap-1]->mobj_scale/8)
+ || thing->player->kartstuff[k_justbumped] || thing->scale > tmthing->scale + (mapobjectscale/8)
|| tmthing->player->kartstuff[k_squishedtimer] || tmthing->player->kartstuff[k_hyudorotimer]
- || tmthing->player->kartstuff[k_justbumped] || tmthing->scale > thing->scale + (mapheaderinfo[gamemap-1]->mobj_scale/8))
+ || tmthing->player->kartstuff[k_justbumped] || tmthing->scale > thing->scale + (mapobjectscale/8))
{
return true;
}
@@ -2706,7 +2706,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
if (!(thing->flags & MF_NOCLIP))
{
//All things are affected by their scale.
- fixed_t maxstep = FixedMul(MAXSTEPMOVE, mapheaderinfo[gamemap-1]->mobj_scale);
+ fixed_t maxstep = FixedMul(MAXSTEPMOVE, mapobjectscale);
if (thing->player)
{
@@ -2909,7 +2909,7 @@ boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y)
if (!(thing->flags & MF_NOCLIP))
{
- const fixed_t maxstep = FixedMul(MAXSTEPMOVE, mapheaderinfo[gamemap-1]->mobj_scale);
+ const fixed_t maxstep = FixedMul(MAXSTEPMOVE, mapobjectscale);
if (tmceilingz - tmfloorz < thing->height)
return false; // doesn't fit
@@ -3133,8 +3133,8 @@ static void P_PlayerHitBounceLine(line_t *ld)
movelen = P_AproxDistance(tmxmove, tmymove);
- if (slidemo->player && movelen < (15*mapheaderinfo[gamemap-1]->mobj_scale))
- movelen = (15*mapheaderinfo[gamemap-1]->mobj_scale);
+ if (slidemo->player && movelen < (15*mapobjectscale))
+ movelen = (15*mapobjectscale);
tmxmove += FixedMul(movelen, FINECOSINE(lineangle));
tmymove += FixedMul(movelen, FINESINE(lineangle));
@@ -3392,7 +3392,7 @@ static boolean PTR_SlideTraverse(intercept_t *in)
if (opentop - slidemo->z < slidemo->height)
goto isblocking; // mobj is too high
- if (openbottom - slidemo->z > FixedMul(MAXSTEPMOVE, mapheaderinfo[gamemap-1]->mobj_scale))
+ if (openbottom - slidemo->z > FixedMul(MAXSTEPMOVE, mapobjectscale))
goto isblocking; // too big a step up
// this line doesn't block movement
@@ -3809,6 +3809,7 @@ void P_BouncePlayerMove(mobj_t *mo)
fixed_t leadx, leady;
fixed_t trailx, traily;
fixed_t mmomx = 0, mmomy = 0;
+ fixed_t oldmomx = mo->momx, oldmomy = mo->momy;
if (!mo->player)
return;
@@ -3897,7 +3898,9 @@ void P_BouncePlayerMove(mobj_t *mo)
mo->player->cmomx = tmxmove;
mo->player->cmomy = tmymove;
- P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true);
+ if (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true)) {
+ P_TryMove(mo, mo->x - oldmomx, mo->y - oldmomy, true);
+ }
}
//
diff --git a/src/p_mobj.c b/src/p_mobj.c
index e393c11e..4379b958 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -1744,7 +1744,7 @@ void P_XYMovement(mobj_t *mo)
}
else
{
- if (mo->scale < mapheaderinfo[gamemap-1]->mobj_scale/16)
+ if (mo->scale < mapobjectscale/16)
{
P_RemoveMobj(mo);
return;
@@ -3675,7 +3675,7 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
postimg = postimg_mirror;
else if (player->pflags & PF_FLIPCAM && !(player->pflags & PF_NIGHTSMODE) && player->mo->eflags & MFE_VERTICALFLIP)
postimg = postimg_flip;
- else if (player->awayviewtics && player->awayviewmobj != NULL) // Camera must obviously exist
+ else if (player->awayviewtics && player->awayviewmobj && !P_MobjWasRemoved(player->awayviewmobj)) // Camera must obviously exist
{
camera_t dummycam;
dummycam.subsector = player->awayviewmobj->subsector;
@@ -7223,7 +7223,7 @@ void P_MobjThinker(mobj_t *mobj)
{
x = mobj->target->x;
y = mobj->target->y;
- z = mobj->target->z + 80*(mapheaderinfo[gamemap-1]->mobj_scale);
+ z = mobj->target->z + (80*mapobjectscale);
}
P_TeleportMove(mobj, x, y, z);
}
@@ -7890,7 +7890,7 @@ void P_MobjThinker(mobj_t *mobj)
else
{
mobj->flags &= ~MF_NOGRAVITY;
- if (mobj->z > mobj->watertop && mobj->z - mobj->watertop < FixedMul(MAXSTEPMOVE, mapheaderinfo[gamemap-1]->mobj_scale))
+ if (mobj->z > mobj->watertop && mobj->z - mobj->watertop < FixedMul(MAXSTEPMOVE, mapobjectscale))
mobj->z = mobj->watertop;
}
break;
@@ -7959,7 +7959,7 @@ void P_MobjThinker(mobj_t *mobj)
if (mobj->flags2 & MF2_NIGHTSPULL)
{
if (!mobj->tracer || !mobj->tracer->health
- || mobj->scale <= mapheaderinfo[gamemap-1]->mobj_scale>>4)
+ || mobj->scale <= mapobjectscale>>4)
{
P_RemoveMobj(mobj);
return;
@@ -7968,7 +7968,7 @@ void P_MobjThinker(mobj_t *mobj)
}
else
{
- fixed_t adj = FixedMul(FRACUNIT - FINECOSINE((mobj->movedir>>ANGLETOFINESHIFT) & FINEMASK), (mapheaderinfo[gamemap-1]->mobj_scale<<3));
+ fixed_t adj = FixedMul(FRACUNIT - FINECOSINE((mobj->movedir>>ANGLETOFINESHIFT) & FINEMASK), (mapobjectscale<<3));
mobj->movedir += 2*ANG2;
if (mobj->eflags & MFE_VERTICALFLIP)
mobj->z = mobj->ceilingz - mobj->height - adj;
@@ -8036,6 +8036,7 @@ void P_MobjThinker(mobj_t *mobj)
for (i = 5; i >= mobj->health; i--)
finalspeed = FixedMul(finalspeed, FRACUNIT-FRACUNIT/4);
}
+
P_InstaThrust(mobj, mobj->angle, finalspeed);
if (grounded)
@@ -8059,7 +8060,7 @@ void P_MobjThinker(mobj_t *mobj)
{
sector_t *sec2;
fixed_t topspeed = mobj->movefactor;
- fixed_t distbarrier = 512*FRACUNIT;
+ fixed_t distbarrier = 512*mapobjectscale;
fixed_t distaway;
P_SpawnGhostMobj(mobj);
@@ -8073,7 +8074,6 @@ void P_MobjThinker(mobj_t *mobj)
distbarrier = FixedMul(distbarrier, FRACUNIT-FRACUNIT/4);
else if (gamespeed == 2)
distbarrier = FixedMul(distbarrier, FRACUNIT+FRACUNIT/4);
- distbarrier = FixedMul(distbarrier, mapheaderinfo[gamemap-1]->mobj_scale);
if (G_RaceGametype() && mobj->tracer)
{
@@ -8832,7 +8832,7 @@ void P_MobjThinker(mobj_t *mobj)
mobj_t *head = P_SpawnMobj(mobj->x, mobj->y, mobj->z, (blue ? MT_BLUEROBRA_HEAD : MT_ROBRA_HEAD));
P_SetTarget(&mobj->tracer, head);
- mobj->destscale = mapheaderinfo[gamemap-1]->mobj_scale;
+ mobj->destscale = mapobjectscale;
P_SetTarget(&mobj->tracer->target, mobj->target);
P_SetTarget(&mobj->tracer->tracer, mobj);
mobj->tracer->extravalue2 = mobj->extravalue2;
@@ -9282,6 +9282,8 @@ void P_MobjThinker(mobj_t *mobj)
// Assumedly in splitscreen players will be on opposing teams
if (players[consoleplayer].ctfteam == 1 || splitscreen)
S_StartSound(NULL, sfx_hoop1);
+ else if (players[consoleplayer].ctfteam == 2)
+ S_StartSound(NULL, sfx_hoop3);
redflag = flagmo;
}
@@ -9293,6 +9295,8 @@ void P_MobjThinker(mobj_t *mobj)
// Assumedly in splitscreen players will be on opposing teams
if (players[consoleplayer].ctfteam == 2 || splitscreen)
S_StartSound(NULL, sfx_hoop1);
+ else if (players[consoleplayer].ctfteam == 1)
+ S_StartSound(NULL, sfx_hoop3);
blueflag = flagmo;
}
@@ -9758,10 +9762,13 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
// All mobjs are created at 100% scale.
mobj->scale = FRACUNIT;
mobj->destscale = mobj->scale;
- mobj->scalespeed = mapheaderinfo[gamemap-1]->mobj_scale/12;
+ mobj->scalespeed = FRACUNIT/12;
- if (mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->mobj_scale != FRACUNIT) //&& !(mobj->type == MT_BLACKEGGMAN)
- mobj->destscale = mapheaderinfo[gamemap-1]->mobj_scale;
+ if (mapobjectscale != FRACUNIT) //&& !(mobj->type == MT_BLACKEGGMAN)
+ {
+ mobj->destscale = mapobjectscale;
+ mobj->scalespeed = mapobjectscale/12;
+ }
// set subsector and/or block links
P_SetThingPosition(mobj);
@@ -10205,10 +10212,13 @@ mobj_t *P_SpawnShadowMobj(mobj_t * caster)
// All mobjs are created at 100% scale.
mobj->scale = FRACUNIT;
mobj->destscale = mobj->scale;
- mobj->scalespeed = mapheaderinfo[gamemap-1]->mobj_scale/12;
+ mobj->scalespeed = FRACUNIT/12;
- if (mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->mobj_scale != FRACUNIT) //&& !(mobj->type == MT_BLACKEGGMAN)
- mobj->destscale = mapheaderinfo[gamemap-1]->mobj_scale;
+ if (mapobjectscale != FRACUNIT) //&& !(mobj->type == MT_BLACKEGGMAN)
+ {
+ mobj->destscale = mapobjectscale;
+ mobj->scalespeed = mapobjectscale/12;
+ }
P_SetScale(mobj, mobj->destscale);
@@ -11114,7 +11124,7 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing)
if (mthing->options >> ZSHIFT)
z -= ((mthing->options >> ZSHIFT) << FRACBITS);
if (p->kartstuff[k_respawn])
- z -= 128*FRACUNIT; // Too late for v1, but for later: 128*mapheaderinfo[gamemap-1]->mobj_scale;
+ z -= 128*FRACUNIT; // Too late for v1, but for later: 128*mapobjectscale;
}
else
{
@@ -11122,7 +11132,7 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing)
if (mthing->options >> ZSHIFT)
z += ((mthing->options >> ZSHIFT) << FRACBITS);
if (p->kartstuff[k_respawn])
- z += 128*FRACUNIT; // Too late for v1, but for later: 128*mapheaderinfo[gamemap-1]->mobj_scale;
+ z += 128*FRACUNIT; // Too late for v1, but for later: 128*mapobjectscale;
}
if (mthing->options & MTF_OBJECTFLIP) // flip the player!
@@ -11896,6 +11906,7 @@ ML_NOCLIMB : Direction not controllable
else if (i == MT_BOSS3WAYPOINT) // SRB2kart 120217 - Used to store checkpoint num
{
mobj->health = mthing->angle;
+ mobj->movecount = mthing->extrainfo;
P_SetTarget(&mobj->tracer, waypointcap);
P_SetTarget(&waypointcap, mobj);
}
diff --git a/src/p_polyobj.c b/src/p_polyobj.c
index ed97f9ba..34402f1a 100644
--- a/src/p_polyobj.c
+++ b/src/p_polyobj.c
@@ -1863,6 +1863,9 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
diffz = po->lines[0]->backsector->floorheight - (target->z - amtz);
po->lines[0]->backsector->floorheight = target->z - amtz;
po->lines[0]->backsector->ceilingheight = target->z + amtz;
+ // Sal: Remember to check your sectors!
+ P_CheckSector(po->lines[0]->frontsector, (boolean)(po->damage));
+ P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage));
// Apply action to mirroring polyobjects as well
start = 0;
while ((po = Polyobj_GetChild(oldpo, &start)))
@@ -1874,6 +1877,9 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
// TODO: use T_MovePlane
po->lines[0]->backsector->floorheight += diffz; // move up/down by same amount as the parent did
po->lines[0]->backsector->ceilingheight += diffz;
+ // Sal: Remember to check your sectors!
+ P_CheckSector(po->lines[0]->frontsector, (boolean)(po->damage));
+ P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage));
}
po = oldpo;
@@ -2034,6 +2040,9 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
// TODO: use T_MovePlane
po->lines[0]->backsector->floorheight += momz;
po->lines[0]->backsector->ceilingheight += momz;
+ // Sal: Remember to check your sectors!
+ P_CheckSector(po->lines[0]->frontsector, (boolean)(po->damage)); // frontsector is NEEDED for crushing
+ P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage)); // backsector may not be necessary, but just in case
// Apply action to mirroring polyobjects as well
start = 0;
@@ -2046,6 +2055,9 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
// TODO: use T_MovePlane
po->lines[0]->backsector->floorheight += momz;
po->lines[0]->backsector->ceilingheight += momz;
+ // Sal: Remember to check your sectors!
+ P_CheckSector(po->lines[0]->frontsector, (boolean)(po->damage));
+ P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage));
}
}
diff --git a/src/p_saveg.c b/src/p_saveg.c
index 02f77457..555a2614 100644
--- a/src/p_saveg.c
+++ b/src/p_saveg.c
@@ -1132,7 +1132,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
diff |= MD_SCALE;
if (mobj->destscale != mobj->scale)
diff |= MD_DSCALE;
- if (mobj->scalespeed != mapheaderinfo[gamemap-1]->mobj_scale/12)
+ if (mobj->scalespeed != mapobjectscale/12)
diff2 |= MD2_SCALESPEED;
if (mobj == redflag)
@@ -2139,7 +2139,7 @@ static void LoadMobjThinker(actionf_p1 thinker)
if (diff2 & MD2_SCALESPEED)
mobj->scalespeed = READFIXED(save_p);
else
- mobj->scalespeed = mapheaderinfo[gamemap-1]->mobj_scale/12;
+ mobj->scalespeed = mapobjectscale/12;
if (diff2 & MD2_CUSVAL)
mobj->cusval = READINT32(save_p);
if (diff2 & MD2_CVMEM)
@@ -3282,6 +3282,7 @@ static void P_NetArchiveMisc(void)
WRITEUINT32(save_p, countdown2);
WRITEFIXED(save_p, gravity);
+ WRITEFIXED(save_p, mapobjectscale);
WRITEUINT32(save_p, countdowntimer);
WRITEUINT8(save_p, countdowntimeup);
@@ -3389,6 +3390,7 @@ static inline boolean P_NetUnArchiveMisc(void)
countdown2 = READUINT32(save_p);
gravity = READFIXED(save_p);
+ mapobjectscale = READFIXED(save_p);
countdowntimer = (tic_t)READUINT32(save_p);
countdowntimeup = (boolean)READUINT8(save_p);
diff --git a/src/p_setup.c b/src/p_setup.c
index 3bdb4d05..2e26404e 100644
--- a/src/p_setup.c
+++ b/src/p_setup.c
@@ -229,6 +229,8 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
mapheaderinfo[num]->levelselect = 0;
DEH_WriteUndoline("BONUSTYPE", va("%d", mapheaderinfo[num]->bonustype), UNDO_NONE);
mapheaderinfo[num]->bonustype = 0;
+ DEH_WriteUndoline("SAVEOVERRIDE", va("%d", mapheaderinfo[num]->saveoverride), UNDO_NONE);
+ mapheaderinfo[num]->saveoverride = SAVE_DEFAULT;
DEH_WriteUndoline("LEVELFLAGS", va("%d", mapheaderinfo[num]->levelflags), UNDO_NONE);
mapheaderinfo[num]->levelflags = 0;
DEH_WriteUndoline("MENUFLAGS", va("%d", mapheaderinfo[num]->menuflags), UNDO_NONE);
@@ -395,30 +397,26 @@ static inline void P_LoadVertexes(lumpnum_t lumpnum)
Z_Free(data);
}
-
-//
-// Computes the line length in fracunits, the OpenGL render needs this
-//
-
/** Computes the length of a seg in fracunits.
- * This is needed for splats.
*
* \param seg Seg to compute length for.
* \return Length in fracunits.
*/
fixed_t P_SegLength(seg_t *seg)
{
- fixed_t dx, dy;
-
- // make a vector (start at origin)
- dx = seg->v2->x - seg->v1->x;
- dy = seg->v2->y - seg->v1->y;
-
- return FixedHypot(dx, dy);
+ INT64 dx = (seg->v2->x - seg->v1->x)>>1;
+ INT64 dy = (seg->v2->y - seg->v1->y)>>1;
+ return FixedHypot(dx, dy)<<1;
}
#ifdef HWRENDER
-static inline float P_SegLengthf(seg_t *seg)
+/** Computes the length of a seg as a float.
+ * This is needed for OpenGL.
+ *
+ * \param seg Seg to compute length for.
+ * \return Length as a float.
+ */
+static inline float P_SegLengthFloat(seg_t *seg)
{
float dx, dy;
@@ -454,11 +452,11 @@ static void P_LoadRawSegs(UINT8 *data, size_t i)
li->v1 = &vertexes[SHORT(ml->v1)];
li->v2 = &vertexes[SHORT(ml->v2)];
-#ifdef HWRENDER // not win32 only 19990829 by Kin
- // used for the hardware render
- if (rendermode != render_soft && rendermode != render_none)
+ li->length = P_SegLength(li);
+#ifdef HWRENDER
+ if (rendermode == render_opengl)
{
- li->flength = P_SegLengthf(li);
+ li->flength = P_SegLengthFloat(li);
//Hurdler: 04/12/2000: for now, only used in hardware mode
li->lightmaps = NULL; // list of static lightmap for this seg
}
@@ -2019,7 +2017,7 @@ static boolean P_LoadRawBlockMap(UINT8 *data, size_t count, const char *lumpname
if (!count || count >= 0x20000)
return false;
- CONS_Printf("Reading blockmap lump for pk3...\n");
+ //CONS_Printf("Reading blockmap lump for pk3...\n");
// no need to malloc anything, assume the data is uncompressed for now
count /= 2;
@@ -2714,6 +2712,32 @@ static void P_SetupCamera(UINT8 pnum, camera_t *cam)
}
}
+static boolean P_CanSave(void)
+{
+#if 0
+ // Saving is completely ignored under these conditions:
+ if ((cursaveslot < 0) // Playing without saving
+ || (modifiedgame && !savemoddata) // Game is modified
+ || (netgame || multiplayer) // Not in single-player
+ || (demoplayback || demorecording || metalrecording) // Currently in demo
+ || (players[consoleplayer].lives <= 0) // Completely dead
+ || (modeattacking || ultimatemode || G_IsSpecialStage(gamemap))) // Specialized instances
+ return false;
+
+ if (mapheaderinfo[gamemap-1]->saveoverride == SAVE_ALWAYS)
+ return true; // Saving should ALWAYS happen!
+ else if (mapheaderinfo[gamemap-1]->saveoverride == SAVE_NEVER)
+ return false; // Saving should NEVER happen!
+
+ // Default condition: In a non-hidden map, at the beginning of a zone or on a completed save-file, and not on save reload.
+ return (!(mapheaderinfo[gamemap-1]->menuflags & LF2_HIDEINMENU)
+ && (mapheaderinfo[gamemap-1]->actnum < 2 || gamecomplete)
+ && (gamemap != lastmapsaved));
+#else
+ return false; // SRB2Kart: no SP, no saving.
+#endif
+}
+
/** Loads a level from a lump or external wad.
*
* \param skipprecip If true, don't spawn precipitation.
@@ -3154,12 +3178,12 @@ boolean P_SetupLevel(boolean skipprecip)
/*if (!cv_cam_height.changed)
CV_Set(&cv_cam_height, cv_cam_height.defaultvalue);
- if (!cv_cam2_height.changed)
- CV_Set(&cv_cam2_height, cv_cam2_height.defaultvalue);
-
if (!cv_cam_dist.changed)
CV_Set(&cv_cam_dist, cv_cam_dist.defaultvalue);
+ if (!cv_cam2_height.changed)
+ CV_Set(&cv_cam2_height, cv_cam2_height.defaultvalue);
+
if (!cv_cam2_dist.changed)
CV_Set(&cv_cam2_dist, cv_cam2_dist.defaultvalue);*/
@@ -3253,10 +3277,7 @@ boolean P_SetupLevel(boolean skipprecip)
P_RunCachedActions();
- if (!(netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking || players[consoleplayer].lives <= 0)
- && (!modifiedgame || savemoddata) && cursaveslot >= 0 && !ultimatemode
- && !(mapheaderinfo[gamemap-1]->menuflags & LF2_HIDEINMENU)
- && (!G_IsSpecialStage(gamemap)) && gamemap != lastmapsaved && (/*mapheaderinfo[gamemap-1]->actnum < 2 ||*/ gamecomplete))
+ if (P_CanSave())
G_SaveGame((UINT32)cursaveslot);
if (savedata.lives > 0)
diff --git a/src/p_slopes.c b/src/p_slopes.c
index ab558c53..c6416b75 100644
--- a/src/p_slopes.c
+++ b/src/p_slopes.c
@@ -801,8 +801,8 @@ void P_SlopeLaunch(mobj_t *mo)
#ifdef GROWNEVERMISSES
{
- const fixed_t xyscale = mapheaderinfo[gamemap-1]->mobj_scale + (mapheaderinfo[gamemap-1]->mobj_scale - mo->scale);
- const fixed_t zscale = mapheaderinfo[gamemap-1]->mobj_scale + (mapheaderinfo[gamemap-1]->mobj_scale - mo->scale);
+ const fixed_t xyscale = mapobjectscale + (mapobjectscale - mo->scale);
+ const fixed_t zscale = mapobjectscale + (mapobjectscale - mo->scale);
mo->momx = FixedMul(slopemom.x, xyscale);
mo->momy = FixedMul(slopemom.y, xyscale);
mo->momz = FixedMul(slopemom.z, zscale);
diff --git a/src/p_spec.c b/src/p_spec.c
index ea7b0c4d..35d26c6c 100644
--- a/src/p_spec.c
+++ b/src/p_spec.c
@@ -3262,7 +3262,7 @@ void P_SetupSignExit(player_t *player)
// SRB2Kart: FINALLY, add in an alternative if no place is found
if (player->mo)
{
- mobj_t *sign = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + (768*mapheaderinfo[gamemap-1]->mobj_scale), MT_SIGN);
+ mobj_t *sign = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + (768*mapobjectscale), MT_SIGN);
P_SetTarget(&sign->target, player->mo);
P_SetMobjState(sign, S_SIGN1);
@@ -3770,7 +3770,7 @@ DoneSection2:
case 1: // SRB2kart: Spring Panel
if (roversector || P_MobjReadyToTrigger(player->mo, sector))
{
- const fixed_t hscale = mapheaderinfo[gamemap-1]->mobj_scale + (mapheaderinfo[gamemap-1]->mobj_scale - player->mo->scale);
+ const fixed_t hscale = mapobjectscale + (mapobjectscale - player->mo->scale);
const fixed_t minspeed = 24*hscale;
if (player->mo->eflags & MFE_SPRUNG)
@@ -3790,7 +3790,7 @@ DoneSection2:
case 3: // SRB2kart: Spring Panel (capped speed)
if (roversector || P_MobjReadyToTrigger(player->mo, sector))
{
- const fixed_t hscale = mapheaderinfo[gamemap-1]->mobj_scale + (mapheaderinfo[gamemap-1]->mobj_scale - player->mo->scale);
+ const fixed_t hscale = mapobjectscale + (mapobjectscale - player->mo->scale);
const fixed_t minspeed = 24*hscale;
const fixed_t maxspeed = 28*hscale;
@@ -3829,8 +3829,8 @@ DoneSection2:
// SRB2Kart: Scale the speed you get from them!
// This is scaled differently from other horizontal speed boosts from stuff like springs, because of how this is used for some ramp jumps.
- if (player->mo->scale > mapheaderinfo[gamemap-1]->mobj_scale)
- linespeed = FixedMul(linespeed, mapheaderinfo[gamemap-1]->mobj_scale + (player->mo->scale - mapheaderinfo[gamemap-1]->mobj_scale));
+ if (player->mo->scale > mapobjectscale)
+ linespeed = FixedMul(linespeed, mapobjectscale + (player->mo->scale - mapobjectscale));
if (!demoplayback || P_AnalogMove(player))
{
@@ -5717,6 +5717,8 @@ void P_SpawnSpecials(INT32 fromnetsave)
else
curWeather = PRECIP_NONE;
+ mapobjectscale = mapheaderinfo[gamemap-1]->mobj_scale;
+
P_InitTagLists(); // Create xref tables for tags
P_SearchForDisableLinedefs(); // Disable linedefs are now allowed to disable *any* line
diff --git a/src/p_user.c b/src/p_user.c
index 853ceaf0..ab6c61dc 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -3033,7 +3033,7 @@ static fixed_t teeteryl, teeteryh;
static boolean PIT_CheckSolidsTeeter(mobj_t *thing) // SRB2kart - unused.
{
fixed_t blockdist;
- fixed_t tiptop = FixedMul(MAXSTEPMOVE, mapheaderinfo[gamemap-1]->mobj_scale);
+ fixed_t tiptop = FixedMul(MAXSTEPMOVE, mapobjectscale);
fixed_t thingtop = thing->z + thing->height;
fixed_t teeterertop = teeterer->z + teeterer->height;
@@ -3150,7 +3150,7 @@ static void P_DoTeeter(player_t *player) // SRB2kart - unused.
boolean roverfloor; // solid 3d floors?
fixed_t floorheight, ceilingheight;
fixed_t topheight, bottomheight; // for 3d floor usage
- const fixed_t tiptop = FixedMul(MAXSTEPMOVE, mapheaderinfo[gamemap-1]->mobj_scale); // Distance you have to be above the ground in order to teeter.
+ const fixed_t tiptop = FixedMul(MAXSTEPMOVE, mapobjectscale); // Distance you have to be above the ground in order to teeter.
if (player->mo->standingslope && player->mo->standingslope->zdelta >= (FRACUNIT/2)) // Always teeter if the slope is too steep.
teeter = true;
@@ -5023,9 +5023,9 @@ static void P_SpectatorMovement(player_t *player)
player->mo->z = player->mo->floorz;
if (cmd->buttons & BT_ACCELERATE)
- player->mo->z += 32*mapheaderinfo[gamemap-1]->mobj_scale;
+ player->mo->z += 32*mapobjectscale;
else if (cmd->buttons & BT_BRAKE)
- player->mo->z -= 32*mapheaderinfo[gamemap-1]->mobj_scale;
+ player->mo->z -= 32*mapobjectscale;
// Aiming needed for SEENAMES, etc.
// We may not need to fire as a spectator, but this is still handy!
@@ -5034,14 +5034,14 @@ static void P_SpectatorMovement(player_t *player)
player->mo->momx = player->mo->momy = player->mo->momz = 0;
if (cmd->forwardmove != 0)
{
- P_Thrust(player->mo, player->mo->angle, cmd->forwardmove*(mapheaderinfo[gamemap-1]->mobj_scale));
+ P_Thrust(player->mo, player->mo->angle, cmd->forwardmove*mapobjectscale);
// Quake-style flying spectators :D
- player->mo->momz += FixedMul(cmd->forwardmove*(mapheaderinfo[gamemap-1]->mobj_scale), AIMINGTOSLOPE(player->aiming));
+ player->mo->momz += FixedMul(cmd->forwardmove*mapobjectscale, AIMINGTOSLOPE(player->aiming));
}
if (cmd->sidemove != 0)
{
- P_Thrust(player->mo, player->mo->angle-ANGLE_90, cmd->sidemove*(mapheaderinfo[gamemap-1]->mobj_scale));
+ P_Thrust(player->mo, player->mo->angle-ANGLE_90, cmd->sidemove*mapobjectscale);
}
}
@@ -6697,7 +6697,7 @@ static void P_MovePlayer(player_t *player)
if (player->mo->state != &states[S_KART_SPIN])
P_SetPlayerMobjState(player->mo, S_KART_SPIN);
- if (speed == 1 && abs(player->mo->angle - player->frameangle) < ANGLE_22h)
+ if (speed == 1 && abs((signed)(player->mo->angle - player->frameangle)) < ANGLE_22h)
player->frameangle = player->mo->angle; // Face forward at the end of the animation
else
player->frameangle -= (ANGLE_11hh * speed);
@@ -7811,8 +7811,8 @@ boolean P_LookForEnemies(player_t *player)
if (mo->type == MT_DETON) // Don't be STUPID, Sonic!
continue;
- if (((mo->z > player->mo->z+FixedMul(MAXSTEPMOVE, mapheaderinfo[gamemap-1]->mobj_scale)) && !(player->mo->eflags & MFE_VERTICALFLIP))
- || ((mo->z+mo->height < player->mo->z+player->mo->height-FixedMul(MAXSTEPMOVE, mapheaderinfo[gamemap-1]->mobj_scale)) && (player->mo->eflags & MFE_VERTICALFLIP))) // Reverse gravity check - Flame.
+ if (((mo->z > player->mo->z+FixedMul(MAXSTEPMOVE, mapobjectscale)) && !(player->mo->eflags & MFE_VERTICALFLIP))
+ || ((mo->z+mo->height < player->mo->z+player->mo->height-FixedMul(MAXSTEPMOVE, mapobjectscale)) && (player->mo->eflags & MFE_VERTICALFLIP))) // Reverse gravity check - Flame.
continue; // Don't home upwards!
if (P_AproxDistance(P_AproxDistance(player->mo->x-mo->x, player->mo->y-mo->y),
@@ -7938,6 +7938,15 @@ void P_FindEmerald(void)
//
static void P_DeathThink(player_t *player)
{
+ //ticcmd_t *cmd = &player->cmd;
+ //player->deltaviewheight = 0;
+
+ if (player->deadtimer < INT32_MAX)
+ player->deadtimer++;
+
+ if (player->bot) // don't allow bots to do any of the below, B_CheckRespawn does all they need for respawning already
+ goto notrealplayer;
+
if (player->pflags & PF_TIMEOVER)
{
player->kartstuff[k_timeovercam]++;
@@ -7952,9 +7961,6 @@ static void P_DeathThink(player_t *player)
K_KartPlayerHUDUpdate(player);
- if (player->deadtimer < INT32_MAX)
- player->deadtimer++;
-
// Force respawn if idle for more than 30 seconds in shooter modes.
if (player->lives > 0 /*&& leveltime >= starttime*/) // *could* you respawn?
{
@@ -7987,6 +7993,8 @@ static void P_DeathThink(player_t *player)
}
}
+notrealplayer:
+
if (!player->mo)
return;
@@ -8044,18 +8052,21 @@ consvar_t cv_cam_still = {"cam_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL,
consvar_t cv_cam_speed = {"cam_speed", "0.4", CV_FLOAT|CV_SAVE, CV_CamSpeed, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_cam_rotate = {"cam_rotate", "0", CV_CALL|CV_NOINIT, CV_CamRotate, CV_CamRotate_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_cam_rotspeed = {"cam_rotspeed", "10", CV_SAVE, rotation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
+
consvar_t cv_cam2_dist = {"cam2_dist", "160", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_cam2_height = {"cam2_height", "50", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_cam2_still = {"cam2_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_cam2_speed = {"cam2_speed", "0.4", CV_FLOAT|CV_SAVE, CV_CamSpeed, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_cam2_rotate = {"cam2_rotate", "0", CV_CALL|CV_NOINIT, CV_CamRotate, CV_CamRotate2_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_cam2_rotspeed = {"cam2_rotspeed", "10", CV_SAVE, rotation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
+
consvar_t cv_cam3_dist = {"cam3_dist", "160", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_cam3_height = {"cam3_height", "50", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_cam3_still = {"cam3_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_cam3_speed = {"cam3_speed", "0.4", CV_FLOAT|CV_SAVE, CV_CamSpeed, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_cam3_rotate = {"cam3_rotate", "0", CV_CALL|CV_NOINIT, CV_CamRotate, CV_CamRotate3_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_cam3_rotspeed = {"cam3_rotspeed", "10", CV_SAVE, rotation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
+
consvar_t cv_cam4_dist = {"cam4_dist", "160", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_cam4_height = {"cam4_height", "50", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_cam4_still = {"cam4_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -8206,8 +8217,8 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
return true;
}
- thiscam->radius = FixedMul(20*FRACUNIT, mapheaderinfo[gamemap-1]->mobj_scale);
- thiscam->height = FixedMul(16*FRACUNIT, mapheaderinfo[gamemap-1]->mobj_scale);
+ thiscam->radius = 20*mapobjectscale;
+ thiscam->height = 16*mapobjectscale;
// Don't run while respawning from a starpost
// Inu 4/8/13 Why not?!
@@ -8253,8 +8264,8 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
camspeed = cv_cam_speed.value;
camstill = cv_cam_still.value;
camrotate = cv_cam_rotate.value;
- camdist = FixedMul(cv_cam_dist.value, mapheaderinfo[gamemap-1]->mobj_scale);
- camheight = FixedMul(cv_cam_height.value, mapheaderinfo[gamemap-1]->mobj_scale);
+ camdist = FixedMul(cv_cam_dist.value, mapobjectscale);
+ camheight = FixedMul(cv_cam_height.value, mapobjectscale);
lookback = camspin;
}
else if (thiscam == &camera2) // Camera 2
@@ -8262,8 +8273,8 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
camspeed = cv_cam2_speed.value;
camstill = cv_cam2_still.value;
camrotate = cv_cam2_rotate.value;
- camdist = FixedMul(cv_cam2_dist.value, mapheaderinfo[gamemap-1]->mobj_scale);
- camheight = FixedMul(cv_cam2_height.value, mapheaderinfo[gamemap-1]->mobj_scale);
+ camdist = FixedMul(cv_cam2_dist.value, mapobjectscale);
+ camheight = FixedMul(cv_cam2_height.value, mapobjectscale);
lookback = camspin2;
}
else if (thiscam == &camera3) // Camera 3
@@ -8271,8 +8282,8 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
camspeed = cv_cam3_speed.value;
camstill = cv_cam3_still.value;
camrotate = cv_cam3_rotate.value;
- camdist = FixedMul(cv_cam3_dist.value, mapheaderinfo[gamemap-1]->mobj_scale);
- camheight = FixedMul(cv_cam3_height.value, mapheaderinfo[gamemap-1]->mobj_scale);
+ camdist = FixedMul(cv_cam3_dist.value, mapobjectscale);
+ camheight = FixedMul(cv_cam3_height.value, mapobjectscale);
lookback = camspin3;
}
else // Camera 4
@@ -8280,8 +8291,8 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
camspeed = cv_cam4_speed.value;
camstill = cv_cam4_still.value;
camrotate = cv_cam4_rotate.value;
- camdist = FixedMul(cv_cam4_dist.value, mapheaderinfo[gamemap-1]->mobj_scale);
- camheight = FixedMul(cv_cam4_height.value, mapheaderinfo[gamemap-1]->mobj_scale);
+ camdist = FixedMul(cv_cam4_dist.value, mapobjectscale);
+ camheight = FixedMul(cv_cam4_height.value, mapobjectscale);
lookback = camspin4;
}
@@ -8294,8 +8305,8 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
{
const INT32 introcam = (introtime - leveltime);
camrotate += introcam*5;
- camdist += (introcam * mapheaderinfo[gamemap-1]->mobj_scale)*3;
- camheight += (introcam * mapheaderinfo[gamemap-1]->mobj_scale)*2;
+ camdist += (introcam * mapobjectscale)*3;
+ camheight += (introcam * mapobjectscale)*2;
}
else if (player->exiting) // SRB2Kart: Leave the camera behind while exiting, for dramatic effect!
camstill = true;
@@ -8603,7 +8614,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
// point viewed by the camera
// this point is just 64 unit forward the player
- dist = 64*mapheaderinfo[gamemap-1]->mobj_scale;
+ dist = 64*mapobjectscale;
viewpointx = mo->x + FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist) + xpan;
viewpointy = mo->y + FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist) + ypan;
@@ -8768,7 +8779,7 @@ static void P_CalcPostImg(player_t *player)
else
pviewheight = player->mo->z + player->viewheight;
- if (player->awayviewtics)
+ if (player->awayviewtics && player->awayviewmobj && !P_MobjWasRemoved(player->awayviewmobj))
{
sector = player->awayviewmobj->subsector->sector;
pviewheight = player->awayviewmobj->z + 20*FRACUNIT;
@@ -8976,6 +8987,13 @@ void P_PlayerThink(player_t *player)
}
}
#endif
+
+ if (player->awayviewmobj && P_MobjWasRemoved(player->awayviewmobj))
+ {
+ P_SetTarget(&player->awayviewmobj, NULL); // remove awayviewmobj asap if invalid
+ player->awayviewtics = 0; // reset to zero
+ }
+
/*
if (player->pflags & PF_GLIDING)
{
@@ -8989,9 +9007,14 @@ void P_PlayerThink(player_t *player)
if (player->flashcount)
player->flashcount--;
- // By the time P_MoveChaseCamera is called, this might be zero. Do not do it here.
- //if (player->awayviewtics)
- // player->awayviewtics--;
+ // Re-fixed by Jimita (11-12-2018)
+ if (player->awayviewtics)
+ {
+ player->awayviewtics--;
+ if (!player->awayviewtics)
+ player->awayviewtics = -1;
+ // The timer might've reached zero, but we'll run the remote view camera anyway by setting it to -1.
+ }
/// \note do this in the cheat code
if (player->pflags & PF_NOCLIP)
@@ -9806,8 +9829,8 @@ void P_PlayerAfterThink(player_t *player)
}
}
- if (player->awayviewtics)
- player->awayviewtics--;
+ if (player->awayviewtics < 0)
+ player->awayviewtics = 0;
// spectator invisibility and nogravity.
if ((netgame || multiplayer) && player->spectator)
diff --git a/src/r_bsp.c b/src/r_bsp.c
index a658c3ca..b819735e 100644
--- a/src/r_bsp.c
+++ b/src/r_bsp.c
@@ -403,17 +403,17 @@ static void R_AddLine(seg_t *line)
{
INT32 x1, x2;
angle_t angle1, angle2, span, tspan;
- static sector_t tempsec; // ceiling/water hack
+ static sector_t tempsec;
+
+ portalline = false;
if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES))
return;
+ // big room fix
+ angle1 = R_PointToAngleEx(viewx, viewy, line->v1->x, line->v1->y);
+ angle2 = R_PointToAngleEx(viewx, viewy, line->v2->x, line->v2->y);
curline = line;
- portalline = false;
-
- // OPTIMIZE: quickly reject orthogonal back sides.
- angle1 = R_PointToAngle(line->v1->x, line->v1->y);
- angle2 = R_PointToAngle(line->v2->x, line->v2->y);
// Clip to view edges.
span = angle1 - angle2;
@@ -602,69 +602,35 @@ INT32 checkcoord[12][4] =
{2, 1, 3, 0}
};
-static boolean R_CheckBBox(fixed_t *bspcoord)
+static boolean R_CheckBBox(const fixed_t *bspcoord)
{
- INT32 boxpos, sx1, sx2;
- fixed_t px1, py1, px2, py2;
- angle_t angle1, angle2, span, tspan;
+ angle_t angle1, angle2;
+ INT32 sx1, sx2, boxpos;
+ const INT32* check;
cliprange_t *start;
// Find the corners of the box that define the edges from current viewpoint.
- if (viewx <= bspcoord[BOXLEFT])
- boxpos = 0;
- else if (viewx < bspcoord[BOXRIGHT])
- boxpos = 1;
- else
- boxpos = 2;
-
- if (viewy >= bspcoord[BOXTOP])
- boxpos |= 0;
- else if (viewy > bspcoord[BOXBOTTOM])
- boxpos |= 1<<2;
- else
- boxpos |= 2<<2;
-
- if (boxpos == 5)
+ if ((boxpos = (viewx <= bspcoord[BOXLEFT] ? 0 : viewx < bspcoord[BOXRIGHT] ? 1 : 2) + (viewy >= bspcoord[BOXTOP] ? 0 : viewy > bspcoord[BOXBOTTOM] ? 4 : 8)) == 5)
return true;
- px1 = bspcoord[checkcoord[boxpos][0]];
- py1 = bspcoord[checkcoord[boxpos][1]];
- px2 = bspcoord[checkcoord[boxpos][2]];
- py2 = bspcoord[checkcoord[boxpos][3]];
+ check = checkcoord[boxpos];
- // check clip list for an open space
- angle1 = R_PointToAngle2(viewx>>1, viewy>>1, px1>>1, py1>>1) - viewangle;
- angle2 = R_PointToAngle2(viewx>>1, viewy>>1, px2>>1, py2>>1) - viewangle;
+ // big room fix
+ angle1 = R_PointToAngleEx(viewx, viewy, bspcoord[check[0]], bspcoord[check[1]]) - viewangle;
+ angle2 = R_PointToAngleEx(viewx, viewy, bspcoord[check[2]], bspcoord[check[3]]) - viewangle;
- span = angle1 - angle2;
-
- // Sitting on a line?
- if (span >= ANGLE_180)
- return true;
-
- tspan = angle1 + clipangle;
-
- if (tspan > doubleclipangle)
+ if ((signed)angle1 < (signed)angle2)
{
- tspan -= doubleclipangle;
-
- // Totally off the left edge?
- if (tspan >= span)
- return false;
-
- angle1 = clipangle;
+ if ((angle1 >= ANGLE_180) && (angle1 < ANGLE_270))
+ angle1 = ANGLE_180-1;
+ else
+ angle2 = ANGLE_180;
}
- tspan = clipangle - angle2;
- if (tspan > doubleclipangle)
- {
- tspan -= doubleclipangle;
- // Totally off the left edge?
- if (tspan >= span)
- return false;
-
- angle2 = -(signed)clipangle;
- }
+ if ((signed)angle2 >= (signed)clipangle) return false;
+ if ((signed)angle1 <= -(signed)clipangle) return false;
+ if ((signed)angle1 >= (signed)clipangle) angle1 = clipangle;
+ if ((signed)angle2 <= -(signed)clipangle) angle2 = 0-clipangle;
// Find the first clippost that touches the source post (adjacent pixels are touching).
angle1 = (angle1+ANGLE_90)>>ANGLETOFINESHIFT;
@@ -673,9 +639,7 @@ static boolean R_CheckBBox(fixed_t *bspcoord)
sx2 = viewangletox[angle2];
// Does not cross a pixel.
- if (sx1 == sx2)
- return false;
- sx2--;
+ if (sx1 >= sx2) return false;
start = solidsegs;
while (start->last < sx2)
@@ -1115,7 +1079,6 @@ static void R_Subsector(size_t num, UINT8 viewnumber)
&& (viewz < polysec->floorheight))
{
light = R_GetPlaneLight(frontsector, polysec->floorheight, viewz < polysec->floorheight);
- light = 0;
ffloor[numffloors].plane = R_FindPlane(polysec->floorheight, polysec->floorpic,
polysec->lightlevel, polysec->floor_xoffs, polysec->floor_yoffs,
polysec->floorpic_angle-po->angle,
@@ -1145,7 +1108,6 @@ static void R_Subsector(size_t num, UINT8 viewnumber)
&& (viewz > polysec->ceilingheight))
{
light = R_GetPlaneLight(frontsector, polysec->ceilingheight, viewz < polysec->ceilingheight);
- light = 0;
ffloor[numffloors].plane = R_FindPlane(polysec->ceilingheight, polysec->ceilingpic,
polysec->lightlevel, polysec->ceiling_xoffs, polysec->ceiling_yoffs,
polysec->ceilingpic_angle-po->angle,
diff --git a/src/r_data.c b/src/r_data.c
index b2c10a65..9fc5aaea 100644
--- a/src/r_data.c
+++ b/src/r_data.c
@@ -1285,7 +1285,7 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3)
continue;
if (maskcolor == extra_colormaps[i].maskcolor
&& fadecolor == extra_colormaps[i].fadecolor
- && (float)maskamt == (float)extra_colormaps[i].maskamt
+ && fabs(maskamt - extra_colormaps[i].maskamt) < DBL_EPSILON
&& fadestart == extra_colormaps[i].fadestart
&& fadeend == extra_colormaps[i].fadeend
&& fog == extra_colormaps[i].fog)
diff --git a/src/r_defs.h b/src/r_defs.h
index 967c3908..52a3be80 100644
--- a/src/r_defs.h
+++ b/src/r_defs.h
@@ -573,6 +573,7 @@ typedef struct seg_s
sector_t *frontsector;
sector_t *backsector;
+ fixed_t length; // precalculated seg length
#ifdef HWRENDER
// new pointers so that AdjustSegs doesn't mess with v1/v2
void *pv1; // polyvertex_t
diff --git a/src/r_main.c b/src/r_main.c
index 12e3e03b..8b070e9e 100644
--- a/src/r_main.c
+++ b/src/r_main.c
@@ -408,6 +408,29 @@ fixed_t R_PointToDist(fixed_t x, fixed_t y)
return R_PointToDist2(viewx, viewy, x, y);
}
+angle_t R_PointToAngleEx(INT32 x2, INT32 y2, INT32 x1, INT32 y1)
+{
+ INT64 dx = x1-x2;
+ INT64 dy = y1-y2;
+ if (dx < INT32_MIN || dx > INT32_MAX || dy < INT32_MIN || dy > INT32_MAX)
+ {
+ x1 = (int)(dx / 2 + x2);
+ y1 = (int)(dy / 2 + y2);
+ }
+ return (y1 -= y2, (x1 -= x2) || y1) ?
+ x1 >= 0 ?
+ y1 >= 0 ?
+ (x1 > y1) ? tantoangle[SlopeDivEx(y1,x1)] : // octant 0
+ ANGLE_90-tantoangle[SlopeDivEx(x1,y1)] : // octant 1
+ x1 > (y1 = -y1) ? 0-tantoangle[SlopeDivEx(y1,x1)] : // octant 8
+ ANGLE_270+tantoangle[SlopeDivEx(x1,y1)] : // octant 7
+ y1 >= 0 ? (x1 = -x1) > y1 ? ANGLE_180-tantoangle[SlopeDivEx(y1,x1)] : // octant 3
+ ANGLE_90 + tantoangle[SlopeDivEx(x1,y1)] : // octant 2
+ (x1 = -x1) > (y1 = -y1) ? ANGLE_180+tantoangle[SlopeDivEx(y1,x1)] : // octant 4
+ ANGLE_270-tantoangle[SlopeDivEx(x1,y1)] : // octant 5
+ 0;
+}
+
//
// R_ScaleFromGlobalAngle
// Returns the texture mapping scale for the current line (horizontal span)
@@ -604,13 +627,11 @@ void R_SetViewSize(void)
//
void R_ExecuteSetViewSize(void)
{
- fixed_t cosadj;
fixed_t dy;
INT32 i;
INT32 j;
INT32 level;
INT32 startmapl;
- INT32 aspectx; //added : 02-02-98 : for aspect ratio calc. below...
setsizeneeded = false;
@@ -656,31 +677,22 @@ void R_ExecuteSetViewSize(void)
for (i = 0; i < viewwidth; i++)
screenheightarray[i] = (INT16)viewheight;
- // setup sky scaling (uses pspriteyscale)
+ // setup sky scaling
R_SetSkyScale();
// planes
- //aspectx = (((vid.height*centerx*BASEVIDWIDTH)/BASEVIDHEIGHT)/vid.width);
- aspectx = centerx;
-
if (rendermode == render_soft)
{
// this is only used for planes rendering in software mode
- j = viewheight*8;
+ j = viewheight*16;
for (i = 0; i < j; i++)
{
- dy = ((i - viewheight*2)<>ANGLETOFINESHIFT));
- distscale[i] = FixedDiv(FRACUNIT, cosadj);
- }
-
memset(scalelight, 0xFF, sizeof(scalelight));
// Calculate the light levels to use for each level/scale combination.
@@ -793,9 +805,28 @@ static mobj_t *viewmobj;
// WARNING: a should be unsigned but to add with 2048, it isn't!
#define AIMINGTODY(a) ((FINETANGENT((2048+(((INT32)a)>>ANGLETOFINESHIFT)) & FINEMASK)*160)>>FRACBITS)
-void R_SkyboxFrame(player_t *player)
+// recalc necessary stuff for mouseaiming
+// slopes are already calculated for the full possible view (which is 4*viewheight).
+// 18/08/18: (No it's actually 16*viewheight, thanks Jimita for finding this out)
+static void R_SetupFreelook(void)
{
INT32 dy = 0;
+ if (rendermode == render_soft)
+ {
+ // clip it in the case we are looking a hardware 90 degrees full aiming
+ // (lmps, network and use F12...)
+ G_SoftwareClipAimingPitch((INT32 *)&aimingangle);
+ dy = AIMINGTODY(aimingangle) * viewwidth/BASEVIDWIDTH;
+ yslope = &yslopetab[viewheight*8 - (viewheight/2 + dy)];
+ }
+ centery = (viewheight/2) + dy;
+ centeryfrac = centery< 2 && player == &players[fourthdisplayplayer])
@@ -1022,27 +1053,11 @@ void R_SkyboxFrame(player_t *player)
viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
- // recalc necessary stuff for mouseaiming
- // slopes are already calculated for the full possible view (which is 4*viewheight).
- // 18/08/18: (No it's actually 8*viewheight, thanks MPC aka Jimita for finding this out)
-
- if (rendermode == render_soft)
- {
- // clip it in the case we are looking a hardware 90 degrees full aiming
- // (lmps, network and use F12...)
- G_SoftwareClipAimingPitch((INT32 *)&aimingangle);
-
- dy = AIMINGTODY(aimingangle) * viewwidth/BASEVIDWIDTH;
-
- yslope = &yslopetab[(3*viewheight/2) - dy];
- }
- centery = (viewheight/2) + dy;
- centeryfrac = centery<>ANGLETOFINESHIFT);
viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
- // recalc necessary stuff for mouseaiming
- // slopes are already calculated for the full possible view (which is 4*viewheight).
- // 18/08/18: (No it's actually 8*viewheight, thanks MPC aka Jimita for finding this out)
-
- if (rendermode == render_soft)
- {
- // clip it in the case we are looking a hardware 90 degrees full aiming
- // (lmps, network and use F12...)
- G_SoftwareClipAimingPitch((INT32 *)&aimingangle);
-
- dy = AIMINGTODY(aimingangle) * viewwidth/BASEVIDWIDTH;
-
- yslope = &yslopetab[(3*viewheight/2) - dy];
- }
- centery = (viewheight/2) + dy;
- centeryfrac = centery<= vid.width) x1 = vid.width - 1;
+ angle = (currentplane->viewangle + currentplane->plangle)>>ANGLETOFINESHIFT;
+ planecos = FINECOSINE(angle);
+ planesin = FINESINE(angle);
+
if (planeheight != cachedheight[y])
{
cachedheight[y] = planeheight;
distance = cacheddistance[y] = FixedMul(planeheight, yslope[y]);
ds_xstep = cachedxstep[y] = FixedMul(distance, basexscale);
ds_ystep = cachedystep[y] = FixedMul(distance, baseyscale);
+
+ if ((span = abs(centery-y)))
+ {
+ ds_xstep = cachedxstep[y] = FixedMul(planesin, planeheight) / span;
+ ds_ystep = cachedystep[y] = FixedMul(planecos, planeheight) / span;
+ }
}
else
{
@@ -301,13 +296,8 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2)
ds_ystep = cachedystep[y];
}
- length = FixedMul (distance,distscale[x1]);
- angle = (currentplane->viewangle + currentplane->plangle + xtoviewangle[x1])>>ANGLETOFINESHIFT;
- /// \note Wouldn't it be faster just to add viewx and viewy
- // to the plane's x/yoffs anyway??
-
- ds_xfrac = FixedMul(FINECOSINE(angle), length) + xoffs;
- ds_yfrac = yoffs - FixedMul(FINESINE(angle), length);
+ ds_xfrac = xoffs + FixedMul(planecos, distance) + (x1 - centerx) * ds_xstep;
+ ds_yfrac = yoffs - FixedMul(planesin, distance) + (x1 - centerx) * ds_ystep;
#ifndef NOWATER
if (itswater)
@@ -315,8 +305,9 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2)
const INT32 yay = (wtofs + (distance>>9) ) & 8191;
// ripples da water texture
bgofs = FixedDiv(FINESINE(yay), (1<<12) + (distance>>11))>>FRACBITS;
+ angle = (currentplane->viewangle + currentplane->plangle + xtoviewangle[x1])>>ANGLETOFINESHIFT;
- angle = (angle + 2048) & 8191; //90�
+ angle = (angle + 2048) & 8191; // 90 degrees
ds_xfrac += FixedMul(FINECOSINE(angle), (bgofs<> LIGHTZSHIFT;
-
if (pindex >= MAXLIGHTZ)
pindex = MAXLIGHTZ - 1;
@@ -367,8 +357,6 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2)
// R_ClearPlanes
// At begining of frame.
//
-// NOTE: Uses con_clipviewtop, so that when console is on,
-// we don't draw the part of the view hidden under the console.
void R_ClearPlanes(void)
{
INT32 i, p;
@@ -378,12 +366,12 @@ void R_ClearPlanes(void)
for (i = 0; i < viewwidth; i++)
{
floorclip[i] = (INT16)viewheight;
- ceilingclip[i] = (INT16)con_clipviewtop;
+ ceilingclip[i] = -1;
frontscale[i] = INT32_MAX;
for (p = 0; p < MAXFFLOORS; p++)
{
ffloor[p].f_clip[i] = (INT16)viewheight;
- ffloor[p].c_clip[i] = (INT16)con_clipviewtop;
+ ffloor[p].c_clip[i] = -1;
}
}
diff --git a/src/r_plane.h b/src/r_plane.h
index aeaf2185..8f5a6073 100644
--- a/src/r_plane.h
+++ b/src/r_plane.h
@@ -21,7 +21,6 @@
//
// Now what is a visplane, anyway?
// Simple: kinda floor/ceiling polygon optimised for SRB2 rendering.
-// 7764 bytes! (for win32, anyway)
//
typedef struct visplane_s
{
@@ -39,25 +38,12 @@ typedef struct visplane_s
extracolormap_t *extra_colormap;
// leave pads for [minx-1]/[maxx+1]
-
- // words sucks .. should get rid of that.. but eats memory
- // THIS IS UNSIGNED! VERY IMPORTANT!!
- UINT16 pad1;
- UINT16 top[MAXVIDWIDTH];
- UINT16 pad2;
- UINT16 pad3;
- UINT16 bottom[MAXVIDWIDTH];
- UINT16 pad4;
-
+ UINT16 padtopstart, top[MAXVIDWIDTH], padtopend;
+ UINT16 padbottomstart, bottom[MAXVIDWIDTH], padbottomend;
INT32 high, low; // R_PlaneBounds should set these.
fixed_t xoffs, yoffs; // Scrolling flats.
- // SoM: frontscale should be stored in the first seg of the subsector
- // where the planes themselves are stored. I'm doing this now because
- // the old way caused trouble with the drawseg array was re-sized.
- INT32 scaleseg;
-
struct ffloor_s *ffloor;
#ifdef POLYOBJECTS_PLANES
polyobj_t *polyobj;
@@ -77,17 +63,15 @@ extern INT16 *lastopening, *openings;
extern size_t maxopenings;
extern INT16 floorclip[MAXVIDWIDTH], ceilingclip[MAXVIDWIDTH];
-extern fixed_t frontscale[MAXVIDWIDTH], yslopetab[MAXVIDHEIGHT*8];
+extern fixed_t frontscale[MAXVIDWIDTH], yslopetab[MAXVIDHEIGHT*16];
extern fixed_t cachedheight[MAXVIDHEIGHT];
extern fixed_t cacheddistance[MAXVIDHEIGHT];
extern fixed_t cachedxstep[MAXVIDHEIGHT];
extern fixed_t cachedystep[MAXVIDHEIGHT];
extern fixed_t basexscale, baseyscale;
-extern lighttable_t **planezlight;
-
extern fixed_t *yslope;
-extern fixed_t distscale[MAXVIDWIDTH];
+extern lighttable_t **planezlight;
void R_InitPlanes(void);
void R_PortalStoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale);
@@ -136,8 +120,8 @@ typedef struct planemgr_s
#ifdef POLYOBJECTS_PLANES
polyobj_t *polyobj;
#endif
-} planemgr_t;
+} visffloor_t;
-extern planemgr_t ffloor[MAXFFLOORS];
+extern visffloor_t ffloor[MAXFFLOORS];
extern INT32 numffloors;
#endif
diff --git a/src/r_segs.c b/src/r_segs.c
index 80ee6194..59abea3a 100644
--- a/src/r_segs.c
+++ b/src/r_segs.c
@@ -1363,24 +1363,12 @@ static void R_RenderSegLoop (void)
if (markfloor)
{
-#if 0 // Old Doom Legacy code
- bottom = floorclip[rw_x]-1;
- if (top <= ceilingclip[rw_x])
- top = ceilingclip[rw_x]+1;
- if (top <= bottom && floorplane)
- {
- floorplane->top[rw_x] = (INT16)top;
- floorplane->bottom[rw_x] = (INT16)bottom;
- }
-#else // Spiffy new PRBoom code
- top = yh < ceilingclip[rw_x] ? ceilingclip[rw_x] : yh;
-
+ top = yh < ceilingclip[rw_x] ? ceilingclip[rw_x] : yh;
if (++top <= bottom && floorplane)
{
floorplane->top[rw_x] = (INT16)top;
floorplane->bottom[rw_x] = (INT16)bottom;
}
-#endif
}
if (numffloors)
@@ -1666,26 +1654,11 @@ static void R_RenderSegLoop (void)
}
for (i = 0; i < numffloors; i++)
- {
-#ifdef POLYOBJECTS_PLANES
- if (ffloor[i].polyobj && (!curline->polyseg || ffloor[i].polyobj != curline->polyseg))
- continue;
-#endif
-
ffloor[i].f_frac += ffloor[i].f_step;
- }
for (i = 0; i < numbackffloors; i++)
{
- INT32 y_w;
-
-#ifdef POLYOBJECTS_PLANES
- if (ffloor[i].polyobj && (!curline->polyseg || ffloor[i].polyobj != curline->polyseg))
- continue;
-#endif
- y_w = ffloor[i].b_frac >> HEIGHTBITS;
-
- ffloor[i].f_clip[rw_x] = ffloor[i].c_clip[rw_x] = (INT16)(y_w & 0xFFFF);
+ ffloor[i].f_clip[rw_x] = ffloor[i].c_clip[rw_x] = (INT16)((ffloor[i].b_frac >> HEIGHTBITS) & 0xFFFF);
ffloor[i].b_frac += ffloor[i].b_step;
}
@@ -1695,6 +1668,23 @@ static void R_RenderSegLoop (void)
}
}
+// Uses precalculated seg->length
+static INT64 R_CalcSegDist(seg_t* seg, INT64 x2, INT64 y2)
+{
+ if (!seg->linedef->dy)
+ return llabs(y2 - seg->v1->y);
+ else if (!seg->linedef->dx)
+ return llabs(x2 - seg->v1->x);
+ else
+ {
+ INT64 dx = (seg->v2->x)-(seg->v1->x);
+ INT64 dy = (seg->v2->y)-(seg->v1->y);
+ INT64 vdx = x2-(seg->v1->x);
+ INT64 vdy = y2-(seg->v1->y);
+ return ((dy*vdx)-(dx*vdy))/(seg->length);
+ }
+}
+
//
// R_StoreWallRange
// A wall segment will be drawn
@@ -1705,6 +1695,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
fixed_t hyp;
fixed_t sineval;
angle_t distangle, offsetangle;
+ boolean longboi;
#ifndef ESLOPE
fixed_t vtop;
#endif
@@ -1750,10 +1741,15 @@ void R_StoreWallRange(INT32 start, INT32 stop)
offsetangle = ANGLE_90;
distangle = ANGLE_90 - offsetangle;
- hyp = R_PointToDist (curline->v1->x, curline->v1->y);
sineval = FINESINE(distangle>>ANGLETOFINESHIFT);
- rw_distance = FixedMul (hyp, sineval);
+ hyp = R_PointToDist(curline->v1->x, curline->v1->y);
+ rw_distance = FixedMul(hyp, sineval);
+ longboi = (hyp >= INT32_MAX);
+
+ // big room fix
+ if (longboi)
+ rw_distance = (fixed_t)R_CalcSegDist(curline,viewx,viewy);
ds_p->x1 = rw_x = start;
ds_p->x2 = stop;
@@ -2613,8 +2609,18 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (offsetangle > ANGLE_90)
offsetangle = ANGLE_90;
- sineval = FINESINE(offsetangle >>ANGLETOFINESHIFT);
- rw_offset = FixedMul (hyp, sineval);
+ sineval = FINESINE(offsetangle>>ANGLETOFINESHIFT);
+ rw_offset = FixedMul(hyp, sineval);
+
+ // big room fix
+ if (longboi)
+ {
+ INT64 dx = (curline->v2->x)-(curline->v1->x);
+ INT64 dy = (curline->v2->y)-(curline->v1->y);
+ INT64 vdx = viewx-(curline->v1->x);
+ INT64 vdy = viewy-(curline->v1->y);
+ rw_offset = ((dx*vdx-dy*vdy))/(curline->length);
+ }
if (rw_normalangle-rw_angle1 < ANGLE_180)
rw_offset = -rw_offset;
@@ -2805,11 +2811,6 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{
for (i = 0; i < numffloors; i++)
{
-#ifdef POLYOBJECTS_PLANES
- if (ffloor[i].polyobj && (!curline->polyseg || ffloor[i].polyobj != curline->polyseg))
- continue;
-#endif
-
ffloor[i].f_pos >>= 4;
#ifdef ESLOPE
ffloor[i].f_pos_slope >>= 4;
@@ -3090,7 +3091,11 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (ceilingplane) //SoM: 3/29/2000: Check for null ceiling planes
ceilingplane = R_CheckPlane (ceilingplane, rw_x, rw_stopx-1);
else
- markceiling = 0;
+ markceiling = false;
+
+ // Don't render the ceiling again when rendering polyobjects
+ if (curline->polyseg)
+ markceiling = false;
}
// get a new or use the same visplane
@@ -3099,7 +3104,11 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (floorplane) //SoM: 3/29/2000: Check for null planes
floorplane = R_CheckPlane (floorplane, rw_x, rw_stopx-1);
else
- markfloor = 0;
+ markfloor = false;
+
+ // Don't render the floor again when rendering polyobjects
+ if (curline->polyseg)
+ markfloor = false;
}
ds_p->numffloorplanes = 0;
diff --git a/src/r_splats.c b/src/r_splats.c
index 8d0a84fa..9ab67127 100644
--- a/src/r_splats.c
+++ b/src/r_splats.c
@@ -365,9 +365,8 @@ static void R_RenderFloorSplat(floorsplat_t *pSplat, vertex_t *verts, UINT8 *pTe
#else
lighttable_t **planezlight;
fixed_t planeheight;
- angle_t angle;
- fixed_t distance;
- fixed_t length;
+ angle_t angle, planecos, planesin;
+ fixed_t distance, span;
size_t indexr;
INT32 light;
#endif
@@ -473,12 +472,22 @@ static void R_RenderFloorSplat(floorsplat_t *pSplat, vertex_t *verts, UINT8 *pTe
if (x2 >= vid.width)
x2 = vid.width - 1;
+ angle = (currentplane->viewangle + currentplane->plangle)>>ANGLETOFINESHIFT;
+ planecos = FINECOSINE(angle);
+ planesin = FINESINE(angle);
+
if (planeheight != cachedheight[y])
{
cachedheight[y] = planeheight;
distance = cacheddistance[y] = FixedMul(planeheight, yslope[y]);
ds_xstep = cachedxstep[y] = FixedMul(distance,basexscale);
ds_ystep = cachedystep[y] = FixedMul(distance,baseyscale);
+
+ if ((span = abs(centery-y)))
+ {
+ ds_xstep = cachedxstep[y] = FixedMul(planesin, planeheight) / span;
+ ds_ystep = cachedystep[y] = FixedMul(planecos, planeheight) / span;
+ }
}
else
{
@@ -486,10 +495,9 @@ static void R_RenderFloorSplat(floorsplat_t *pSplat, vertex_t *verts, UINT8 *pTe
ds_xstep = cachedxstep[y];
ds_ystep = cachedystep[y];
}
- length = FixedMul(distance, distscale[x1]);
- angle = (viewangle + xtoviewangle[x1])>>ANGLETOFINESHIFT;
- ds_xfrac = viewx + FixedMul(FINECOSINE(angle), length);
- ds_yfrac = -viewy - FixedMul(FINESINE(angle), length);
+
+ ds_xfrac = xoffs + FixedMul(planecos, distance) + (x1 - centerx) * ds_xstep;
+ ds_yfrac = yoffs - FixedMul(planesin, distance) + (x1 - centerx) * ds_ystep;
ds_xfrac -= offsetx;
ds_yfrac += offsety;
diff --git a/src/r_things.c b/src/r_things.c
index 9abbdd12..1825d2d9 100644
--- a/src/r_things.c
+++ b/src/r_things.c
@@ -1927,7 +1927,7 @@ static void R_CreateDrawNodes(void)
plane = ds->curline->polyseg->visplane;
R_PlaneBounds(plane);
- if (plane->low < con_clipviewtop || plane->high > vid.height || plane->high > plane->low)
+ if (plane->low < 0 || plane->high > vid.height || plane->high > plane->low)
;
else {
// Put it in!
@@ -1956,7 +1956,7 @@ static void R_CreateDrawNodes(void)
plane = ds->ffloorplanes[p];
R_PlaneBounds(plane);
- if (plane->low < con_clipviewtop || plane->high > vid.height || plane->high > plane->low || plane->polyobj)
+ if (plane->low < 0 || plane->high > vid.height || plane->high > plane->low || plane->polyobj)
{
ds->ffloorplanes[p] = NULL;
continue;
@@ -1993,7 +1993,7 @@ static void R_CreateDrawNodes(void)
plane = PolyObjects[i].visplane;
R_PlaneBounds(plane);
- if (plane->low < con_clipviewtop || plane->high > vid.height || plane->high > plane->low)
+ if (plane->low < 0 || plane->high > vid.height || plane->high > plane->low)
{
PolyObjects[i].visplane = NULL;
continue;
diff --git a/src/r_things.h b/src/r_things.h
index b3c7656d..a8635034 100644
--- a/src/r_things.h
+++ b/src/r_things.h
@@ -231,6 +231,7 @@ FUNCMATH FUNCINLINE static ATTRINLINE char R_Frame2Char(UINT8 frame)
FUNCMATH FUNCINLINE static ATTRINLINE UINT8 R_Char2Frame(char cn)
{
#if 1 // 2.1 compat
+ if (cn == '+') return '\\' - 'A'; // PK3 can't use backslash, so use + instead
return cn - 'A';
#else
if (cn >= 'A' && cn <= 'Z') return cn - 'A';
diff --git a/src/s_sound.c b/src/s_sound.c
index 8b5d29ed..34163fd3 100644
--- a/src/s_sound.c
+++ b/src/s_sound.c
@@ -1218,7 +1218,7 @@ fixed_t S_CalculateSoundDistance(fixed_t sx1, fixed_t sy1, fixed_t sz1, fixed_t
approx_dist <<= FRACBITS;
- return FixedDiv(approx_dist, mapheaderinfo[gamemap-1]->mobj_scale); // approx_dist
+ return FixedDiv(approx_dist, mapobjectscale); // approx_dist
}
//
diff --git a/src/screen.c b/src/screen.c
index d5beaf36..af6aed03 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -309,14 +309,6 @@ void SCR_Recalc(void)
if (automapactive)
AM_Stop();
- // r_plane stuff: visplanes, openings, floorclip, ceilingclip, spanstart,
- // spanstop, yslope, distscale, cachedheight, cacheddistance,
- // cachedxstep, cachedystep
- // -> allocated at the maximum vidsize, static.
-
- // r_main: xtoviewangle, allocated at the maximum size.
- // r_things: negonearray, screenheightarray allocated max. size.
-
// set the screen[x] ptrs on the new vidbuffers
V_Init();
diff --git a/src/sdl/CMakeLists.txt b/src/sdl/CMakeLists.txt
index a3626970..f7b7c7ba 100644
--- a/src/sdl/CMakeLists.txt
+++ b/src/sdl/CMakeLists.txt
@@ -278,13 +278,13 @@ if(${SDL2_FOUND})
if (${CMAKE_GENERATOR} STREQUAL "MinGW Makefiles")
if(${SRB2_SYSTEM_BITS} EQUAL 64)
find_library(SRB2_SDL2_DLL_${dllname} "${defaultname}"
- HINTS ${CMAKE_SOURCE_DIR}/Bin/Resources/x86_64
+ HINTS ${CMAKE_SOURCE_DIR}/libs/dll-binaries/x86_64
HINTS ${CMAKE_SOURCE_DIR}/libs/SDL2/x86_64-w64-mingw32/bin
HINTS ${CMAKE_SOURCE_DIR}/libs/SDL2_mixer/x86_64-w64-mingw32/bin
)
else()
find_library(SRB2_SDL2_DLL_${dllname} "${defaultname}"
- HINTS ${CMAKE_SOURCE_DIR}/Bin/Resources/i686
+ HINTS ${CMAKE_SOURCE_DIR}/libs/dll-binaries/i686
HINTS ${CMAKE_SOURCE_DIR}/libs/SDL2/i686-w64-mingw32/bin
HINTS ${CMAKE_SOURCE_DIR}/libs/SDL2_mixer/i686-w64-mingw32/bin
)
@@ -292,13 +292,13 @@ if(${SDL2_FOUND})
else()
if(${SRB2_SYSTEM_BITS} EQUAL 64)
find_library(SRB2_SDL2_DLL_${dllname} "${defaultname}"
- HINTS ${CMAKE_SOURCE_DIR}/Bin/Resources/x86_64
+ HINTS ${CMAKE_SOURCE_DIR}/libs/dll-binaries/x86_64
HINTS ${CMAKE_SOURCE_DIR}/libs/SDL2/lib/x64
HINTS ${CMAKE_SOURCE_DIR}/libs/SDL2_mixer/lib/x64
)
else()
find_library(SRB2_SDL2_DLL_${dllname} "${defaultname}"
- HINTS ${CMAKE_SOURCE_DIR}/Bin/Resources/i686
+ HINTS ${CMAKE_SOURCE_DIR}/libs/dll-binaries/i686
HINTS ${CMAKE_SOURCE_DIR}/libs/SDL2/lib/x86
HINTS ${CMAKE_SOURCE_DIR}/libs/SDL2_mixer/lib/x86
)
diff --git a/src/sdl/Srb2SDL-vc10.vcxproj b/src/sdl/Srb2SDL-vc10.vcxproj
index df582865..bd964259 100644
--- a/src/sdl/Srb2SDL-vc10.vcxproj
+++ b/src/sdl/Srb2SDL-vc10.vcxproj
@@ -1,10 +1,26 @@
+
+ Debug
+ ARM
+
+
+ Debug
+ ARM64
+
Debug
Win32
+
+ Release
+ ARM
+
+
+ Release
+ ARM64
+
Release
Win32
@@ -19,31 +35,54 @@
- Srb2Win
+ srb2kart
{61BA7D3C-F77D-4D31-B718-1177FE482CF2}
Win32Proj
Srb2SDL
+ 10.0.16299.0
srb2kart
- 8.1
-
- v140
-
+ v140
true
+
+ v141
+ true
+ true
+
+ v140
false
true
+
+ v141
+ false
+ true
+ true
+
+ v140
true
+
+ v141
+ true
+ true
+
+ v140
false
true
+
+ v141
+ false
+ true
+ true
+
@@ -60,27 +99,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<_ProjectFileVersion>10.0.30319.1
false
-
+
- false
+ ProgramDatabase
+ false
+
+ setupapi.lib;winmm.lib;imm32.lib;version.lib;ole32.lib;advapi32.lib;shell32.lib;gdi32.lib;oleaut32.lib;uuid.lib;%(AdditionalDependencies)
+
+
+
+
+ ProgramDatabase
+ false
+
+
+
+
+ setupapi.lib;winmm.lib;imm32.lib;version.lib;ole32.lib;advapi32.lib;shell32.lib;gdi32.lib;oleaut32.lib;uuid.lib;%(AdditionalDependencies)
+
@@ -304,7 +374,7 @@
-
+
diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c
index bfd89728..f8517618 100644
--- a/src/sdl/i_system.c
+++ b/src/sdl/i_system.c
@@ -856,6 +856,220 @@ void I_JoyScale4(void)
JoyInfo4.scale = Joystick4.bGamepadStyle?1:cv_joyscale4.value;
}
+// Cheat to get the device index for a joystick handle
+INT32 I_GetJoystickDeviceIndex(SDL_Joystick *dev)
+{
+ INT32 i, count = SDL_NumJoysticks();
+
+ for (i = 0; dev && i < count; i++)
+ {
+ SDL_Joystick *test = SDL_JoystickOpen(i);
+ if (test && test == dev)
+ return i;
+ else if (JoyInfo.dev != test && JoyInfo2.dev != test && JoyInfo3.dev != test && JoyInfo4.dev != test)
+ SDL_JoystickClose(test);
+ }
+
+ return -1;
+}
+
+// Misleading function: updates device indices for all players BUT the one specified.
+// Necessary for SDL_JOYDEVICEADDED events
+void I_UpdateJoystickDeviceIndices(INT32 player)
+{
+ if (player != 1) // This is a fucking mess.
+ {
+ //////////////////////////////
+ // update joystick 1's device index
+ //////////////////////////////
+
+ if (JoyInfo.dev)
+ cv_usejoystick.value = I_GetJoystickDeviceIndex(JoyInfo.dev) + 1;
+ // is cv_usejoystick used?
+ else if (// don't check JoyInfo or cv_usejoystick; we're currently operating on those
+ atoi(cv_usejoystick.string) != JoyInfo2.oldjoy
+ && atoi(cv_usejoystick.string) != cv_usejoystick2.value
+ && atoi(cv_usejoystick.string) != JoyInfo3.oldjoy
+ && atoi(cv_usejoystick.string) != cv_usejoystick3.value
+ && atoi(cv_usejoystick.string) != JoyInfo4.oldjoy
+ && atoi(cv_usejoystick.string) != cv_usejoystick4.value)
+ cv_usejoystick.value = atoi(cv_usejoystick.string);
+ // is cv_usejoystick2 used?
+ else if ( // don't check JoyInfo or cv_usejoystick; we're currently operating on those
+ atoi(cv_usejoystick2.string) != JoyInfo2.oldjoy
+ && atoi(cv_usejoystick2.string) != cv_usejoystick2.value
+ && atoi(cv_usejoystick2.string) != JoyInfo3.oldjoy
+ && atoi(cv_usejoystick2.string) != cv_usejoystick3.value
+ && atoi(cv_usejoystick2.string) != JoyInfo4.oldjoy
+ && atoi(cv_usejoystick2.string) != cv_usejoystick4.value)
+ cv_usejoystick.value = atoi(cv_usejoystick2.string);
+ // is cv_usejoystick3 used?
+ else if (// don't check JoyInfo or cv_usejoystick; we're currently operating on those
+ atoi(cv_usejoystick3.string) != JoyInfo2.oldjoy
+ && atoi(cv_usejoystick3.string) != cv_usejoystick2.value
+ && atoi(cv_usejoystick3.string) != JoyInfo3.oldjoy
+ && atoi(cv_usejoystick3.string) != cv_usejoystick3.value
+ && atoi(cv_usejoystick3.string) != JoyInfo4.oldjoy
+ && atoi(cv_usejoystick3.string) != cv_usejoystick4.value)
+ cv_usejoystick.value = atoi(cv_usejoystick3.string);
+ // is cv_usejoystick4 used?
+ else if (// don't check JoyInfo or cv_usejoystick; we're currently operating on those
+ atoi(cv_usejoystick4.string) != JoyInfo2.oldjoy
+ && atoi(cv_usejoystick4.string) != cv_usejoystick2.value
+ && atoi(cv_usejoystick4.string) != JoyInfo3.oldjoy
+ && atoi(cv_usejoystick4.string) != cv_usejoystick3.value
+ && atoi(cv_usejoystick4.string) != JoyInfo4.oldjoy
+ && atoi(cv_usejoystick4.string) != cv_usejoystick4.value)
+ cv_usejoystick.value = atoi(cv_usejoystick4.string);
+ else // we tried...
+ cv_usejoystick.value = 0;
+ }
+
+ if (player != 2)
+ {
+ //////////////////////////////
+ // update joystick 2's device index
+ //////////////////////////////
+
+ if (JoyInfo2.dev)
+ cv_usejoystick2.value = I_GetJoystickDeviceIndex(JoyInfo2.dev) + 1;
+ // is cv_usejoystick2 used?
+ else if (atoi(cv_usejoystick2.string) != JoyInfo.oldjoy
+ && atoi(cv_usejoystick2.string) != cv_usejoystick.value
+ // don't check JoyInfo2 or cv_usejoystick2; we're currently operating on those
+ && atoi(cv_usejoystick2.string) != JoyInfo3.oldjoy
+ && atoi(cv_usejoystick2.string) != cv_usejoystick3.value
+ && atoi(cv_usejoystick2.string) != JoyInfo4.oldjoy
+ && atoi(cv_usejoystick2.string) != cv_usejoystick4.value)
+ cv_usejoystick2.value = atoi(cv_usejoystick2.string);
+ // is cv_usejoystick used?
+ else if (atoi(cv_usejoystick.string) != JoyInfo.oldjoy
+ && atoi(cv_usejoystick.string) != cv_usejoystick.value
+ // don't check JoyInfo2 or cv_usejoystick2; we're currently operating on those
+ && atoi(cv_usejoystick.string) != JoyInfo3.oldjoy
+ && atoi(cv_usejoystick.string) != cv_usejoystick3.value
+ && atoi(cv_usejoystick.string) != JoyInfo4.oldjoy
+ && atoi(cv_usejoystick.string) != cv_usejoystick4.value)
+ cv_usejoystick2.value = atoi(cv_usejoystick.string);
+ // is cv_usejoystick3 used?
+ else if (atoi(cv_usejoystick3.string) != JoyInfo.oldjoy
+ && atoi(cv_usejoystick3.string) != cv_usejoystick.value
+ // don't check JoyInfo2 or cv_usejoystick2; we're currently operating on those
+ && atoi(cv_usejoystick3.string) != JoyInfo3.oldjoy
+ && atoi(cv_usejoystick3.string) != cv_usejoystick3.value
+ && atoi(cv_usejoystick3.string) != JoyInfo4.oldjoy
+ && atoi(cv_usejoystick3.string) != cv_usejoystick4.value)
+ cv_usejoystick2.value = atoi(cv_usejoystick3.string);
+ // is cv_usejoystick4 used?
+ else if (atoi(cv_usejoystick4.string) != JoyInfo.oldjoy
+ && atoi(cv_usejoystick4.string) != cv_usejoystick.value
+ // don't check JoyInfo2 or cv_usejoystick2; we're currently operating on those
+ && atoi(cv_usejoystick4.string) != JoyInfo3.oldjoy
+ && atoi(cv_usejoystick4.string) != cv_usejoystick3.value
+ && atoi(cv_usejoystick4.string) != JoyInfo4.oldjoy
+ && atoi(cv_usejoystick4.string) != cv_usejoystick4.value)
+ cv_usejoystick2.value = atoi(cv_usejoystick4.string);
+ else // we tried...
+ cv_usejoystick2.value = 0;
+ }
+
+ if (player != 3)
+ {
+ //////////////////////////////
+ // update joystick 3's device index
+ //////////////////////////////
+
+ if (JoyInfo3.dev)
+ cv_usejoystick3.value = I_GetJoystickDeviceIndex(JoyInfo3.dev) + 1;
+ // is cv_usejoystick3 used?
+ else if (atoi(cv_usejoystick3.string) != JoyInfo.oldjoy
+ && atoi(cv_usejoystick3.string) != cv_usejoystick.value
+ && atoi(cv_usejoystick3.string) != JoyInfo2.oldjoy
+ && atoi(cv_usejoystick3.string) != cv_usejoystick2.value
+ // don't check JoyInfo3 or cv_usejoystick3; we're currently operating on those
+ && atoi(cv_usejoystick3.string) != JoyInfo4.oldjoy
+ && atoi(cv_usejoystick3.string) != cv_usejoystick4.value)
+ cv_usejoystick3.value = atoi(cv_usejoystick3.string);
+ // is cv_usejoystick used?
+ else if (atoi(cv_usejoystick.string) != JoyInfo.oldjoy
+ && atoi(cv_usejoystick.string) != cv_usejoystick.value
+ && atoi(cv_usejoystick.string) != JoyInfo2.oldjoy
+ && atoi(cv_usejoystick.string) != cv_usejoystick2.value
+ // don't check JoyInfo3 or cv_usejoystick3; we're currently operating on those
+ && atoi(cv_usejoystick.string) != JoyInfo4.oldjoy
+ && atoi(cv_usejoystick.string) != cv_usejoystick4.value)
+ cv_usejoystick3.value = atoi(cv_usejoystick.string);
+ // is cv_usejoystick2 used?
+ else if (atoi(cv_usejoystick2.string) != JoyInfo.oldjoy
+ && atoi(cv_usejoystick2.string) != cv_usejoystick.value
+ && atoi(cv_usejoystick2.string) != JoyInfo2.oldjoy
+ && atoi(cv_usejoystick2.string) != cv_usejoystick2.value
+ // don't check JoyInfo3 or cv_usejoystick3; we're currently operating on those
+ && atoi(cv_usejoystick2.string) != JoyInfo4.oldjoy
+ && atoi(cv_usejoystick2.string) != cv_usejoystick4.value)
+ cv_usejoystick3.value = atoi(cv_usejoystick2.string);
+ // is cv_usejoystick4 used?
+ else if (atoi(cv_usejoystick4.string) != JoyInfo.oldjoy
+ && atoi(cv_usejoystick4.string) != cv_usejoystick.value
+ && atoi(cv_usejoystick4.string) != JoyInfo2.oldjoy
+ && atoi(cv_usejoystick4.string) != cv_usejoystick2.value
+ // don't check JoyInfo3 or cv_usejoystick3; we're currently operating on those
+ && atoi(cv_usejoystick4.string) != JoyInfo4.oldjoy
+ && atoi(cv_usejoystick4.string) != cv_usejoystick4.value)
+ cv_usejoystick3.value = atoi(cv_usejoystick4.string);
+ else // we tried...
+ cv_usejoystick3.value = 0;
+ }
+
+ if (player != 4)
+ {
+ //////////////////////////////
+ // update joystick 4's device index
+ //////////////////////////////
+
+ if (JoyInfo4.dev)
+ cv_usejoystick4.value = I_GetJoystickDeviceIndex(JoyInfo4.dev) + 1;
+ // is cv_usejoystick4 used?
+ else if (atoi(cv_usejoystick4.string) != JoyInfo.oldjoy
+ && atoi(cv_usejoystick4.string) != cv_usejoystick.value
+ && atoi(cv_usejoystick4.string) != JoyInfo2.oldjoy
+ && atoi(cv_usejoystick4.string) != cv_usejoystick2.value
+ && atoi(cv_usejoystick4.string) != JoyInfo3.oldjoy
+ && atoi(cv_usejoystick4.string) != cv_usejoystick3.value)
+ // don't check JoyInfo4 or cv_usejoystick4; we're currently operating on those
+ cv_usejoystick4.value = atoi(cv_usejoystick4.string);
+ // is cv_usejoystick used?
+ else if (atoi(cv_usejoystick.string) != JoyInfo.oldjoy
+ && atoi(cv_usejoystick.string) != cv_usejoystick.value
+ && atoi(cv_usejoystick.string) != JoyInfo2.oldjoy
+ && atoi(cv_usejoystick.string) != cv_usejoystick2.value
+ && atoi(cv_usejoystick.string) != JoyInfo3.oldjoy
+ && atoi(cv_usejoystick.string) != cv_usejoystick3.value)
+ // don't check JoyInfo4 or cv_usejoystick4; we're currently operating on those
+ cv_usejoystick4.value = atoi(cv_usejoystick.string);
+ // is cv_usejoystick2 used?
+ else if (atoi(cv_usejoystick2.string) != JoyInfo.oldjoy
+ && atoi(cv_usejoystick2.string) != cv_usejoystick.value
+ && atoi(cv_usejoystick2.string) != JoyInfo2.oldjoy
+ && atoi(cv_usejoystick2.string) != cv_usejoystick2.value
+ && atoi(cv_usejoystick2.string) != JoyInfo3.oldjoy
+ && atoi(cv_usejoystick2.string) != cv_usejoystick3.value)
+ // don't check JoyInfo4 or cv_usejoystick4; we're currently operating on those
+ cv_usejoystick4.value = atoi(cv_usejoystick2.string);
+ // is cv_usejoystick3 used?
+ else if (atoi(cv_usejoystick3.string) != JoyInfo.oldjoy
+ && atoi(cv_usejoystick3.string) != cv_usejoystick.value
+ && atoi(cv_usejoystick3.string) != JoyInfo2.oldjoy
+ && atoi(cv_usejoystick3.string) != cv_usejoystick2.value
+ && atoi(cv_usejoystick3.string) != JoyInfo3.oldjoy
+ && atoi(cv_usejoystick3.string) != cv_usejoystick3.value)
+ // don't check JoyInfo4 or cv_usejoystick4; we're currently operating on those
+ cv_usejoystick4.value = atoi(cv_usejoystick3.string);
+ else // we tried...
+ cv_usejoystick4.value = 0;
+ }
+}
+
/** \brief Joystick 1 buttons states
*/
static UINT64 lastjoybuttons = 0;
@@ -871,7 +1085,7 @@ static UINT64 lastjoyhats = 0;
*/
-static void I_ShutdownJoystick(void)
+void I_ShutdownJoystick(void)
{
INT32 i;
event_t event;
@@ -905,15 +1119,8 @@ static void I_ShutdownJoystick(void)
joystick_started = 0;
JoyReset(&JoyInfo);
- if (!joystick_started && !joystick2_started && !joystick3_started && !joystick4_started
- && SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
- {
- SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
- if (cv_usejoystick.value == 0)
- {
- I_OutputMsg("I_Joystick: SDL's Joystick system has been shutdown\n");
- }
- }
+
+ // don't shut down the subsystem here, because hotplugging
}
void I_GetJoystickEvents(void)
@@ -1054,74 +1261,66 @@ void I_GetJoystickEvents(void)
*/
-static int joy_open(const char *fname)
+static int joy_open(int joyindex)
{
- int joyindex = atoi(fname);
+ SDL_Joystick *newdev = NULL;
int num_joy = 0;
- int i;
- if (joystick_started == 0 && joystick2_started == 0 && joystick3_started == 0 && joystick4_started == 0)
+ if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
{
- if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1)
- {
- CONS_Printf(M_GetText("Couldn't initialize joystick: %s\n"), SDL_GetError());
- return -1;
- }
- else
- {
- num_joy = SDL_NumJoysticks();
- }
+ CONS_Printf(M_GetText("Joystick subsystem not started\n"));
+ return -1;
+ }
- if (num_joy < joyindex)
- {
- CONS_Printf(M_GetText("Cannot use joystick #%d/(%s), it doesn't exist\n"),joyindex,fname);
- for (i = 0; i < num_joy; i++)
- CONS_Printf("#%d/(%s)\n", i+1, SDL_JoystickNameForIndex(i));
- I_ShutdownJoystick();
- return -1;
- }
- }
- else
- {
- JoyReset(&JoyInfo);
- //I_ShutdownJoystick();
- //joy_open(fname);
- }
+ if (joyindex <= 0)
+ return -1;
num_joy = SDL_NumJoysticks();
- if (joyindex <= 0 || num_joy == 0 || JoyInfo.oldjoy == joyindex)
+ if (num_joy == 0)
{
-// I_OutputMsg("Unable to use that joystick #(%s), non-number\n",fname);
- if (num_joy != 0)
- {
- CONS_Printf(M_GetText("Found %d joysticks on this system\n"), num_joy);
- for (i = 0; i < num_joy; i++)
- CONS_Printf("#%d/(%s)\n", i+1, SDL_JoystickNameForIndex(i));
- }
- else
- CONS_Printf("%s", M_GetText("Found no joysticks on this system\n"));
- if (joyindex <= 0 || num_joy == 0) return 0;
+ CONS_Printf("%s", M_GetText("Found no joysticks on this system\n"));
+ return -1;
}
- JoyInfo.dev = SDL_JoystickOpen(joyindex-1);
+ newdev = SDL_JoystickOpen(joyindex-1);
+
+ // Handle the edge case where the device <-> joystick index assignment can change due to hotplugging
+ // This indexing is SDL's responsibility and there's not much we can do about it.
+ //
+ // Example:
+ // 1. Plug Controller A -> Index 0 opened
+ // 2. Plug Controller B -> Index 1 opened
+ // 3. Unplug Controller A -> Index 0 closed, Index 1 active
+ // 4. Unplug Controller B -> Index 0 inactive, Index 1 closed
+ // 5. Plug Controller B -> Index 0 opened
+ // 6. Plug Controller A -> Index 0 REPLACED, opened as Controller A; Index 1 is now Controller B
+ if (JoyInfo.dev)
+ {
+ if (JoyInfo.dev == newdev // same device, nothing to do
+ || (newdev == NULL && SDL_JoystickGetAttached(JoyInfo.dev))) // we failed, but already have a working device
+ return JoyInfo.axises;
+ // Else, we're changing devices, so send neutral joy events
+ CONS_Debug(DBG_GAMELOGIC, "Joystick1 device is changing; resetting events...\n");
+ I_ShutdownJoystick();
+ }
+
+ JoyInfo.dev = newdev;
if (JoyInfo.dev == NULL)
{
- CONS_Printf(M_GetText("Couldn't open joystick: %s\n"), SDL_GetError());
- I_ShutdownJoystick();
+ CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick1: Couldn't open device - %s\n"), SDL_GetError());
return -1;
}
else
{
- CONS_Printf(M_GetText("Joystick: %s\n"), SDL_JoystickName(JoyInfo.dev));
+ CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick1: %s\n"), SDL_JoystickName(JoyInfo.dev));
JoyInfo.axises = SDL_JoystickNumAxes(JoyInfo.dev);
if (JoyInfo.axises > JOYAXISSET*2)
JoyInfo.axises = JOYAXISSET*2;
-/* if (joyaxes<2)
+ /* if (joyaxes<2)
{
I_OutputMsg("Not enought axes?\n");
- I_ShutdownJoystick();
return 0;
}*/
@@ -1156,7 +1355,7 @@ static UINT64 lastjoy2hats = 0;
\return void
*/
-static void I_ShutdownJoystick2(void)
+void I_ShutdownJoystick2(void)
{
INT32 i;
event_t event;
@@ -1190,15 +1389,8 @@ static void I_ShutdownJoystick2(void)
joystick2_started = 0;
JoyReset(&JoyInfo2);
- if (!joystick_started && !joystick2_started && !joystick3_started && !joystick4_started
- && SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
- {
- SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
- if (cv_usejoystick2.value == 0)
- {
- DEBFILE("I_Joystick2: SDL's Joystick system has been shutdown\n");
- }
- }
+
+ // don't shut down the subsystem here, because hotplugging
}
void I_GetJoystick2Events(void)
@@ -1341,72 +1533,66 @@ void I_GetJoystick2Events(void)
*/
-static int joy_open2(const char *fname)
+static int joy_open2(int joyindex)
{
- int joyindex = atoi(fname);
+ SDL_Joystick *newdev = NULL;
int num_joy = 0;
- int i;
- if (joystick_started == 0 && joystick2_started == 0 && joystick3_started == 0 && joystick4_started == 0)
+ if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
{
- if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1)
- {
- CONS_Printf(M_GetText("Couldn't initialize joystick: %s\n"), SDL_GetError());
- return -1;
- }
- else
- num_joy = SDL_NumJoysticks();
+ CONS_Printf(M_GetText("Joystick subsystem not started\n"));
+ return -1;
+ }
- if (num_joy < joyindex)
- {
- CONS_Printf(M_GetText("Cannot use joystick #%d/(%s), it doesn't exist\n"),joyindex,fname);
- for (i = 0; i < num_joy; i++)
- CONS_Printf("#%d/(%s)\n", i+1, SDL_JoystickNameForIndex(i));
- I_ShutdownJoystick2();
- return -1;
- }
- }
- else
- {
- JoyReset(&JoyInfo2);
- //I_ShutdownJoystick();
- //joy_open(fname);
- }
+ if (joyindex <= 0)
+ return -1;
num_joy = SDL_NumJoysticks();
- if (joyindex <= 0 || num_joy == 0 || JoyInfo2.oldjoy == joyindex)
+ if (num_joy == 0)
{
-// I_OutputMsg("Unable to use that joystick #(%s), non-number\n",fname);
- if (num_joy != 0)
- {
- CONS_Printf(M_GetText("Found %d joysticks on this system\n"), num_joy);
- for (i = 0; i < num_joy; i++)
- CONS_Printf("#%d/(%s)\n", i+1, SDL_JoystickNameForIndex(i));
- }
- else
- CONS_Printf("%s", M_GetText("Found no joysticks on this system\n"));
- if (joyindex <= 0 || num_joy == 0) return 0;
+ CONS_Printf("%s", M_GetText("Found no joysticks on this system\n"));
+ return -1;
}
- JoyInfo2.dev = SDL_JoystickOpen(joyindex-1);
+ newdev = SDL_JoystickOpen(joyindex-1);
- if (!JoyInfo2.dev)
+ // Handle the edge case where the device <-> joystick index assignment can change due to hotplugging
+ // This indexing is SDL's responsibility and there's not much we can do about it.
+ //
+ // Example:
+ // 1. Plug Controller A -> Index 0 opened
+ // 2. Plug Controller B -> Index 1 opened
+ // 3. Unplug Controller A -> Index 0 closed, Index 1 active
+ // 4. Unplug Controller B -> Index 0 inactive, Index 1 closed
+ // 5. Plug Controller B -> Index 0 opened
+ // 6. Plug Controller A -> Index 0 REPLACED, opened as Controller A; Index 1 is now Controller B
+ if (JoyInfo2.dev)
{
- CONS_Printf(M_GetText("Couldn't open joystick2: %s\n"), SDL_GetError());
+ if (JoyInfo2.dev == newdev // same device, nothing to do
+ || (newdev == NULL && SDL_JoystickGetAttached(JoyInfo2.dev))) // we failed, but already have a working device
+ return JoyInfo.axises;
+ // Else, we're changing devices, so send neutral joy events
+ CONS_Debug(DBG_GAMELOGIC, "Joystick2 device is changing; resetting events...\n");
I_ShutdownJoystick2();
+ }
+
+ JoyInfo2.dev = newdev;
+
+ if (JoyInfo2.dev == NULL)
+ {
+ CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick2: couldn't open device - %s\n"), SDL_GetError());
return -1;
}
else
{
- CONS_Printf(M_GetText("Joystick2: %s\n"), SDL_JoystickName(JoyInfo2.dev));
+ CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick2: %s\n"), SDL_JoystickName(JoyInfo2.dev));
JoyInfo2.axises = SDL_JoystickNumAxes(JoyInfo2.dev);
if (JoyInfo2.axises > JOYAXISSET*2)
JoyInfo2.axises = JOYAXISSET*2;
-/* if (joyaxes < 2)
+/* if (joyaxes<2)
{
I_OutputMsg("Not enought axes?\n");
- I_ShutdownJoystick2();
return 0;
}*/
@@ -1441,7 +1627,7 @@ static UINT64 lastjoy3hats = 0;
\return void
*/
-static void I_ShutdownJoystick3(void)
+void I_ShutdownJoystick3(void)
{
INT32 i;
event_t event;
@@ -1473,16 +1659,10 @@ static void I_ShutdownJoystick3(void)
D_PostEvent(&event);
}
+ joystick3_started = 0;
JoyReset(&JoyInfo3);
- if (!joystick_started && !joystick2_started && !joystick3_started && !joystick4_started
- && SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
- {
- SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
- if (cv_usejoystick3.value == 0)
- {
- DEBFILE("I_Joystick3: SDL's Joystick system has been shutdown\n");
- }
- }
+
+ // don't shutdown the subsystem here, because hotplugging
}
void I_GetJoystick3Events(void)
@@ -1624,73 +1804,67 @@ void I_GetJoystick3Events(void)
*/
-static int joy_open3(const char *fname)
+static int joy_open3(int joyindex)
{
- int joyindex = atoi(fname);
+ SDL_Joystick *newdev = NULL;
int num_joy = 0;
- int i;
- if (joystick_started == 0 && joystick2_started == 0 && joystick3_started == 0 && joystick4_started == 0)
+ if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
{
- if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1)
- {
- CONS_Printf(M_GetText("Couldn't initialize joystick: %s\n"), SDL_GetError());
- return -1;
- }
- else
- num_joy = SDL_NumJoysticks();
+ CONS_Printf(M_GetText("Joystick subsystem not started\n"));
+ return -1;
+ }
- if (num_joy < joyindex)
- {
- CONS_Printf(M_GetText("Cannot use joystick #%d/(%s), it doesn't exist\n"),joyindex,fname);
- for (i = 0; i < num_joy; i++)
- CONS_Printf("#%d/(%s)\n", i+1, SDL_JoystickNameForIndex(i));
- I_ShutdownJoystick3();
- return -1;
- }
- }
- else
- {
- JoyReset(&JoyInfo3);
- //I_ShutdownJoystick();
- //joy_open(fname);
- }
+ if (joyindex <= 0)
+ return -1;
num_joy = SDL_NumJoysticks();
- if (joyindex <= 0 || num_joy == 0 || JoyInfo3.oldjoy == joyindex)
+ if (num_joy == 0)
{
-// I_OutputMsg("Unable to use that joystick #(%s), non-number\n",fname);
- if (num_joy != 0)
- {
- CONS_Printf(M_GetText("Found %d joysticks on this system\n"), num_joy);
- for (i = 0; i < num_joy; i++)
- CONS_Printf("#%d/(%s)\n", i+1, SDL_JoystickNameForIndex(i));
- }
- else
- CONS_Printf("%s", M_GetText("Found no joysticks on this system\n"));
- if (joyindex <= 0 || num_joy == 0) return 0;
+ CONS_Printf("%s", M_GetText("Found no joysticks on this system\n"));
+ return -1;
}
- JoyInfo3.dev = SDL_JoystickOpen(joyindex-1);
+ newdev = SDL_JoystickOpen(joyindex - 1);
- if (!JoyInfo3.dev)
+ // Handle the edge case where the device <-> joystick index assignment can change due to hotplugging
+ // This indexing is SDL's responsibility and there's not much we can do about it.
+ //
+ // Example:
+ // 1. Plug Controller A -> Index 0 opened
+ // 2. Plug Controller B -> Index 1 opened
+ // 3. Unplug Controller A -> Index 0 closed, Index 1 active
+ // 4. Unplug Controller B -> Index 0 inactive, Index 1 closed
+ // 5. Plug Controller B -> Index 0 opened
+ // 6. Plug Controller A -> Index 0 REPLACED, opened as Controller A; Index 1 is now Controller B
+ if (JoyInfo3.dev)
{
- CONS_Printf(M_GetText("Couldn't open joystick3: %s\n"), SDL_GetError());
+ if (JoyInfo3.dev == newdev // same device, nothing to do
+ || (newdev == NULL && SDL_JoystickGetAttached(JoyInfo3.dev))) // we failed, but already have a working device
+ return JoyInfo.axises;
+ // Else, we're changing devices, so send neutral joy events
+ CONS_Debug(DBG_GAMELOGIC, "Joystick3 device is changing; resetting events...\n");
I_ShutdownJoystick3();
+ }
+
+ JoyInfo3.dev = newdev;
+
+ if (JoyInfo3.dev == NULL)
+ {
+ CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick3: couldn't open device - %s\n"), SDL_GetError());
return -1;
}
else
{
- CONS_Printf(M_GetText("Joystick3: %s\n"), SDL_JoystickName(JoyInfo3.dev));
+ CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick3: %s\n"), SDL_JoystickName(JoyInfo3.dev));
JoyInfo3.axises = SDL_JoystickNumAxes(JoyInfo3.dev);
- if (JoyInfo3.axises > JOYAXISSET*2)
- JoyInfo3.axises = JOYAXISSET*2;
-/* if (joyaxes < 2)
+ if (JoyInfo3.axises > JOYAXISSET * 2)
+ JoyInfo3.axises = JOYAXISSET * 2;
+ /* if (joyaxes<2)
{
- I_OutputMsg("Not enought axes?\n");
- I_ShutdownJoystick3();
- return 0;
+ I_OutputMsg("Not enought axes?\n");
+ return 0;
}*/
JoyInfo3.buttons = SDL_JoystickNumButtons(JoyInfo3.dev);
@@ -1724,7 +1898,7 @@ static UINT64 lastjoy4hats = 0;
\return void
*/
-static void I_ShutdownJoystick4(void)
+void I_ShutdownJoystick4(void)
{
INT32 i;
event_t event;
@@ -1756,16 +1930,10 @@ static void I_ShutdownJoystick4(void)
D_PostEvent(&event);
}
+ joystick4_started = 0;
JoyReset(&JoyInfo4);
- if (!joystick_started && !joystick2_started && !joystick3_started && !joystick4_started
- && SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
- {
- SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
- if (cv_usejoystick4.value == 0)
- {
- DEBFILE("I_Joystick4: SDL's Joystick system has been shutdown\n");
- }
- }
+
+ // don't shutdown the subsystem here, because hotplugging
}
void I_GetJoystick4Events(void)
@@ -1907,73 +2075,67 @@ void I_GetJoystick4Events(void)
*/
-static int joy_open4(const char *fname)
+static int joy_open4(int joyindex)
{
- int joyindex = atoi(fname);
+ SDL_Joystick *newdev = NULL;
int num_joy = 0;
- int i;
- if (joystick_started == 0 && joystick2_started == 0 && joystick3_started == 0 && joystick4_started == 0)
+ if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
{
- if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1)
- {
- CONS_Printf(M_GetText("Couldn't initialize joystick: %s\n"), SDL_GetError());
- return -1;
- }
- else
- num_joy = SDL_NumJoysticks();
+ CONS_Printf(M_GetText("Joystick subsystem not started\n"));
+ return -1;
+ }
- if (num_joy < joyindex)
- {
- CONS_Printf(M_GetText("Cannot use joystick #%d/(%s), it doesn't exist\n"),joyindex,fname);
- for (i = 0; i < num_joy; i++)
- CONS_Printf("#%d/(%s)\n", i+1, SDL_JoystickNameForIndex(i));
- I_ShutdownJoystick4();
- return -1;
- }
- }
- else
- {
- JoyReset(&JoyInfo4);
- //I_ShutdownJoystick();
- //joy_open(fname);
- }
+ if (joyindex <= 0)
+ return -1;
num_joy = SDL_NumJoysticks();
- if (joyindex <= 0 || num_joy == 0 || JoyInfo4.oldjoy == joyindex)
+ if (num_joy == 0)
{
-// I_OutputMsg("Unable to use that joystick #(%s), non-number\n",fname);
- if (num_joy != 0)
- {
- CONS_Printf(M_GetText("Found %d joysticks on this system\n"), num_joy);
- for (i = 0; i < num_joy; i++)
- CONS_Printf("#%d/(%s)\n", i+1, SDL_JoystickNameForIndex(i));
- }
- else
- CONS_Printf("%s", M_GetText("Found no joysticks on this system\n"));
- if (joyindex <= 0 || num_joy == 0) return 0;
+ CONS_Printf("%s", M_GetText("Found no joysticks on this system\n"));
+ return -1;
}
- JoyInfo4.dev = SDL_JoystickOpen(joyindex-1);
+ newdev = SDL_JoystickOpen(joyindex - 1);
- if (!JoyInfo4.dev)
+ // Handle the edge case where the device <-> joystick index assignment can change due to hotplugging
+ // This indexing is SDL's responsibility and there's not much we can do about it.
+ //
+ // Example:
+ // 1. Plug Controller A -> Index 0 opened
+ // 2. Plug Controller B -> Index 1 opened
+ // 3. Unplug Controller A -> Index 0 closed, Index 1 active
+ // 4. Unplug Controller B -> Index 0 inactive, Index 1 closed
+ // 5. Plug Controller B -> Index 0 opened
+ // 6. Plug Controller A -> Index 0 REPLACED, opened as Controller A; Index 1 is now Controller B
+ if (JoyInfo4.dev)
{
- CONS_Printf(M_GetText("Couldn't open joystick4: %s\n"), SDL_GetError());
+ if (JoyInfo4.dev == newdev // same device, nothing to do
+ || (newdev == NULL && SDL_JoystickGetAttached(JoyInfo4.dev))) // we failed, but already have a working device
+ return JoyInfo.axises;
+ // Else, we're changing devices, so send neutral joy events
+ CONS_Debug(DBG_GAMELOGIC, "Joystick4 device is changing; resetting events...\n");
I_ShutdownJoystick4();
+ }
+
+ JoyInfo4.dev = newdev;
+
+ if (JoyInfo4.dev == NULL)
+ {
+ CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick4: couldn't open device - %s\n"), SDL_GetError());
return -1;
}
else
{
- CONS_Printf(M_GetText("Joystick4: %s\n"), SDL_JoystickName(JoyInfo4.dev));
+ CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick4: %s\n"), SDL_JoystickName(JoyInfo4.dev));
JoyInfo4.axises = SDL_JoystickNumAxes(JoyInfo4.dev);
- if (JoyInfo4.axises > JOYAXISSET*2)
- JoyInfo4.axises = JOYAXISSET*2;
-/* if (joyaxes < 2)
+ if (JoyInfo4.axises > JOYAXISSET * 2)
+ JoyInfo4.axises = JOYAXISSET * 2;
+ /* if (joyaxes<2)
{
- I_OutputMsg("Not enought axes?\n");
- I_ShutdownJoystick4();
- return 0;
+ I_OutputMsg("Not enought axes?\n");
+ return 0;
}*/
JoyInfo4.buttons = SDL_JoystickNumButtons(JoyInfo4.dev);
@@ -1986,7 +2148,7 @@ static int joy_open4(const char *fname)
JoyInfo4.balls = SDL_JoystickNumBalls(JoyInfo4.dev);
- //Joystick4.bGamepadStyle = !stricmp(SDL_JoystickName(JoyInfo4.dev), "pad");
+ //Joystick.bGamepadStyle = !stricmp(SDL_JoystickName(JoyInfo4.dev), "pad");
return JoyInfo4.axises;
}
@@ -1997,91 +2159,199 @@ static int joy_open4(const char *fname)
//
void I_InitJoystick(void)
{
- I_ShutdownJoystick();
- SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE);
- if (!strcmp(cv_usejoystick.string, "0") || M_CheckParm("-nojoy"))
+ SDL_Joystick *newjoy = NULL;
+
+ //I_ShutdownJoystick();
+ //SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE);
+ if (M_CheckParm("-nojoy"))
return;
- if (joy_open(cv_usejoystick.string) != -1)
- JoyInfo.oldjoy = atoi(cv_usejoystick.string);
+
+ if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
+ {
+ CONS_Printf("I_InitJoystick()...\n");
+
+ if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1)
+ {
+ CONS_Printf(M_GetText("Couldn't initialize joystick: %s\n"), SDL_GetError());
+ return;
+ }
+ }
+
+ if (cv_usejoystick.value)
+ newjoy = SDL_JoystickOpen(cv_usejoystick.value-1);
+
+ if (newjoy && (JoyInfo2.dev == newjoy || JoyInfo3.dev == newjoy || JoyInfo4.dev == newjoy)) // don't override an active device
+ cv_usejoystick.value = I_GetJoystickDeviceIndex(JoyInfo.dev) + 1;
+ else if (newjoy && joy_open(cv_usejoystick.value) != -1)
+ {
+ // SDL's device indexes are unstable, so cv_usejoystick may not match
+ // the actual device index. So let's cheat a bit and find the device's current index.
+ JoyInfo.oldjoy = I_GetJoystickDeviceIndex(JoyInfo.dev) + 1;
+ joystick_started = 1;
+ }
else
{
+ if (JoyInfo.oldjoy)
+ I_ShutdownJoystick();
cv_usejoystick.value = 0;
- return;
+ joystick_started = 0;
}
- joystick_started = 1;
+
+ if (JoyInfo.dev != newjoy && JoyInfo2.dev != newjoy && JoyInfo3.dev != newjoy && JoyInfo4.dev != newjoy)
+ SDL_JoystickClose(newjoy);
}
void I_InitJoystick2(void)
{
- I_ShutdownJoystick2();
- SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE);
- if (!strcmp(cv_usejoystick2.string, "0") || M_CheckParm("-nojoy"))
+ SDL_Joystick *newjoy = NULL;
+
+ //I_ShutdownJoystick2();
+ //SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE);
+ if (M_CheckParm("-nojoy"))
return;
- if (joy_open2(cv_usejoystick2.string) != -1)
- JoyInfo2.oldjoy = atoi(cv_usejoystick2.string);
+
+ if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
+ {
+ CONS_Printf("I_InitJoystick2()...\n");
+ if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1)
+ {
+ CONS_Printf(M_GetText("Couldn't initialize joystick: %s\n"), SDL_GetError());
+ return;
+ }
+ }
+
+ if (cv_usejoystick2.value)
+ newjoy = SDL_JoystickOpen(cv_usejoystick2.value-1);
+
+ if (newjoy && (JoyInfo.dev == newjoy || JoyInfo3.dev == newjoy || JoyInfo4.dev == newjoy)) // don't override an active device
+ cv_usejoystick2.value = I_GetJoystickDeviceIndex(JoyInfo2.dev) + 1;
+ else if (newjoy && joy_open2(cv_usejoystick2.value) != -1)
+ {
+ // SDL's device indexes are unstable, so cv_usejoystick may not match
+ // the actual device index. So let's cheat a bit and find the device's current index.
+ JoyInfo2.oldjoy = I_GetJoystickDeviceIndex(JoyInfo2.dev) + 1;
+ joystick2_started = 1;
+ }
else
{
+ if (JoyInfo2.oldjoy)
+ I_ShutdownJoystick2();
cv_usejoystick2.value = 0;
- return;
+ joystick2_started = 0;
}
- joystick2_started = 1;
+
+ if (JoyInfo.dev != newjoy && JoyInfo2.dev != newjoy && JoyInfo3.dev != newjoy && JoyInfo4.dev != newjoy)
+ SDL_JoystickClose(newjoy);
}
void I_InitJoystick3(void)
{
- I_ShutdownJoystick3();
- SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE);
- if (!strcmp(cv_usejoystick3.string, "0") || M_CheckParm("-nojoy"))
+ SDL_Joystick *newjoy = NULL;
+
+ //I_ShutdownJoystick3();
+ //SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE);
+ if (M_CheckParm("-nojoy"))
return;
- if (joy_open3(cv_usejoystick3.string) != -1)
- JoyInfo3.oldjoy = atoi(cv_usejoystick3.string);
+
+ if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
+ {
+ CONS_Printf("I_InitJoystick3()...\n");
+ if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1)
+ {
+ CONS_Printf(M_GetText("Couldn't initialize joystick: %s\n"), SDL_GetError());
+ return;
+ }
+ }
+
+ if (cv_usejoystick3.value)
+ newjoy = SDL_JoystickOpen(cv_usejoystick3.value - 1);
+
+ if (newjoy && (JoyInfo.dev == newjoy || JoyInfo2.dev == newjoy || JoyInfo4.dev == newjoy)) // don't override an active device
+ cv_usejoystick3.value = I_GetJoystickDeviceIndex(JoyInfo3.dev) + 1;
+ else if (newjoy && joy_open3(cv_usejoystick3.value) != -1)
+ {
+ // SDL's device indexes are unstable, so cv_usejoystick may not match
+ // the actual device index. So let's cheat a bit and find the device's current index.
+ JoyInfo3.oldjoy = I_GetJoystickDeviceIndex(JoyInfo3.dev) + 1;
+ joystick3_started = 1;
+ }
else
{
+ if (JoyInfo3.oldjoy)
+ I_ShutdownJoystick3();
cv_usejoystick3.value = 0;
- return;
+ joystick3_started = 0;
}
- joystick3_started = 1;
+
+ if (JoyInfo.dev != newjoy && JoyInfo2.dev != newjoy && JoyInfo3.dev != newjoy && JoyInfo4.dev != newjoy)
+ SDL_JoystickClose(newjoy);
}
void I_InitJoystick4(void)
{
- I_ShutdownJoystick4();
- SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE);
- if (!strcmp(cv_usejoystick4.string, "0") || M_CheckParm("-nojoy"))
+ SDL_Joystick *newjoy = NULL;
+
+ //I_ShutdownJoystick4();
+ //SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE);
+ if (M_CheckParm("-nojoy"))
return;
- if (joy_open4(cv_usejoystick4.string) != -1)
- JoyInfo4.oldjoy = atoi(cv_usejoystick4.string);
+
+ if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
+ {
+ CONS_Printf("I_InitJoystick4()...\n");
+ if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1)
+ {
+ CONS_Printf(M_GetText("Couldn't initialize joystick: %s\n"), SDL_GetError());
+ return;
+ }
+ }
+
+ if (cv_usejoystick4.value)
+ newjoy = SDL_JoystickOpen(cv_usejoystick4.value - 1);
+
+ if (newjoy && (JoyInfo.dev == newjoy || JoyInfo2.dev == newjoy || JoyInfo4.dev == newjoy)) // don't override an active device
+ cv_usejoystick4.value = I_GetJoystickDeviceIndex(JoyInfo4.dev) + 1;
+ else if (newjoy && joy_open4(cv_usejoystick4.value) != -1)
+ {
+ // SDL's device indexes are unstable, so cv_usejoystick may not match
+ // the actual device index. So let's cheat a bit and find the device's current index.
+ JoyInfo4.oldjoy = I_GetJoystickDeviceIndex(JoyInfo4.dev) + 1;
+ joystick4_started = 1;
+ }
else
{
+ if (JoyInfo4.oldjoy)
+ I_ShutdownJoystick4();
cv_usejoystick4.value = 0;
- return;
+ joystick4_started = 0;
}
- joystick4_started = 1;
+
+ if (JoyInfo.dev != newjoy && JoyInfo2.dev != newjoy && JoyInfo3.dev != newjoy && JoyInfo4.dev != newjoy)
+ SDL_JoystickClose(newjoy);
}
static void I_ShutdownInput(void)
{
+ // Yes, the name is misleading: these send neutral events to
+ // clean up the unplugged joystick's input
+ // Note these methods are internal to this file, not called elsewhere.
+ I_ShutdownJoystick();
+ I_ShutdownJoystick2();
+ I_ShutdownJoystick3();
+ I_ShutdownJoystick4();
+
if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
{
- JoyReset(&JoyInfo);
- JoyReset(&JoyInfo2);
- JoyReset(&JoyInfo3);
- JoyReset(&JoyInfo4);
+ CONS_Printf("Shutting down joy system\n");
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
+ I_OutputMsg("I_Joystick: SDL's Joystick system has been shutdown\n");
}
-
}
INT32 I_NumJoys(void)
{
INT32 numjoy = 0;
- if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
- {
- if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != -1)
- numjoy = SDL_NumJoysticks();
- SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
- }
- else
+ if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
numjoy = SDL_NumJoysticks();
return numjoy;
}
@@ -2091,18 +2361,9 @@ static char joyname[255]; // MAX_PATH; joystick name is straight from the driver
const char *I_GetJoyName(INT32 joyindex)
{
const char *tempname = NULL;
+ joyname[0] = 0;
joyindex--; //SDL's Joystick System starts at 0, not 1
- if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
- {
- if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != -1)
- {
- tempname = SDL_JoystickNameForIndex(joyindex);
- if (tempname)
- strncpy(joyname, tempname, 255);
- }
- SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
- }
- else
+ if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
{
tempname = SDL_JoystickNameForIndex(joyindex);
if (tempname)
diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c
index 78dfc820..f63e9847 100644
--- a/src/sdl/i_video.c
+++ b/src/sdl/i_video.c
@@ -72,6 +72,7 @@
#include "../console.h"
#include "../command.h"
#include "sdlmain.h"
+#include "../i_system.h"
#ifdef HWRENDER
#include "../hardware/hw_main.h"
#include "../hardware/hw_drv.h"
@@ -200,7 +201,10 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen)
}
// Reposition window only in windowed mode
SDL_SetWindowSize(window, width, height);
- SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
+ SDL_SetWindowPosition(window,
+ SDL_WINDOWPOS_CENTERED_DISPLAY(SDL_GetWindowDisplayIndex(window)),
+ SDL_WINDOWPOS_CENTERED_DISPLAY(SDL_GetWindowDisplayIndex(window))
+ );
}
}
else
@@ -357,6 +361,7 @@ static INT32 Impl_SDL_Scancode_To_Keycode(SDL_Scancode code)
static void SDLdoUngrabMouse(void)
{
+ SDL_ShowCursor(SDL_ENABLE);
SDL_SetWindowGrab(window, SDL_FALSE);
wrapmouseok = SDL_FALSE;
SDL_SetRelativeMouseMode(SDL_FALSE);
@@ -366,6 +371,7 @@ void SDLforceUngrabMouse(void)
{
if (SDL_WasInit(SDL_INIT_VIDEO)==SDL_INIT_VIDEO && window != NULL)
{
+ SDL_ShowCursor(SDL_ENABLE);
SDL_SetWindowGrab(window, SDL_FALSE);
wrapmouseok = SDL_FALSE;
SDL_SetRelativeMouseMode(SDL_FALSE);
@@ -617,6 +623,8 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
if (cv_usemouse.value) I_StartupMouse();
}
//else firsttimeonmouse = SDL_FALSE;
+
+ capslock = !!( SDL_GetModState() & KMOD_CAPS );// in case CL changes
}
else if (!mousefocus && !kbfocus)
{
@@ -944,6 +952,284 @@ void I_GetEvent(void)
case SDL_JOYBUTTONDOWN:
Impl_HandleJoystickButtonEvent(evt.jbutton, evt.type);
break;
+
+ ////////////////////////////////////////////////////////////
+
+ case SDL_JOYDEVICEADDED:
+ {
+ // OH BOY are you in for a good time! #abominationstation
+
+ SDL_Joystick *newjoy = SDL_JoystickOpen(evt.jdevice.which);
+
+ CONS_Debug(DBG_GAMELOGIC, "Joystick device index %d added\n", evt.jdevice.which + 1);
+
+ ////////////////////////////////////////////////////////////
+ // Because SDL's device index is unstable, we're going to cheat here a bit:
+ // For the first joystick setting that is NOT active:
+ //
+ // 1. Set cv_usejoystickX.value to the new device index (this does not change what is written to config.cfg)
+ //
+ // 2. Set OTHERS' cv_usejoystickX.value to THEIR new device index, because it likely changed
+ // * If device doesn't exist, switch cv_usejoystick back to default value (.string)
+ // * BUT: If that default index is being occupied, use ANOTHER cv_usejoystick's default value!
+ ////////////////////////////////////////////////////////////
+
+ //////////////////////////////
+ // PLAYER 1
+ //////////////////////////////
+
+ if (newjoy && (!JoyInfo.dev || !SDL_JoystickGetAttached(JoyInfo.dev))
+ && JoyInfo2.dev != newjoy && JoyInfo3.dev != newjoy && JoyInfo4.dev != newjoy) // don't override a currently active device
+ {
+ cv_usejoystick.value = evt.jdevice.which + 1;
+ I_UpdateJoystickDeviceIndices(1);
+ }
+
+ //////////////////////////////
+ // PLAYER 2
+ //////////////////////////////
+
+ else if (newjoy && (!JoyInfo2.dev || !SDL_JoystickGetAttached(JoyInfo2.dev))
+ && JoyInfo.dev != newjoy && JoyInfo3.dev != newjoy && JoyInfo4.dev != newjoy) // don't override a currently active device
+ {
+ cv_usejoystick2.value = evt.jdevice.which + 1;
+ I_UpdateJoystickDeviceIndices(2);
+ }
+
+ //////////////////////////////
+ // PLAYER 3
+ //////////////////////////////
+
+ else if (newjoy && (!JoyInfo3.dev || !SDL_JoystickGetAttached(JoyInfo3.dev))
+ && JoyInfo.dev != newjoy && JoyInfo2.dev != newjoy && JoyInfo4.dev != newjoy) // don't override a currently active device
+ {
+ cv_usejoystick3.value = evt.jdevice.which + 1;
+ I_UpdateJoystickDeviceIndices(3);
+ }
+
+ //////////////////////////////
+ // PLAYER 4
+ //////////////////////////////
+
+ else if (newjoy && (!JoyInfo4.dev || !SDL_JoystickGetAttached(JoyInfo4.dev))
+ && JoyInfo.dev != newjoy && JoyInfo2.dev != newjoy && JoyInfo3.dev != newjoy) // don't override a currently active device
+ {
+ cv_usejoystick4.value = evt.jdevice.which + 1;
+ I_UpdateJoystickDeviceIndices(4);
+ }
+
+ ////////////////////////////////////////////////////////////
+ // Was cv_usejoystick disabled in settings?
+ ////////////////////////////////////////////////////////////
+
+ if (!strcmp(cv_usejoystick.string, "0") || !cv_usejoystick.value)
+ cv_usejoystick.value = 0;
+ else if (atoi(cv_usejoystick.string) <= I_NumJoys() // don't mess if we intentionally set higher than NumJoys
+ && cv_usejoystick.value) // update the cvar ONLY if a device exists
+ CV_SetValue(&cv_usejoystick, cv_usejoystick.value);
+
+ if (!strcmp(cv_usejoystick2.string, "0") || !cv_usejoystick2.value)
+ cv_usejoystick2.value = 0;
+ else if (atoi(cv_usejoystick2.string) <= I_NumJoys() // don't mess if we intentionally set higher than NumJoys
+ && cv_usejoystick2.value) // update the cvar ONLY if a device exists
+ CV_SetValue(&cv_usejoystick2, cv_usejoystick2.value);
+
+ if (!strcmp(cv_usejoystick3.string, "0") || !cv_usejoystick3.value)
+ cv_usejoystick3.value = 0;
+ else if (atoi(cv_usejoystick3.string) <= I_NumJoys() // don't mess if we intentionally set higher than NumJoys
+ && cv_usejoystick3.value) // update the cvar ONLY if a device exists
+ CV_SetValue(&cv_usejoystick3, cv_usejoystick3.value);
+
+ if (!strcmp(cv_usejoystick4.string, "0") || !cv_usejoystick4.value)
+ cv_usejoystick4.value = 0;
+ else if (atoi(cv_usejoystick4.string) <= I_NumJoys() // don't mess if we intentionally set higher than NumJoys
+ && cv_usejoystick4.value) // update the cvar ONLY if a device exists
+ CV_SetValue(&cv_usejoystick4, cv_usejoystick4.value);
+
+ ////////////////////////////////////////////////////////////
+ // Update all joysticks' init states
+ // This is a little wasteful since cv_usejoystick already calls this, but
+ // we need to do this in case CV_SetValue did nothing because the string was already same.
+ // if the device is already active, this should do nothing, effectively.
+ ////////////////////////////////////////////////////////////
+
+ I_InitJoystick();
+ I_InitJoystick2();
+ I_InitJoystick3();
+ I_InitJoystick4();
+
+ ////////////////////////////////////////////////////////////
+
+ CONS_Debug(DBG_GAMELOGIC, "Joystick1 device index: %d\n", JoyInfo.oldjoy);
+ CONS_Debug(DBG_GAMELOGIC, "Joystick2 device index: %d\n", JoyInfo2.oldjoy);
+ CONS_Debug(DBG_GAMELOGIC, "Joystick3 device index: %d\n", JoyInfo3.oldjoy);
+ CONS_Debug(DBG_GAMELOGIC, "Joystick4 device index: %d\n", JoyInfo4.oldjoy);
+
+ // update the menu
+ if (currentMenu == &OP_JoystickSetDef)
+ M_SetupJoystickMenu(0);
+
+ if (JoyInfo.dev != newjoy && JoyInfo2.dev != newjoy && JoyInfo3.dev != newjoy && JoyInfo4.dev != newjoy)
+ SDL_JoystickClose(newjoy);
+ }
+ break;
+
+ ////////////////////////////////////////////////////////////
+
+ case SDL_JOYDEVICEREMOVED:
+ if (JoyInfo.dev && !SDL_JoystickGetAttached(JoyInfo.dev))
+ {
+ CONS_Debug(DBG_GAMELOGIC, "Joystick1 removed, device index: %d\n", JoyInfo.oldjoy);
+ I_ShutdownJoystick();
+ }
+
+ if (JoyInfo2.dev && !SDL_JoystickGetAttached(JoyInfo2.dev))
+ {
+ CONS_Debug(DBG_GAMELOGIC, "Joystick2 removed, device index: %d\n", JoyInfo2.oldjoy);
+ I_ShutdownJoystick2();
+ }
+
+ if (JoyInfo3.dev && !SDL_JoystickGetAttached(JoyInfo3.dev))
+ {
+ CONS_Debug(DBG_GAMELOGIC, "Joystick3 removed, device index: %d\n", JoyInfo3.oldjoy);
+ I_ShutdownJoystick3();
+ }
+
+ if (JoyInfo4.dev && !SDL_JoystickGetAttached(JoyInfo4.dev))
+ {
+ CONS_Debug(DBG_GAMELOGIC, "Joystick4 removed, device index: %d\n", JoyInfo4.oldjoy);
+ I_ShutdownJoystick4();
+ }
+
+ ////////////////////////////////////////////////////////////
+ // Update the device indexes, because they likely changed
+ // * If device doesn't exist, switch cv_usejoystick back to default value (.string)
+ // * BUT: If that default index is being occupied, use ANOTHER cv_usejoystick's default value!
+ ////////////////////////////////////////////////////////////
+
+ if (JoyInfo.dev)
+ cv_usejoystick.value = JoyInfo.oldjoy = I_GetJoystickDeviceIndex(JoyInfo.dev) + 1;
+ else if (atoi(cv_usejoystick.string) != JoyInfo2.oldjoy
+ && atoi(cv_usejoystick.string) != JoyInfo3.oldjoy
+ && atoi(cv_usejoystick.string) != JoyInfo4.oldjoy)
+ cv_usejoystick.value = atoi(cv_usejoystick.string);
+ else if (atoi(cv_usejoystick2.string) != JoyInfo2.oldjoy
+ && atoi(cv_usejoystick2.string) != JoyInfo3.oldjoy
+ && atoi(cv_usejoystick2.string) != JoyInfo4.oldjoy)
+ cv_usejoystick.value = atoi(cv_usejoystick2.string);
+ else if (atoi(cv_usejoystick3.string) != JoyInfo2.oldjoy
+ && atoi(cv_usejoystick3.string) != JoyInfo3.oldjoy
+ && atoi(cv_usejoystick3.string) != JoyInfo4.oldjoy)
+ cv_usejoystick.value = atoi(cv_usejoystick3.string);
+ else if (atoi(cv_usejoystick4.string) != JoyInfo2.oldjoy
+ && atoi(cv_usejoystick4.string) != JoyInfo3.oldjoy
+ && atoi(cv_usejoystick4.string) != JoyInfo4.oldjoy)
+ cv_usejoystick.value = atoi(cv_usejoystick4.string);
+ else // we tried...
+ cv_usejoystick.value = 0;
+
+ if (JoyInfo2.dev)
+ cv_usejoystick2.value = JoyInfo2.oldjoy = I_GetJoystickDeviceIndex(JoyInfo2.dev) + 1;
+ else if (atoi(cv_usejoystick.string) != JoyInfo.oldjoy
+ && atoi(cv_usejoystick.string) != JoyInfo3.oldjoy
+ && atoi(cv_usejoystick.string) != JoyInfo4.oldjoy)
+ cv_usejoystick2.value = atoi(cv_usejoystick.string);
+ else if (atoi(cv_usejoystick2.string) != JoyInfo.oldjoy
+ && atoi(cv_usejoystick2.string) != JoyInfo3.oldjoy
+ && atoi(cv_usejoystick2.string) != JoyInfo4.oldjoy)
+ cv_usejoystick2.value = atoi(cv_usejoystick2.string);
+ else if (atoi(cv_usejoystick3.string) != JoyInfo.oldjoy
+ && atoi(cv_usejoystick3.string) != JoyInfo3.oldjoy
+ && atoi(cv_usejoystick3.string) != JoyInfo4.oldjoy)
+ cv_usejoystick2.value = atoi(cv_usejoystick3.string);
+ else if (atoi(cv_usejoystick4.string) != JoyInfo.oldjoy
+ && atoi(cv_usejoystick4.string) != JoyInfo3.oldjoy
+ && atoi(cv_usejoystick4.string) != JoyInfo4.oldjoy)
+ cv_usejoystick2.value = atoi(cv_usejoystick4.string);
+ else // we tried...
+ cv_usejoystick2.value = 0;
+
+ if (JoyInfo3.dev)
+ cv_usejoystick3.value = JoyInfo3.oldjoy = I_GetJoystickDeviceIndex(JoyInfo3.dev) + 1;
+ else if (atoi(cv_usejoystick.string) != JoyInfo.oldjoy
+ && atoi(cv_usejoystick.string) != JoyInfo2.oldjoy
+ && atoi(cv_usejoystick.string) != JoyInfo4.oldjoy)
+ cv_usejoystick3.value = atoi(cv_usejoystick.string);
+ else if (atoi(cv_usejoystick2.string) != JoyInfo.oldjoy
+ && atoi(cv_usejoystick2.string) != JoyInfo2.oldjoy
+ && atoi(cv_usejoystick2.string) != JoyInfo4.oldjoy)
+ cv_usejoystick3.value = atoi(cv_usejoystick2.string);
+ else if (atoi(cv_usejoystick3.string) != JoyInfo.oldjoy
+ && atoi(cv_usejoystick3.string) != JoyInfo2.oldjoy
+ && atoi(cv_usejoystick3.string) != JoyInfo4.oldjoy)
+ cv_usejoystick3.value = atoi(cv_usejoystick3.string);
+ else if (atoi(cv_usejoystick4.string) != JoyInfo.oldjoy
+ && atoi(cv_usejoystick4.string) != JoyInfo2.oldjoy
+ && atoi(cv_usejoystick4.string) != JoyInfo4.oldjoy)
+ cv_usejoystick3.value = atoi(cv_usejoystick4.string);
+ else // we tried...
+ cv_usejoystick3.value = 0;
+
+ if (JoyInfo4.dev)
+ cv_usejoystick4.value = JoyInfo4.oldjoy = I_GetJoystickDeviceIndex(JoyInfo4.dev) + 1;
+ else if (atoi(cv_usejoystick.string) != JoyInfo.oldjoy
+ && atoi(cv_usejoystick.string) != JoyInfo2.oldjoy
+ && atoi(cv_usejoystick.string) != JoyInfo3.oldjoy)
+ cv_usejoystick4.value = atoi(cv_usejoystick.string);
+ else if (atoi(cv_usejoystick2.string) != JoyInfo.oldjoy
+ && atoi(cv_usejoystick2.string) != JoyInfo2.oldjoy
+ && atoi(cv_usejoystick2.string) != JoyInfo3.oldjoy)
+ cv_usejoystick4.value = atoi(cv_usejoystick2.string);
+ else if (atoi(cv_usejoystick3.string) != JoyInfo.oldjoy
+ && atoi(cv_usejoystick3.string) != JoyInfo2.oldjoy
+ && atoi(cv_usejoystick3.string) != JoyInfo3.oldjoy)
+ cv_usejoystick4.value = atoi(cv_usejoystick3.string);
+ else if (atoi(cv_usejoystick4.string) != JoyInfo.oldjoy
+ && atoi(cv_usejoystick4.string) != JoyInfo2.oldjoy
+ && atoi(cv_usejoystick4.string) != JoyInfo3.oldjoy)
+ cv_usejoystick4.value = atoi(cv_usejoystick4.string);
+ else // we tried...
+ cv_usejoystick4.value = 0;
+
+ ////////////////////////////////////////////////////////////
+ // Was cv_usejoystick disabled in settings?
+ ////////////////////////////////////////////////////////////
+
+ if (!strcmp(cv_usejoystick.string, "0"))
+ cv_usejoystick.value = 0;
+ else if (atoi(cv_usejoystick.string) <= I_NumJoys() // don't mess if we intentionally set higher than NumJoys
+ && cv_usejoystick.value) // update the cvar ONLY if a device exists
+ CV_SetValue(&cv_usejoystick, cv_usejoystick.value);
+
+ if (!strcmp(cv_usejoystick2.string, "0"))
+ cv_usejoystick2.value = 0;
+ else if (atoi(cv_usejoystick2.string) <= I_NumJoys() // don't mess if we intentionally set higher than NumJoys
+ && cv_usejoystick2.value) // update the cvar ONLY if a device exists
+ CV_SetValue(&cv_usejoystick2, cv_usejoystick2.value);
+
+ if (!strcmp(cv_usejoystick3.string, "0"))
+ cv_usejoystick3.value = 0;
+ else if (atoi(cv_usejoystick3.string) <= I_NumJoys() // don't mess if we intentionally set higher than NumJoys
+ && cv_usejoystick3.value) // update the cvar ONLY if a device exists
+ CV_SetValue(&cv_usejoystick3, cv_usejoystick3.value);
+
+ if (!strcmp(cv_usejoystick4.string, "0"))
+ cv_usejoystick4.value = 0;
+ else if (atoi(cv_usejoystick4.string) <= I_NumJoys() // don't mess if we intentionally set higher than NumJoys
+ && cv_usejoystick4.value) // update the cvar ONLY if a device exists
+ CV_SetValue(&cv_usejoystick4, cv_usejoystick4.value);
+
+ ////////////////////////////////////////////////////////////
+
+ CONS_Debug(DBG_GAMELOGIC, "Joystick1 device index: %d\n", JoyInfo.oldjoy);
+ CONS_Debug(DBG_GAMELOGIC, "Joystick2 device index: %d\n", JoyInfo2.oldjoy);
+ CONS_Debug(DBG_GAMELOGIC, "Joystick3 device index: %d\n", JoyInfo3.oldjoy);
+ CONS_Debug(DBG_GAMELOGIC, "Joystick4 device index: %d\n", JoyInfo4.oldjoy);
+
+ // update the menu
+ if (currentMenu == &OP_JoystickSetDef)
+ M_SetupJoystickMenu(0);
+ break;
case SDL_QUIT:
I_Quit();
M_QuitResponse('y');
@@ -1613,9 +1899,18 @@ void I_StartupGraphics(void)
realheight = (Uint16)vid.height;
VID_Command_Info_f();
- if (!disable_mouse) SDL_ShowCursor(SDL_DISABLE);
SDLdoUngrabMouse();
+ SDL_RaiseWindow(window);
+
+ if (mousegrabok && !disable_mouse)
+ {
+ SDL_ShowCursor(SDL_DISABLE);
+ SDL_SetRelativeMouseMode(SDL_TRUE);
+ wrapmouseok = SDL_TRUE;
+ SDL_SetWindowGrab(window, SDL_TRUE);
+ }
+
graphics_started = true;
}
diff --git a/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj b/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj
index eaac87de..94a3fbb6 100644
--- a/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj
+++ b/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj
@@ -1214,7 +1214,7 @@
C01FCF4B08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
- CURRENT_PROJECT_VERSION = 2.1.20;
+ CURRENT_PROJECT_VERSION = 2.1.23;
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
NORMALSRB2,
@@ -1226,7 +1226,7 @@
C01FCF4C08A954540054247B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
- CURRENT_PROJECT_VERSION = 2.1.20;
+ CURRENT_PROJECT_VERSION = 2.1.23;
GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_PREPROCESSOR_DEFINITIONS = (
diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c
index a0446f87..954ef5ee 100644
--- a/src/sdl/mixer_sound.c
+++ b/src/sdl/mixer_sound.c
@@ -92,6 +92,12 @@ void I_StartupSound(void)
{
I_Assert(!sound_started);
+#ifdef _WIN32
+ // Force DirectSound instead of WASAPI
+ // SDL 2.0.6+ defaults to the latter and it screws up our sound effects
+ SDL_setenv("SDL_AUDIODRIVER", "directsound", 1);
+#endif
+
// EE inits audio first so we're following along.
if (SDL_WasInit(SDL_INIT_AUDIO) == SDL_INIT_AUDIO)
{
@@ -758,6 +764,7 @@ void I_UnloadSong(void)
boolean I_PlaySong(boolean looping)
{
+ boolean lpz = fpclassify(loop_point) == FP_ZERO;
#ifdef HAVE_LIBGME
if (gme)
{
@@ -771,14 +778,15 @@ boolean I_PlaySong(boolean looping)
if (!music)
return false;
- if (Mix_PlayMusic(music, looping && loop_point == 0.0f ? -1 : 0) == -1)
+
+ if (Mix_PlayMusic(music, looping && lpz ? -1 : 0) == -1)
{
CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError());
return false;
}
Mix_VolumeMusic((UINT32)music_volume*128/31);
- if (loop_point != 0.0f)
+ if (!lpz)
Mix_HookMusicFinished(music_loop);
return true;
}
diff --git a/src/sdl/sdl_sound.c b/src/sdl/sdl_sound.c
index ebd615de..9ff1dd0b 100644
--- a/src/sdl/sdl_sound.c
+++ b/src/sdl/sdl_sound.c
@@ -1186,6 +1186,12 @@ void I_StartupSound(void)
// Configure sound device
CONS_Printf("I_StartupSound:\n");
+#ifdef _WIN32
+ // Force DirectSound instead of WASAPI
+ // SDL 2.0.6+ defaults to the latter and it screws up our sound effects
+ SDL_setenv("SDL_AUDIODRIVER", "directsound", 1);
+#endif
+
// EE inits audio first so we're following along.
if (SDL_WasInit(SDL_INIT_AUDIO) == SDL_INIT_AUDIO)
CONS_Printf("SDL Audio already started\n");
diff --git a/src/sdl/sdlmain.h b/src/sdl/sdlmain.h
index 93588ebb..0bc771a7 100644
--- a/src/sdl/sdlmain.h
+++ b/src/sdl/sdlmain.h
@@ -31,6 +31,9 @@ extern SDL_bool framebuffer;
#define SDL2STUB() CONS_Printf("SDL2: stubbed: %s:%d\n", __func__, __LINE__)
#endif
+// So m_menu knows whether to store cv_usejoystick value or string
+#define JOYSTICK_HOTPLUG
+
/** \brief The JoyInfo_s struct
info about joystick
@@ -77,6 +80,20 @@ extern SDLJoyInfo_t JoyInfo4;
void I_GetConsoleEvents(void);
+// So we can call this from i_video event loop
+void I_ShutdownJoystick(void);
+void I_ShutdownJoystick2(void);
+void I_ShutdownJoystick3(void);
+void I_ShutdownJoystick4(void);
+
+// Cheat to get the device index for a joystick handle
+INT32 I_GetJoystickDeviceIndex(SDL_Joystick *dev);
+
+// Quick thing to make SDL_JOYDEVICEADDED events less of an abomination
+void I_UpdateJoystickDeviceIndices(INT32 player);
+
+void I_GetConsoleEvents(void);
+
void SDLforceUngrabMouse(void);
// Needed for some WIN32 functions
diff --git a/src/sdl12/macosx/Srb2mac.xcodeproj/project.pbxproj b/src/sdl12/macosx/Srb2mac.xcodeproj/project.pbxproj
index 574161c6..0ab40c45 100644
--- a/src/sdl12/macosx/Srb2mac.xcodeproj/project.pbxproj
+++ b/src/sdl12/macosx/Srb2mac.xcodeproj/project.pbxproj
@@ -1214,7 +1214,7 @@
C01FCF4B08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
- CURRENT_PROJECT_VERSION = 2.1.20;
+ CURRENT_PROJECT_VERSION = 2.1.23;
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
NORMALSRB2,
@@ -1226,7 +1226,7 @@
C01FCF4C08A954540054247B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
- CURRENT_PROJECT_VERSION = 2.1.20;
+ CURRENT_PROJECT_VERSION = 2.1.23;
GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_PREPROCESSOR_DEFINITIONS = (
diff --git a/src/st_stuff.c b/src/st_stuff.c
index a3429690..10d62498 100644
--- a/src/st_stuff.c
+++ b/src/st_stuff.c
@@ -131,11 +131,6 @@ static patch_t *hud_tv2;
// SRB2kart
-//
-
-static boolean facefreed[MAXPLAYERS];
-boolean iconfreed[MAXPLAYERS];
-
hudinfo_t hudinfo[NUMHUDITEMS] =
{
{ 34, 176}, // HUD_LIVESNAME
@@ -362,7 +357,6 @@ void ST_LoadFaceGraphics(char *rankstr, char *wantstr, char *mmapstr, INT32 skin
facerankprefix[skinnum] = W_CachePatchName(rankstr, PU_HUDGFX);
facewantprefix[skinnum] = W_CachePatchName(wantstr, PU_HUDGFX);
facemmapprefix[skinnum] = W_CachePatchName(mmapstr, PU_HUDGFX);
- facefreed[skinnum] = false;
}
void ST_ReloadSkinFaceGraphics(void)
@@ -411,14 +405,6 @@ lumpnum_t st_borderpatchnum;
void ST_Init(void)
{
- INT32 i;
-
- for (i = 0; i < MAXPLAYERS; i++)
- {
- facefreed[i] = true;
- iconfreed[i] = true;
- }
-
if (dedicated)
return;
diff --git a/src/st_stuff.h b/src/st_stuff.h
index 303b87a5..f96aee93 100644
--- a/src/st_stuff.h
+++ b/src/st_stuff.h
@@ -71,7 +71,6 @@ extern patch_t *facewantprefix[MAXSKINS]; // wanted
extern patch_t *facemmapprefix[MAXSKINS]; // minimap
extern patch_t *livesback;
extern patch_t *ngradeletters[7];
-extern boolean iconfreed[MAXPLAYERS];
/** HUD location information (don't move this comment)
*/
diff --git a/src/tables.c b/src/tables.c
index d4e0e5df..7d513707 100644
--- a/src/tables.c
+++ b/src/tables.c
@@ -37,6 +37,15 @@ unsigned SlopeDiv(unsigned num, unsigned den)
return ans <= SLOPERANGE ? ans : SLOPERANGE;
}
+UINT64 SlopeDivEx(unsigned int num, unsigned int den)
+{
+ UINT64 ans;
+ if (den < 512)
+ return SLOPERANGE;
+ ans = ((UINT64)num<<3)/(den>>8);
+ return ans <= SLOPERANGE ? ans : SLOPERANGE;
+}
+
fixed_t AngleFixed(angle_t af)
{
angle_t wa = ANGLE_180;
diff --git a/src/tables.h b/src/tables.h
index 3aaaec80..2c2f74e1 100644
--- a/src/tables.h
+++ b/src/tables.h
@@ -87,6 +87,8 @@ extern angle_t tantoangle[SLOPERANGE+1];
// Utility function, called by R_PointToAngle.
FUNCMATH unsigned SlopeDiv(unsigned num, unsigned den);
+// Only called by R_PointToAngleEx
+UINT64 SlopeDivEx(unsigned int num, unsigned int den);
// 360 - angle_t(ANGLE_45) = ANGLE_315
FUNCMATH FUNCINLINE static ATTRINLINE angle_t InvAngle(angle_t a)
diff --git a/src/v_video.c b/src/v_video.c
index 90411d4e..eeb2593a 100644
--- a/src/v_video.c
+++ b/src/v_video.c
@@ -860,6 +860,149 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
memset(dest, c, w * vid.bpp);
}
+#ifdef HWRENDER
+// This is now a function since it's otherwise repeated 2 times and honestly looks retarded:
+static UINT32 V_GetHWConsBackColor(void)
+{
+ UINT32 hwcolor;
+ switch (cons_backcolor.value)
+ {
+ case 0: hwcolor = 0xffffff00; break; // White
+ case 1: hwcolor = 0x80808000; break; // Gray
+ case 2: hwcolor = 0xdeb88700; break; // Sepia
+ case 3: hwcolor = 0x40201000; break; // Brown
+ case 4: hwcolor = 0xfa807200; break; // Pink
+ case 5: hwcolor = 0xff69b400; break; // Raspberry
+ case 6: hwcolor = 0xff000000; break; // Red
+ case 7: hwcolor = 0xffd68300; break; // Creamsicle
+ case 8: hwcolor = 0xff800000; break; // Orange
+ case 9: hwcolor = 0xdaa52000; break; // Gold
+ case 10: hwcolor = 0x80800000; break; // Yellow
+ case 11: hwcolor = 0x00ff0000; break; // Emerald
+ case 12: hwcolor = 0x00800000; break; // Green
+ case 13: hwcolor = 0x4080ff00; break; // Cyan
+ case 14: hwcolor = 0x4682b400; break; // Steel
+ case 15: hwcolor = 0x1e90ff00; break; // Periwinkle
+ case 16: hwcolor = 0x0000ff00; break; // Blue
+ case 17: hwcolor = 0xff00ff00; break; // Purple
+ case 18: hwcolor = 0xee82ee00; break; // Lavender
+ // Default green
+ default: hwcolor = 0x00800000; break;
+ }
+ return hwcolor;
+}
+#endif
+
+// THANK YOU MPC!!!
+
+void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
+{
+ UINT8 *dest;
+ INT32 u, v;
+ UINT32 alphalevel = 0;
+
+ if (rendermode == render_none)
+ return;
+
+#ifdef HWRENDER
+ if (rendermode != render_soft && rendermode != render_none)
+ {
+ UINT32 hwcolor = V_GetHWConsBackColor();
+ HWR_DrawConsoleFill(x, y, w, h, hwcolor, c); // we still use the regular color stuff but only for flags. actual draw color is "hwcolor" for this.
+ return;
+ }
+#endif
+
+ if (!(c & V_NOSCALESTART))
+ {
+ INT32 dupx = vid.dupx, dupy = vid.dupy;
+
+ if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT)
+ { // Clear the entire screen, from dest to deststop. Yes, this really works.
+ memset(screens[0], (UINT8)(c&255), vid.width * vid.height * vid.bpp);
+ return;
+ }
+
+ x *= dupx;
+ y *= dupy;
+ w *= dupx;
+ h *= dupy;
+
+ // Center it if necessary
+ if (vid.width != BASEVIDWIDTH * dupx)
+ {
+ // dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx,
+ // so center this imaginary screen
+ if (c & V_SNAPTORIGHT)
+ x += (vid.width - (BASEVIDWIDTH * dupx));
+ else if (!(c & V_SNAPTOLEFT))
+ x += (vid.width - (BASEVIDWIDTH * dupx)) / 2;
+ }
+ if (vid.height != BASEVIDHEIGHT * dupy)
+ {
+ // same thing here
+ if (c & V_SNAPTOBOTTOM)
+ y += (vid.height - (BASEVIDHEIGHT * dupy));
+ else if (!(c & V_SNAPTOTOP))
+ y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2;
+ }
+ }
+
+ if (x >= vid.width || y >= vid.height)
+ return; // off the screen
+ if (x < 0) {
+ w += x;
+ x = 0;
+ }
+ if (y < 0) {
+ h += y;
+ y = 0;
+ }
+
+ if (w <= 0 || h <= 0)
+ return; // zero width/height wouldn't draw anything
+ if (x + w > vid.width)
+ w = vid.width-x;
+ if (y + h > vid.height)
+ h = vid.height-y;
+
+ dest = screens[0] + y*vid.width + x;
+
+ if ((alphalevel = ((c & V_ALPHAMASK) >> V_ALPHASHIFT)))
+ {
+ if (alphalevel == 13)
+ alphalevel = hudminusalpha[cv_translucenthud.value];
+ else if (alphalevel == 14)
+ alphalevel = 10 - cv_translucenthud.value;
+ else if (alphalevel == 15)
+ alphalevel = hudplusalpha[cv_translucenthud.value];
+
+ if (alphalevel >= 10)
+ return; // invis
+ }
+
+ c &= 255;
+
+ if (!alphalevel) {
+ for (v = 0; v < h; v++, dest += vid.width) {
+ for (u = 0; u < w; u++) {
+ dest[u] = consolebgmap[dest[u]];
+ }
+ }
+ } else { // mpc 12-04-2018
+ const UINT8 *fadetable = ((UINT8 *)transtables + ((alphalevel-1)<y) ? y : x
+ w = clip(w,vid.width);
+ h = clip(h,vid.height);
+#undef clip
+ for (v = 0; v < h; v++, dest += vid.width) {
+ for (u = 0; u < w; u++) {
+ dest[u] = fadetable[consolebgmap[dest[u]]];
+ }
+ }
+ }
+}
+
//
// Fills a triangle of pixels with a single color, NOTE: scaled to screen size
//
@@ -961,148 +1104,6 @@ void V_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 c)
}
}
-#ifdef HWRENDER
-// This is now a function since it's otherwise repeated 2 times and honestly looks retarded:
-static UINT32 V_GetHWConsBackColor(void)
-{
- UINT32 hwcolor;
- switch (cons_backcolor.value)
- {
- case 0: hwcolor = 0xffffff00; break; // White
- case 1: hwcolor = 0x80808000; break; // Gray
- case 2: hwcolor = 0xdeb88700; break; // Sepia
- case 3: hwcolor = 0x40201000; break; // Brown
- case 4: hwcolor = 0xfa807200; break; // Pink
- case 5: hwcolor = 0xff69b400; break; // Raspberry
- case 6: hwcolor = 0xff000000; break; // Red
- case 7: hwcolor = 0xffd68300; break; // Creamsicle
- case 8: hwcolor = 0xff800000; break; // Orange
- case 9: hwcolor = 0xdaa52000; break; // Gold
- case 10: hwcolor = 0x80800000; break; // Yellow
- case 11: hwcolor = 0x00ff0000; break; // Emerald
- case 12: hwcolor = 0x00800000; break; // Green
- case 13: hwcolor = 0x4080ff00; break; // Cyan
- case 14: hwcolor = 0x4682b400; break; // Steel
- case 15: hwcolor = 0x1e90ff00; break; // Periwinkle
- case 16: hwcolor = 0x0000ff00; break; // Blue
- case 17: hwcolor = 0xff00ff00; break; // Purple
- case 18: hwcolor = 0xee82ee00; break; // Lavender
- // Default green
- default: hwcolor = 0x00800000; break;
- }
- return hwcolor;
-}
-#endif
-
-// THANK YOU MPC!!!
-
-void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
-{
- UINT8 *dest;
- INT32 u, v;
- UINT32 alphalevel = 0;
-
- if (rendermode == render_none)
- return;
-
-#ifdef HWRENDER
- if (rendermode != render_soft && rendermode != render_none)
- {
- UINT32 hwcolor = V_GetHWConsBackColor();
- HWR_DrawConsoleFill(x, y, w, h, hwcolor, c); // we still use the regular color stuff but only for flags. actual draw color is "hwcolor" for this.
- return;
- }
-#endif
-
- if (!(c & V_NOSCALESTART))
- {
- INT32 dupx = vid.dupx, dupy = vid.dupy;
-
- if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT)
- { // Clear the entire screen, from dest to deststop. Yes, this really works.
- memset(screens[0], (UINT8)(c&255), vid.width * vid.height * vid.bpp);
- return;
- }
-
- x *= dupx;
- y *= dupy;
- w *= dupx;
- h *= dupy;
-
- // Center it if necessary
- if (vid.width != BASEVIDWIDTH * dupx)
- {
- // dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx,
- // so center this imaginary screen
- if (c & V_SNAPTORIGHT)
- x += (vid.width - (BASEVIDWIDTH * dupx));
- else if (!(c & V_SNAPTOLEFT))
- x += (vid.width - (BASEVIDWIDTH * dupx)) / 2;
- }
- if (vid.height != BASEVIDHEIGHT * dupy)
- {
- // same thing here
- if (c & V_SNAPTOBOTTOM)
- y += (vid.height - (BASEVIDHEIGHT * dupy));
- else if (!(c & V_SNAPTOTOP))
- y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2;
- }
- }
-
- if (x >= vid.width || y >= vid.height)
- return; // off the screen
- if (x < 0) {
- w += x;
- x = 0;
- }
- if (y < 0) {
- h += y;
- y = 0;
- }
-
- if (w <= 0 || h <= 0)
- return; // zero width/height wouldn't draw anything
- if (x + w > vid.width)
- w = vid.width-x;
- if (y + h > vid.height)
- h = vid.height-y;
-
- dest = screens[0] + y*vid.width + x;
-
- if ((alphalevel = ((c & V_ALPHAMASK) >> V_ALPHASHIFT)))
- {
- if (alphalevel == 13)
- alphalevel = hudminusalpha[cv_translucenthud.value];
- else if (alphalevel == 14)
- alphalevel = 10 - cv_translucenthud.value;
- else if (alphalevel == 15)
- alphalevel = hudplusalpha[cv_translucenthud.value];
-
- if (alphalevel >= 10)
- return; // invis
- }
-
- c &= 255;
-
- if (!alphalevel) {
- for (v = 0; v < h; v++, dest += vid.width) {
- for (u = 0; u < w; u++) {
- dest[u] = consolebgmap[dest[u]];
- }
- }
- } else { // mpc 12-04-2018
- const UINT8 *fadetable = ((UINT8 *)transtables + ((alphalevel-1)<y) ? y : x
- w = clip(w,vid.width);
- h = clip(h,vid.height);
- for (v = 0; v < h; v++, dest += vid.width) {
- for (u = 0; u < w; u++) {
- dest[u] = fadetable[consolebgmap[dest[u]]];
- }
- }
- }
-}
-
//
// Fills a box of pixels using a flat texture as a pattern, scaled to screen size.
//
diff --git a/src/v_video.h b/src/v_video.h
index 01710c6d..4a904f79 100644
--- a/src/v_video.h
+++ b/src/v_video.h
@@ -162,6 +162,7 @@ void V_DrawFadeConsBack(INT32 plines);
void V_DrawCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed);
// draw a single character, but for the chat
void V_DrawChatCharacter(INT32 x, INT32 y, INT32 c, boolean lowercaseallowed, UINT8 *colormap);
+
UINT8 *V_GetStringColormap(INT32 colorflags);
void V_DrawLevelTitle(INT32 x, INT32 y, INT32 option, const char *string);
diff --git a/src/w_wad.c b/src/w_wad.c
index 512320c2..69b4cb2e 100644
--- a/src/w_wad.c
+++ b/src/w_wad.c
@@ -1728,11 +1728,15 @@ int W_VerifyNMUSlumps(const char *filename)
{"TRANS", 5}, // Translucency map
{"LTFNT", 5}, // Level title font changes
+ {"TTL", 3}, // Act number changes
{"STCFN", 5}, // Console font changes
{"TNYFN", 5}, // Tiny console font changes
- {"MKFNT", 5}, // Kart font changes
+ {"SBO", 3}, // Acceptable HUD changes (Score Time Rings)
+ {"RRINGS", 6}, // Rings HUD (not named as SBO)
+ {"YB_", 3}, // Intermission graphics, goes with the above
+ {"M_", 2}, // As does menu stuff
- {"M_", 2}, // Menu changes
+ {"MKFNT", 5}, // Kart font changes
{"K_", 2}, // Kart graphic changes
{NULL, 0},
diff --git a/src/win32/Srb2win-vc10.vcxproj b/src/win32/Srb2win-vc10.vcxproj
index 5bfa29b8..ca73b129 100644
--- a/src/win32/Srb2win-vc10.vcxproj
+++ b/src/win32/Srb2win-vc10.vcxproj
@@ -1,10 +1,26 @@
+
+ Debug
+ ARM
+
+
+ Debug
+ ARM64
+
Debug
Win32
+
+ Release
+ ARM
+
+
+ Release
+ ARM64
+
Release
Win32
@@ -23,26 +39,49 @@
{0F554F1D-ED49-4D65-A9A7-F63C57F277BE}
Win32Proj
Srb2win
- 8.1
+ 10.0.17763.0
-
- v140
-
+ v140
true
+
+ true
+ true
+ v141
+
+ v140
false
true
+
+ false
+ true
+ true
+ v141
+
+ v140
true
+
+ true
+ true
+ v141
+
+ v140
false
true
+
+ false
+ true
+ true
+ v141
+
@@ -58,23 +97,89 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<_ProjectFileVersion>10.0.30319.1
false
+
+
+ true
+ gdi32.lib;%(AdditionalDependencies)
+
+
+ ProgramDatabase
+ false
+
+
+
+
+ true
+ gdi32.lib;%(AdditionalDependencies)
+
+
+
+
+ ProgramDatabase
+ false
+
+
+ gdi32.lib;%(AdditionalDependencies)
+
+
+
+
+ gdi32.lib;%(AdditionalDependencies)
+
+
+
+
+ gdi32.lib;%(AdditionalDependencies)
+
+
+
+
+ gdi32.lib;%(AdditionalDependencies)
+
+
+
+
+ gdi32.lib;%(AdditionalDependencies)
+
+
+
+
+ gdi32.lib;%(AdditionalDependencies)
+
+
@@ -132,7 +237,7 @@
-
+
diff --git a/src/win32/win_vid.c b/src/win32/win_vid.c
index f355eaea..9f3d13f8 100644
--- a/src/win32/win_vid.c
+++ b/src/win32/win_vid.c
@@ -995,7 +995,7 @@ static INT32 WINAPI VID_SetDirectDrawMode(viddef_t *lvid, vmode_t *currentmode)
// but rather render to memory bitmap buffer
lvid->direct = NULL;
- if (!cv_stretch.value && (float)vid.width/vid.height != ((float)BASEVIDWIDTH/BASEVIDHEIGHT))
+ if (!cv_stretch.value && fabsf((float)vid.width/vid.height - ((float)BASEVIDWIDTH/BASEVIDHEIGHT)) > 1.0E-36f)
vid.height = (int)(vid.width * ((float)BASEVIDHEIGHT/BASEVIDWIDTH));// Adjust the height to match
return 1;
diff --git a/windows-installer/! MAKE SURE FILES ARE IN new-install ARCHIVE FOLDER !.txt b/windows-installer/! MAKE SURE FILES ARE IN new-install ARCHIVE FOLDER !.txt
deleted file mode 100644
index e69de29b..00000000
diff --git a/windows-installer/.gitignore b/windows-installer/.gitignore
deleted file mode 100644
index 40ca3713..00000000
--- a/windows-installer/.gitignore
+++ /dev/null
@@ -1,10 +0,0 @@
-*
-*.*
-!staging
-!sfx
-!uninstaller
-!! MAKE SURE FILES ARE IN new-install ARCHIVE FOLDER !.txt
-!BuildInstaller.bat
-!README.txt
-!VersionFileName.txt
-!.gitignore
diff --git a/windows-installer/BuildInstaller.bat b/windows-installer/BuildInstaller.bat
deleted file mode 100644
index 3a75afb2..00000000
--- a/windows-installer/BuildInstaller.bat
+++ /dev/null
@@ -1,76 +0,0 @@
-@echo off
-
-set "SCRIPTDIR=%~dp0"
-set "SCRIPTDIR=%SCRIPTDIR:~0,-1%"
-
-IF [%SRB2VERSIONNAME%] == [] set /p SRB2VERSIONNAME=<"%SCRIPTDIR%\VersionFileName.txt"
-
-:: Find 7z
-
-set SVZIP=
-
-if NOT [%1] == [] (
- echo.%~1 | findstr /C:"7z" 1>nul
- if NOT errorlevel 1 (
- if exist "%~1" set "SVZIP=%~1"
- )
-)
-
-if ["%SVZIP%"] == [""] (
- if exist "%ProgramFiles(x86)%\7-Zip\7z.exe" set "SVZIP=%ProgramFiles(x86)%\7-Zip\7z.exe"
- if exist "%ProgramFiles%\7-Zip\7z.exe" set "SVZIP=%ProgramFiles%\7-Zip\7z.exe"
- if exist "%ProgramW6432%\7-Zip\7z.exe" set "SVZIP=%ProgramW6432%\7-Zip\7z.exe"
-)
-
-:: Is it in PATH?
-
-if ["%SVZIP%"] == [""] (
- "7z.exe" --help > NUL 2> NUL
- if NOT errorlevel 1 (
- set "SVZIP=7z.exe"
- )
-)
-
-:: Create the uninstaller
-
-if NOT ["%SVZIP%"] == [""] (
- del /f /q "%SCRIPTDIR%\Uninstaller.7z" 2> NUL
- "%SVZIP%" a -t7z "%SCRIPTDIR%\Uninstaller.7z" "%SCRIPTDIR%\uninstaller\*" -m5=LZMA2
- copy /y /b "%SCRIPTDIR%\sfx\7zsd_LZMA2.sfx" + "%SCRIPTDIR%\sfx\config-uninstaller.txt" + "%SCRIPTDIR%\Uninstaller.7z" "%SCRIPTDIR%\staging\new-install\uninstall.exe"
- del /f /q "%SCRIPTDIR%\uninstaller.7z"
-)
-
-:: Operate on install archives
-
-type NUL > "%SCRIPTDIR%\staging\new-install\staging.txt"
-
-if exist "%SCRIPTDIR%\Installer.7z" (
- if NOT ["%SVZIP%"] == [""] (
- "%SVZIP%" a "%SCRIPTDIR%\Installer.7z" "%SCRIPTDIR%\staging\*"
- )
- copy /y /b "%SCRIPTDIR%\sfx\7zsd_LZMA2.sfx" + "%SCRIPTDIR%\sfx\config-installer.txt" + "%SCRIPTDIR%\Installer.7z" "%SCRIPTDIR%\SRB2Kart-%SRB2VERSIONNAME%-Installer.exe"
-)
-
-if exist "%SCRIPTDIR%\Patch.7z" (
- if NOT ["%SVZIP%"] == [""] (
- "%SVZIP%" a "%SCRIPTDIR%\Patch.7z" "%SCRIPTDIR%\staging\*"
- )
- copy /y /b "%SCRIPTDIR%\sfx\7zsd_LZMA2.sfx" + "%SCRIPTDIR%\sfx\config-patch.txt" + "%SCRIPTDIR%\Patch.7z" "%SCRIPTDIR%\SRB2Kart-%SRB2VERSIONNAME%-Patch.exe"
-)
-
-if exist "%SCRIPTDIR%\Installer_x64.7z" (
- if NOT ["%SVZIP%"] == [""] (
- "%SVZIP%" a "%SCRIPTDIR%\Installer_x64.7z" "%SCRIPTDIR%\staging\*"
- )
- copy /y /b "%SCRIPTDIR%\sfx\7zsd_LZMA2_x64.sfx" + "%SCRIPTDIR%\sfx\config-installer.txt" + "%SCRIPTDIR%\Installer_x64.7z" "%SCRIPTDIR%\SRB2Kart-%SRB2VERSIONNAME%-x64-Installer.exe"
-)
-
-if exist "%SCRIPTDIR%\Patch_x64.7z" (
- if NOT ["%SVZIP%"] == [""] (
- "%SVZIP%" a "%SCRIPTDIR%\Patch_x64.7z" "%SCRIPTDIR%\staging\*"
- )
- copy /y /b "%SCRIPTDIR%\sfx\7zsd_LZMA2_x64.sfx" + "%SCRIPTDIR%\sfx\config-patch.txt" + "%SCRIPTDIR%\Patch_x64.7z" "%SCRIPTDIR%\SRB2Kart-%SRB2VERSIONNAME%-x64-Patch.exe"
-)
-
-del /f /q "%SCRIPTDIR%\staging\new-install\staging.txt"
-del /f /q "%SCRIPTDIR%\staging\new-install\uninstall.exe"
diff --git a/windows-installer/README.txt b/windows-installer/README.txt
deleted file mode 100644
index 51b8a7e9..00000000
--- a/windows-installer/README.txt
+++ /dev/null
@@ -1,48 +0,0 @@
-Windows Install Builder
-for SRB2Kart
-
-This installer is much like the 7-Zip self-extracting archive, except
-this allows for scripting the post-install step.
-
-This also allows for some light customization, including dialog messages
-and program shortcuts.
-
-The included install scripts manage the game data location depending on the
-install location -- if installed in Program Files or AppData\Local, the
-game data location is set to %UserProfile%\SRB2Kart.
-
-Program shortcuts are also added, as well as an uninstaller that
-will remove the icons and also selectively uninstall the core game files.
-The uninstaller gives you the option to preserve your game data and mods.
-
-How to Use
-----------
-
-1. Zip up the install contents in 7z format.
- * ALL FILES MUST BE IN THE `new-install/` ARCHIVE SUBFOLDER, OR THE
- POST-INSTALL SCRIPT WILL NOT WORK!
- * Make sure you are using the LZMA2 algorithm, which is 7-Zip's default.
-
-2. Copy the 7z archive to this folder using the following names:
- * Installer.7z - 32-bit full installer
- * Patch.7z - 32-bit patch
- * Installer_x64.7z - 64-bit full installer
- * Patch_x64.7z - 64-bit patch
-
-3. Set the text in VersionFilename.txt to the version identifier for the
- installer's filename.
- * e.g., v102 for v1.0.2, from "SRB2Kart-v102-Installer.exe"
- * Also look through sfx/config-installer.txt and sfx/config-patch.txt
- and update the version strings. Templating is TODO.
-
-4. Run BuildInstaller.bat [7z.exe install path]
- * First argument is the path to 7z.exe. If this is not specified, the
- script will try to look for it in C:\Program Files [(x86)]
- * This script will automatically add the install scripts to each
- installer.
-
-Credit
-------
-
-OlegScherbakov/7zSFX
-https://github.com/OlegScherbakov/7zSFX
diff --git a/windows-installer/VersionFileName.txt b/windows-installer/VersionFileName.txt
deleted file mode 100644
index c65b1654..00000000
--- a/windows-installer/VersionFileName.txt
+++ /dev/null
@@ -1 +0,0 @@
-v102
\ No newline at end of file
diff --git a/windows-installer/sfx/7zsd_LZMA2.sfx b/windows-installer/sfx/7zsd_LZMA2.sfx
deleted file mode 100644
index c4ba9c58..00000000
Binary files a/windows-installer/sfx/7zsd_LZMA2.sfx and /dev/null differ
diff --git a/windows-installer/sfx/7zsd_LZMA2_x64.sfx b/windows-installer/sfx/7zsd_LZMA2_x64.sfx
deleted file mode 100644
index 758e4c2d..00000000
Binary files a/windows-installer/sfx/7zsd_LZMA2_x64.sfx and /dev/null differ
diff --git a/windows-installer/sfx/config-installer.txt b/windows-installer/sfx/config-installer.txt
deleted file mode 100644
index 2811acc7..00000000
--- a/windows-installer/sfx/config-installer.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-;!@Install@!UTF-8!
-
-GUIFlags="8+32+64+4096"
-GUIMode="1"
-
-Title="Sonic Robo Blast 2 Kart v1.0.2"
-BeginPrompt="Sonic Robo Blast 2 Kart v1.0.2\nFull Installer\n\nSelect a folder to install SRB2Kart in.\n\nIf you install in \"AppData\\Local\" or \"Program Files\", your game data will be saved to:\n%UserProfile%\\SRB2Kart\n\nOtherwise, your game data will be in the installation folder.\n\nShortcuts will be created in your Start Menu."
-
-ExtractPathText="Installation folder: (no exclamation points, please!)"
-InstallPath="%LocalAppData%\\SRB2Kart"
-ExtractTitle="Installing..."
-ExtractDialogText="Installing SRB2Kart v1.0.2...\n\nCheck out our modding community!\nWe make levels, characters, and much more!\n\nVisit http://www.srb2.org/mods"
-
-Shortcut="Pu,{%%T\\srb2kart.exe},{},{SRB2Kart},{Sonic Robo Blast 2 Kart (SRB2Kart), a Kart racer built on the SRB2 engine.},{SRB2Kart},{%%T\\},{%%T\\srb2kart.exe},{0}"
-Shortcut="Pu,{%%T\\srb2kart.exe},{-win},{SRB2Kart},{Sonic Robo Blast 2 Kart (SRB2Kart), a Kart racer built on the SRB2 engine.},{SRB2Kart (Windowed)},{%%T\\},{%%T\\srb2kart.exe},{0}"
-Shortcut="Pu,{%%T\\srb2kart.exe},{-opengl},{SRB2Kart},{Sonic Robo Blast 2 Kart (SRB2Kart), a Kart racer built on the SRB2 engine.},{SRB2Kart (OpenGL)},{%%T\\},{%%T\\srb2kart.exe},{0}"
-Shortcut="Pu,{%%T\\srb2kart.exe},{-opengl -win},{SRB2Kart},{Sonic Robo Blast 2 Kart (SRB2Kart), a Kart racer built on the SRB2 engine.},{SRB2Kart (OpenGL, Windowed)},{%%T\\},{%%T\\srb2kart.exe},{0}"
-Shortcut="Pu,{%%T\\uninstall.exe},{},{SRB2Kart},{Sonic Robo Blast 2 Kart (SRB2Kart), a Kart racer built on the SRB2 engine.},{Uninstall SRB2Kart},{%%T\\},{shell32.dll},{31}"
-
-RunProgram="nowait:\"%%T\\new-install\\staging.bat\""
-
-;!@InstallEnd@!
diff --git a/windows-installer/sfx/config-patch.txt b/windows-installer/sfx/config-patch.txt
deleted file mode 100644
index 2b516f8c..00000000
--- a/windows-installer/sfx/config-patch.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-;!@Install@!UTF-8!
-
-GUIFlags="8+32+64+4096"
-GUIMode="1"
-
-Title="Sonic Robo Blast 2 Kart v1.0.2"
-BeginPrompt="Sonic Robo Blast 2 Kart v1.0.2\nPatch Installer\n\nYou must have at least v1.0.0 to use this patch.\n\nSelect your current SRB2Kart folder.\n\nShortcuts will be created in your Start Menu."
-
-ExtractPathText="Current SRB2Kart folder: (no exclamation points, please!)"
-InstallPath="%LocalAppData%\\SRB2Kart"
-ExtractTitle="Installing..."
-ExtractDialogText="Installing SRB2Kart v1.0.2...\n\nCheck out our modding community!\nWe make levels, characters, and much more!\n\nVisit http://www.srb2.org/mods"
-
-Shortcut="Pu,{%%T\\srb2kart.exe},{},{SRB2Kart},{Sonic Robo Blast 2 Kart (SRB2Kart), a Kart racer built on the SRB2 engine.},{SRB2Kart},{%%T\\},{%%T\\srb2kart.exe},{0}"
-Shortcut="Pu,{%%T\\srb2kart.exe},{-win},{SRB2Kart},{Sonic Robo Blast 2 Kart (SRB2Kart), a Kart racer built on the SRB2 engine.},{SRB2Kart (Windowed)},{%%T\\},{%%T\\srb2kart.exe},{0}"
-Shortcut="Pu,{%%T\\srb2kart.exe},{-opengl},{SRB2Kart},{Sonic Robo Blast 2 Kart (SRB2Kart), a Kart racer built on the SRB2 engine.},{SRB2Kart (OpenGL)},{%%T\\},{%%T\\srb2kart.exe},{0}"
-Shortcut="Pu,{%%T\\srb2kart.exe},{-opengl -win},{SRB2Kart},{Sonic Robo Blast 2 Kart (SRB2Kart), a Kart racer built on the SRB2 engine.},{SRB2Kart (OpenGL, Windowed)},{%%T\\},{%%T\\srb2kart.exe},{0}"
-Shortcut="Pu,{%%T\\uninstall.exe},{},{SRB2Kart},{Sonic Robo Blast 2 Kart (SRB2Kart), a Kart racer built on the SRB2 engine.},{Uninstall SRB2Kart},{%%T\\},{shell32.dll},{31}"
-
-RunProgram="nowait:\"%%T\\new-install\\staging.bat\""
-
-;!@InstallEnd@!
diff --git a/windows-installer/sfx/config-uninstaller.txt b/windows-installer/sfx/config-uninstaller.txt
deleted file mode 100644
index 2b35ad23..00000000
--- a/windows-installer/sfx/config-uninstaller.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-;!@Install@!UTF-8!
-
-GUIFlags="1+2+8"
-GUIMode="2"
-
-Title="Uninstall SRB2Kart"
-BeginPrompt="Are you sure you want to uninstall Sonic Robo Blast 2 Kart?\n\nYour game data and mods will be preserved, as well as\nany extra files in your install folder."
-
-InstallPath="%%S"
-
-RunProgram="nowait:\"%%S\\uninstall.bat\" /y"
-
-;!@InstallEnd@!
diff --git a/windows-installer/staging/new-install/old-install-list.txt b/windows-installer/staging/new-install/old-install-list.txt
deleted file mode 100644
index 5fd2adc1..00000000
--- a/windows-installer/staging/new-install/old-install-list.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-exchndl.dll
-fmodex.dll
-libFLAC-8.dll
-libgme.dll
-libintl-8.dll
-libmikmod-2.dll
-libogg-0.dll
-libvorbis-0.dll
-libvorbisfile-3.dll
-r_opengl.dll
-SDL2.dll
-SDL2_mixer.dll
-smpeg2.dll
-srb2kart.exe
\ No newline at end of file
diff --git a/windows-installer/staging/new-install/staging.bat b/windows-installer/staging/new-install/staging.bat
deleted file mode 100644
index 85ca3fd4..00000000
--- a/windows-installer/staging/new-install/staging.bat
+++ /dev/null
@@ -1,363 +0,0 @@
-@echo off
-
-setlocal enabledelayedexpansion
-
-cls
-
-:: SRB2Kart Install Staging
-::
-:: This accomplishes the following tasks:
-::
-:: 1. Creates a user profile folder if SRB2Kart is installed in AppData or Program Files, and config.cfg is not already in the install folder
-::
-:: 2. Moves old installation files into old-install
-::
-:: 3. Moves new installaton files into install folder
-::
-
-:: Get Parent folder (the SRB2Kart install folder)
-::
-:: https://wiert.me/2011/08/30/batch-file-to-get-parent-directory-not-the-directory-of-the-batch-file-but-the-parent-of-that-directory/
-
-set "STAGINGDIR=%~dp0"
-:: strip trailing backslash
-set "STAGINGDIR=!STAGINGDIR:~0,-1!"
-:: ~dp only works for batch file parameters and loop indexes
-for %%d in ("!STAGINGDIR!") do set "INSTALLDIR=%%~dpd"
-set "INSTALLDIR=!INSTALLDIR:~0,-1!"
-
-:: Find 7z
-
-set SVZIP=
-if ["%SVZIP%"] == [""] (
- if exist "!ProgramFiles(x86)!\7-Zip\7z.exe" set "SVZIP=!ProgramFiles(x86)!\7-Zip\7z.exe"
- if exist "!ProgramFiles!\7-Zip\7z.exe" set "SVZIP=!ProgramFiles!\7-Zip\7z.exe"
- if exist "!ProgramW6432!\7-Zip\7z.exe" set "SVZIP=!ProgramW6432!\7-Zip\7z.exe"
-)
-
-:: Is it in PATH?
-
-if ["%SVZIP%"] == [""] (
- "7z.exe" --help > NUL 2> NUL
- if NOT errorlevel 1 (
- set "SVZIP=7z.exe"
- )
-)
-
-:: FAILSAFE: Check if staging.txt exists in the directory
-:: If not, exit, so we don't mess up anything by accident.
-
-if NOT exist "!STAGINGDIR!\staging.txt" (
- exit
-)
-
-: CheckPermissionsInstall
-
-:: Write a dummy file and check for an error. If error, we need administrator rights
-
-:: NOTE: We should never have to deal with this because the main installer should
-:: already have the rights.
-
-mkdir "!INSTALLDIR!\install-dummy"
-
-:: TODO elevate automatically
-if errorlevel 1 (
- echo Finish installing SRB2Kart with these steps:
- echo.
- echo 1. Go to your SRB2Kart install folder
- echo.
- echo !INSTALLDIR!
- echo.
- echo 2. Copy all files from the "new-install" subfolder into the main folder
- echo and DELETE staging.bat and staging.txt!!!
- echo.
- echo 3. Optionally, create a folder in your user profile named "SRB2Kart".
- echo This is where your game data and addons may live.
- echo To create the folder, go here:
- echo.
- echo !USERPROFILE!
- echo.
- echo If anything fails, you may delete the files and try to run the installer
- echo again with Administrator Rights: Right-click on the icon and click
- echo "Run as administrator."
- echo.
- "!SystemRoot!\explorer.exe" "!INSTALLDIR!"
- set /p ADMINFINAL="Press Enter key to exit. "
-
- exit
-) else (
- rmdir /s /q "!INSTALLDIR!\install-dummy"
- goto CheckUserDir
-)
-
-: CheckUserDir
-
-:: Check if we need to create !userprofile!\SRB2Kart
-
-set "USERDIR=!INSTALLDIR!"
-
-:: Is config.cfg in our install dir?
-if exist "!INSTALLDIR!\config.cfg" goto MoveOldInstall
-
-:: Are we in AppData?
-echo.!STAGINGDIR! | findstr /C:"!LocalAppData!" 1>nul
-if errorlevel 1 (
- echo.
-) else (
- goto SetUserDir
-)
-
-: Are we in Program Files?
-echo.!STAGINGDIR! | findstr /C:"!ProgramFiles!" 1>nul
-if NOT errorlevel 1 (
- goto SetUserDir
-)
-
-:: Are we in Program Files (x86)?
-echo.!STAGINGDIR! | findstr /C:"!ProgramFiles(X86)!" 1>nul
-if NOT errorlevel 1 (
- goto SetUserDir
-)
-
-:: Are we 32-bit and actually in Program Files?
-echo.!STAGINGDIR! | findstr /C:"!ProgramW6432!" 1>nul
-if NOT errorlevel 1 (
- goto SetUserDir
-)
-
-goto MoveOldInstall
-
-: SetUserDir
-: CheckPermissionsUserDir
-
-set "USERDIR=!UserProfile!\SRB2Kart"
-
-:: Check for permissions and create the folder
-if exist "!USERDIR!\*" (
- mkdir "!USERDIR!\install-dummy"
-
- if errorlevel 1 (
- echo User profile folder exists, but we won't operate on it.
- echo.
- goto MoveOldInstall
- ) else (
- rmdir /s /q "!USERDIR!\install-dummy"
- )
-) else (
- mkdir "!USERDIR!"
-
- if errorlevel 1 (
- echo Could not create user profile folder
- echo Defaulting to install dir: "!INSTALLDIR!"
- echo.
- set "USERDIR=!INSTALLDIR!"
- goto MoveOldInstall
- )
-)
-
-:: Now copy READMEs
-:: echo f answers xcopy's prompt as to whether the destination is a file or a folder
-echo f | xcopy /y "!STAGINGDIR!\README.txt" "!USERDIR!\README.txt"
-echo f | xcopy /y "!STAGINGDIR!\LICENSE.txt" "!USERDIR!\LICENSE.txt"
-echo f | xcopy /y "!STAGINGDIR!\LICENSE-3RD-PARTY.txt" "!USERDIR!\LICENSE-3RD-PARTY.txt"
-echo Your game data and mods folder is: > "!USERDIR!\^! Data and Mods Go Here ^!.txt"
-echo. >> "!USERDIR!\^! Data and Mods Go Here ^!.txt"
-echo !USERDIR! >> "!USERDIR!\^! Data and Mods Go Here ^!.txt"
-echo. >> "!USERDIR!\^! Data and Mods Go Here ^!.txt"
-echo Your install folder is: >> "!USERDIR!\^! Data and Mods Go Here ^!.txt"
-echo. >> "!USERDIR!\^! Data and Mods Go Here ^!.txt"
-echo !INSTALLDIR! >> "!USERDIR!\^! Data and Mods Go Here ^!.txt"
-echo. >> "!USERDIR!\^! Data and Mods Go Here ^!.txt"
-echo To run SRB2, go to: >> "!USERDIR!\^! Data and Mods Go Here ^!.txt"
-echo. >> "!USERDIR!\^! Data and Mods Go Here ^!.txt"
-echo Start Menu ^> Programs ^> SRB2Kart >> "!USERDIR!\^! Data and Mods Go Here ^!.txt"
-
-:: Copy path to install folder
-
-set "SCRIPT=!TEMP!\!RANDOM!-!RANDOM!-!RANDOM!-!RANDOM!.vbs"
-echo Set oWS = WScript.CreateObject("WScript.Shell") >> "!SCRIPT!"
-echo sLinkFile = "!USERDIR!\^! SRB2Kart Install Folder ^!.lnk" >> "!SCRIPT!"
-echo Set oLink = oWS.CreateShortcut(sLinkFile) >> "!SCRIPT!"
-echo oLink.TargetPath = "!INSTALLDIR!" >> "!SCRIPT!"
-echo oLink.WorkingDirectory = "!INSTALLDIR!" >> "!SCRIPT!"
-echo oLink.Arguments = "" >> "!SCRIPT!"
-echo oLink.IconLocation = "!INSTALLDIR!\srb2kart.exe,0" >> "!SCRIPT!"
-echo oLink.Save >> "!SCRIPT!"
-cscript /nologo "!SCRIPT!"
-del "!SCRIPT!"
-
-:: Also do it the other way around
-
-set "SCRIPT=!TEMP!\!RANDOM!-!RANDOM!-!RANDOM!-!RANDOM!.vbs"
-echo Set oWS = WScript.CreateObject("WScript.Shell") >> "!SCRIPT!"
-echo sLinkFile = "!INSTALLDIR!\^! SRB2Kart Data Folder ^!.lnk" >> "!SCRIPT!"
-echo Set oLink = oWS.CreateShortcut(sLinkFile) >> "!SCRIPT!"
-echo oLink.TargetPath = "!USERDIR!" >> "!SCRIPT!"
-echo oLink.WorkingDirectory = "!USERDIR!" >> "!SCRIPT!"
-echo oLink.Arguments = "" >> "!SCRIPT!"
-echo oLink.IconLocation = "!INSTALLDIR!\srb2kart.exe,0" >> "!SCRIPT!"
-echo oLink.Save >> "!SCRIPT!"
-cscript /nologo "!SCRIPT!"
-del "!SCRIPT!"
-
-: MoveOldInstall
-
-if exist "!INSTALLDIR!\old-install\*" (
- set "OLDINSTALLDIR=!INSTALLDIR!\old-install-!RANDOM!"
-) else (
- set "OLDINSTALLDIR=!INSTALLDIR!\old-install"
-)
-
-mkdir "!OLDINSTALLDIR!"
-
-::
-:: Move all old install files
-:: We support a list of explicit files to copy to old-install
-:: And later, we also loop through our staging files, look for the pre-existing copy in
-:: install root, then copy that also to old-install
-::
-
-:: Extract the uninstall-list.txt and uninstall-userdir.txt files from uninstaller.exe
-:: if it exists
-
-if exist "!INSTALLDIR!\uninstall.exe" (
- if NOT ["!SVZIP!"] == [""] (
- "!SVZIP!" x "!INSTALLDIR!\uninstall.exe" "uninstall-list.txt" -o"!INSTALLDIR!"
- "!SVZIP!" x "!INSTALLDIR!\uninstall.exe" "uninstall-userdir.txt" -o"!INSTALLDIR!"
- )
-)
-
-set OLDINSTALLCHANGED=
-
-if exist "!STAGINGDIR!\old-install-list.txt" (
- goto MoveOldInstallOldFiles
-) else (
- goto MoveOldInstallNewFiles
-)
-
-: MoveOldInstallOldFiles
-
-set "TESTFILE=!TEMP!\!RANDOM!.txt"
-
-:: Do our failsafes before copying the file in the list
-:: See uninstall.bat for details
-for /F "usebackq tokens=*" %%A in ("!STAGINGDIR!\old-install-list.txt") do (
- if exist "!INSTALLDIR!\%%A" (
- if NOT ["%%A"] == [""] (
- if NOT ["%%A"] == ["%~nx0"] (
- echo %%A> "!TESTFILE!"
- findstr /r ".*[<>:\"\"/\\|?*%%].*" "!TESTFILE!" >nul
- if !errorlevel! equ 0 (
- echo %%A has invalid characters, skipping...
- ) else (
- if exist "!INSTALLDIR!\%%A\*" (
- echo %%A is a folder, skipping...
- ) else (
- echo Moving !INSTALLDIR!\%%A to "old-install" folder
- echo f | xcopy /y /v "!INSTALLDIR!\%%A" "!OLDINSTALLDIR!\%%A"
- if errorlevel 0 del /f /q "!INSTALLDIR!\%%A"
- )
- )
- )
- )
- )
-)
-
-del /q /f "!STAGINGDIR!\old-install-list.txt"
-
-for %%F in ("!OLDINSTALLDIR!\*") DO (
- set OLDINSTALLCHANGED=1
- goto MoveOldInstallNewFiles
-)
-
-: MoveOldInstallNewFiles
-
-:: Save a list of standard files
-:: So the uninstall script will know what to remove
-:: Append to any existing file, in case we are a patch
-
-dir /b /a-d "!STAGINGDIR!" >> "!INSTALLDIR!\uninstall-list.txt"
-
-:: Overwrite the last known gamedata folder
-
-echo !USERDIR! > "!INSTALLDIR!\uninstall-userdir.txt"
-
-:: Add the install-generated to the uninstall list
-:: NO FOLLOWING SPACES AFTER THE FILENAME!!!
-
-echo uninstall.bat>> "!INSTALLDIR!\uninstall-list.txt"
-echo uninstall-list.txt>> "!INSTALLDIR!\uninstall-list.txt"
-echo uninstall-userdir.txt>> "!INSTALLDIR!\uninstall-list.txt"
-:: *ahem* Prints as ^! SRB2Kart Data Folder ^!.lnk
-:: We need to escape the exclamations (^^!) and the carets themselves (^^^^)
-echo ^^^^^^! SRB2Kart Data Folder ^^^^^^!.lnk>> "!INSTALLDIR!\uninstall-list.txt"
-
-:: Add the uninstall list files to the uninstall EXE
-
-if NOT ["!SVZIP!"] == [""] (
- if exist "!INSTALLDIR!\new-install\uninstall.exe" (
- "!SVZIP!" a "!INSTALLDIR!\new-install\uninstall.exe" "!INSTALLDIR!\uninstall-list.txt" -sdel
- "!SVZIP!" a "!INSTALLDIR!\new-install\uninstall.exe" "!INSTALLDIR!\uninstall-userdir.txt" -sdel
- )
-)
-
-:: Start moving files
-
-for %%F in ("!STAGINGDIR!\*") DO (
- if exist "!INSTALLDIR!\%%~nxF" (
- set OLDINSTALLCHANGED=1
- move "!INSTALLDIR!\%%~nxF" "!OLDINSTALLDIR!\%%~nxF"
- )
- if NOT ["%%~nxF"] == ["staging.bat"] (
- if NOT ["%%~nxF"] == ["staging.txt"] (
- move "!STAGINGDIR!\%%~nxF" "!INSTALLDIR!\%%~nxF"
- )
- )
-)
-
-: Finished
-
-del /q /f "!INSTALLDIR!\^! SRB2KART INSTALL INSTRUCTIONS ^!.txt"
-
-set MSGEXE=
-if exist "!SystemRoot!\System32\msg.exe" (
- set MSGEXE=!SystemRoot!\System32\msg.exe
-) else (
- if exist "!SystemRoot!\Sysnative\msg.exe" (
- set MSGEXE=!SystemRoot!\Sysnative\msg.exe
- )
-)
-
-if ["!OLDINSTALLCHANGED!"] == ["1"] (
- "!systemroot!\explorer.exe" /select, "!OLDINSTALLDIR!"
- echo Finished^^! Some of your old installation files were moved to the "old-install" folder. > !TEMP!\srb2kartmsgprompt.txt
- echo. >> !TEMP!\srb2kartmsgprompt.txt
- echo If you no longer need these files, you may delete the folder safely. >> !TEMP!\srb2kartmsgprompt.txt
- echo. >> !TEMP!\srb2kartmsgprompt.txt
- echo To run SRB2Kart, go to: Start Menu ^> Programs ^> SRB2Kart. >> !TEMP!\srb2kartmsgprompt.txt
- !MSGEXE! "!username!" < !TEMP!\srb2kartmsgprompt.txt
- del !TEMP!\srb2kartmsgprompt.txt
-) else (
- if /I ["!USERDIR!"] == ["!INSTALLDIR!"] (
- "!systemroot!\explorer.exe" "!INSTALLDIR!"
- echo Finished^^! > !TEMP!\srb2kartmsgprompt.txt
- echo. >> !TEMP!\srb2kartmsgprompt.txt
- echo To run SRB2Kart, go to: Start Menu ^> Programs ^> SRB2Kart. >> !TEMP!\srb2kartmsgprompt.txt
- !MSGEXE! "!username!" < !TEMP!\srb2kartmsgprompt.txt
- del !TEMP!\srb2kartmsgprompt.txt
- ) else (
- "!systemroot!\explorer.exe" "!USERDIR!"
- echo Finished^^! You may find your game data in this folder: > !TEMP!\srb2kartmsgprompt.txt
- echo. >> !TEMP!\srb2kartmsgprompt.txt
- echo !USERDIR! >> !TEMP!\srb2kartmsgprompt.txt
- echo. >> !TEMP!\srb2kartmsgprompt.txt
- echo To run SRB2Kart, go to: Start Menu ^> Programs ^> SRB2Kart. >> !TEMP!\srb2kartmsgprompt.txt
- !MSGEXE! "!username!" < !TEMP!\srb2kartmsgprompt.txt
- del !TEMP!\srb2kartmsgprompt.txt
- )
-)
-
-: Attempt to remove OLDINSTALLDIR, in case it's empty
-rmdir /q "!OLDINSTALLDIR!"
-cd \
-start "" /b "cmd" /s /c " del /f /q "%STAGINGDIR%\*"&rmdir /s /q "%STAGINGDIR%"&exit /b "
diff --git a/windows-installer/uninstaller/uninstall.bat b/windows-installer/uninstaller/uninstall.bat
deleted file mode 100644
index 4a788425..00000000
--- a/windows-installer/uninstaller/uninstall.bat
+++ /dev/null
@@ -1,183 +0,0 @@
-@echo off
-
-setlocal enabledelayedexpansion
-
-cls
-
-set "INSTALLDIR=%~dp0"
-set "INSTALLDIR=!INSTALLDIR:~0,-1!"
-set /p USERDIR=<"!INSTALLDIR!\uninstall-userdir.txt"
-set "USERDIR=!USERDIR:~0,-1!"
-
-: ProceedPrompt
-
-if ["%1"] == ["/y"] (
- set "PROCEED=1"
-) else (
- set PROCEED=
- set /p PROCEED="Are you sure you want to uninstall SRB2Kart? [yes/no] "
-
- if /I ["!PROCEED:~0,1!"] == ["n"] exit
- if /I ["!PROCEED!"] == ["y"] (
- echo Type Yes or No
- echo.
- goto ProceedPrompt
- ) else (
- if /I ["!PROCEED!"] == ["yes"] (
- set PROCEED=1
- ) else (
- echo.
- goto ProceedPrompt
- )
- )
-)
-
-:: Failsafe, in case we Ctrl+C and decline "Terminate batch file?"
-
-if NOT ["!PROCEED!"] == ["1"] (
- exit
-)
-
-: CheckPermissions
-
-:: Write a dummy file and check for an error. If error, we need administrator rights
-
-mkdir "!INSTALLDIR!\uninstall-dummy"
-
-:: TODO elevate automatically
-if errorlevel 1 (
- echo We need Administrator Rights to uninstall SRB2Kart.
- echo.
- echo Try running this uninstaller by right-clicking on the icon
- echo and click "Run as administrator"
- echo.
- set /p ADMINFINAL="Press Enter key to exit. "
- exit
-) else (
- rmdir /s /q "!INSTALLDIR!\uninstall-dummy"
- goto DeleteFiles
-)
-
-: DeleteFiles
-
-:: Our deletion list is a list of filenames, no paths, in the current folder
-::
-:: We apply the following failsafes:
-:: 1. Is filename the script itself?
-:: 2. Does filename have illegal characters? https://stackoverflow.com/a/33625339/241046
-:: 3. Is filename a directory?
-::
-:: TODO hack this to support .\file.txt relative paths
-:: Can %%A be substring'd to get only the filename and extension?
-:: If so, print that to the temp file instead of the whole line
-:: And possibly do the folder check before the invalid char check.
-:: ALSO: Don't honor upward relative paths! (..\)
-::
-set "TESTFILE=!TEMP!\!RANDOM!.txt"
-
-for /F "usebackq tokens=*" %%A in ("!INSTALLDIR!\uninstall-list.txt") do (
- if exist "!INSTALLDIR!\%%A" (
- if NOT ["%%A"] == [""] (
- if NOT ["%%A"] == ["%~nx0"] (
- echo %%A> "!TESTFILE!"
- findstr /r ".*[<>:\"\"/\\|?*%%].*" "!TESTFILE!" >nul
- if !errorlevel! equ 0 (
- echo %%A has invalid characters, skipping...
- ) else (
- if exist "!INSTALLDIR!\%%A\*" (
- echo %%A is a folder, skipping...
- ) else (
- echo Deleting !INSTALLDIR!\%%A
- del /q /f "!INSTALLDIR!\%%A"
- )
- )
- )
- )
- )
-)
-
-del /q /f "!TESTFILE!"
-
-: AllDone
-
-:: Delete the program icons
-echo Deleting your program icons...
-echo.
-
-cd \
-rmdir /s /q "!AppData!\Microsoft\Windows\Start Menu\Programs\SRB2Kart"
-
-:: Check if our install folder is non-empty
-
-set USERDIRFILLED=
-set INSTALLDIRFILLED=
-for /F %%i in ('dir /b /a "!USERDIR!\*"') do (
- if NOT ["%%i"] == ["%~nx0"] (
- set USERDIRFILLED=1
- goto InstallFilledCheck
- )
-)
-
-: InstallFilledCheck
-
-if /I NOT ["!USERDIR!"] == ["!INSTALLDIR!"] (
- for /F %%i in ('dir /b /a "!INSTALLDIR!\*"') do (
- if ["%%i"] == ["%~nx0"] (
- echo.
- ) else (
- set INSTALLDIRFILLED=1
- goto Final
- )
- )
-)
-
-: Final
-
-echo All done^^! Visit http://www.srb2.org if you want to play SRB2Kart again^^!
-echo.
-
-set "FINALPROMPT=Press Enter key to exit."
-if ["!USERDIRFILLED!"] == ["1"] (
- echo We left your game data and mods alone, so you may delete those manually.
- echo.
- echo !USERDIR!
- echo.
- set "FINALPROMPT=Do you want to view your data? [yes/no]"
-)
-
-if ["!INSTALLDIRFILLED!"] == ["1"] (
- echo We left some extra files alone in your install folder.
- echo.
- echo !INSTALLDIR!
- echo.
- set "FINALPROMPT=Do you want to view your data? [yes/no]"
-)
-
-set FINALRESPONSE=
-set /p FINALRESPONSE="!FINALPROMPT! "
-
-if NOT ["!FINALPROMPT!"] == ["Press Enter key to exit."] (
- if /I ["!FINALRESPONSE:~0,1!"] == ["y"] (
- if ["!USERDIRFILLED!"] == ["1"] (
- "!SystemRoot!\explorer.exe" "!USERDIR!"
- )
- if ["!INSTALLDIRFILLED!"] == ["1"] (
- "!SystemRoot!\explorer.exe" "!INSTALLDIR!"
- )
- ) else (
- if ["!FINALRESPONSE!"] == [""] (
- if ["!USERDIRFILLED!"] == ["1"] (
- "!SystemRoot!\explorer.exe" "!USERDIR!"
- )
- if ["!INSTALLDIRFILLED!"] == ["1"] (
- "!SystemRoot!\explorer.exe" "!INSTALLDIR!"
- )
- )
- )
-)
-
-: DeferredDelete
-
-:: Now let's delete our installation folder!
-cd \
-start "" /b "cmd" /s /c " del /q /f "%INSTALLDIR%\uninstall.bat"&timeout /t 2 > NUL&rmdir "%INSTALLDIR%"&exit /b "