Merge branch 'next' into public_next

This commit is contained in:
spherallic 2023-01-31 15:47:11 +01:00
commit 4a1e99729b
73 changed files with 3163 additions and 11601 deletions

View file

@ -6491,7 +6491,7 @@ thingtypes
centerHitbox = true;
flagsvaluetext = "Height";
angletext = "Pitch/Yaw";
fixedrotation = 1;
parametertext = "Degrees?";
}
1706
{
@ -6551,6 +6551,8 @@ thingtypes
height = 160;
unflippable = true;
centerHitbox = true;
angletext = "Pitch/Yaw";
parametertext = "Degrees?";
}
1714
{

View file

@ -37,51 +37,51 @@
<PropertyGroup Label="Globals">
<ProjectGuid>{72B01ACA-7A1A-4F7B-ACEF-2607299CF052}</ProjectGuid>
<RootNamespace>libpng</RootNamespace>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WindowsSDKDesktopARMSupport>true</WindowsSDKDesktopARMSupport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WindowsSDKDesktopARMSupport>true</WindowsSDKDesktopARMSupport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
@ -278,7 +278,7 @@
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..;..\..\..\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;DEBUG;PNG_DEBUG=1;PNG_USE_PNGVCRD;PNG_LIBPNG_SPECIALBUILD;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<AssemblerListingLocation>$(ProjectDir)$(Platform)\$(Configuration)\</AssemblerListingLocation>
@ -288,7 +288,7 @@
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<CompileAs>CompileAsC</CompileAs>
<MultiProcessorCompilation>false</MultiProcessorCompilation>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

View file

@ -37,51 +37,51 @@
<PropertyGroup Label="Globals">
<ProjectGuid>{73A5729C-7323-41D4-AB48-8A03C9F81603}</ProjectGuid>
<RootNamespace>zlib</RootNamespace>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WindowsSDKDesktopARMSupport>true</WindowsSDKDesktopARMSupport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WindowsSDKDesktopARMSupport>true</WindowsSDKDesktopARMSupport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
@ -144,7 +144,7 @@
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<AssemblerListingLocation>$(ProjectDir)$(Platform)\$(Configuration)\</AssemblerListingLocation>
@ -154,7 +154,7 @@
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<CompileAs>CompileAsC</CompileAs>
<MultiProcessorCompilation>false</MultiProcessorCompilation>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

View file

@ -1,89 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual C++ Express 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Srb2win", "src\win32\Srb2win-vc9.vcproj", "{0F554F1D-ED49-4D65-A9A7-F63C57F277BE}"
ProjectSection(ProjectDependencies) = postProject
{73A5729C-7323-41D4-AB48-8A03C9F81603} = {73A5729C-7323-41D4-AB48-8A03C9F81603}
{72B01ACA-7A1A-4F7B-ACEF-2607299CF052} = {72B01ACA-7A1A-4F7B-ACEF-2607299CF052}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpng", "libs\libpng-src\projects\visualc9\libpng.vcproj", "{72B01ACA-7A1A-4F7B-ACEF-2607299CF052}"
ProjectSection(ProjectDependencies) = postProject
{73A5729C-7323-41D4-AB48-8A03C9F81603} = {73A5729C-7323-41D4-AB48-8A03C9F81603}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "r_opengl", "src\hardware\r_opengl\r_opengl-vc9.vcproj", "{51137D5C-4E81-4955-AACF-EA3092006051}"
ProjectSection(ProjectDependencies) = postProject
{0F554F1D-ED49-4D65-A9A7-F63C57F277BE} = {0F554F1D-ED49-4D65-A9A7-F63C57F277BE}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "libs\zlib\projects\visualc9\zlib.vcproj", "{73A5729C-7323-41D4-AB48-8A03C9F81603}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "s_openal", "src\hardware\s_openal\s_openal-vc9.vcproj", "{E662D0B3-412D-4D55-A5EC-8CBD680DDCBE}"
ProjectSection(ProjectDependencies) = postProject
{0F554F1D-ED49-4D65-A9A7-F63C57F277BE} = {0F554F1D-ED49-4D65-A9A7-F63C57F277BE}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Srb2SDL", "src\sdl\Srb2SDL-vc9.vcproj", "{61BA7D3C-F77D-4D31-B718-1177FE482CF2}"
ProjectSection(ProjectDependencies) = postProject
{73A5729C-7323-41D4-AB48-8A03C9F81603} = {73A5729C-7323-41D4-AB48-8A03C9F81603}
{72B01ACA-7A1A-4F7B-ACEF-2607299CF052} = {72B01ACA-7A1A-4F7B-ACEF-2607299CF052}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{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|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|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|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|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|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|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|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|Win32.ActiveCfg = Debug|Win32
{E662D0B3-412D-4D55-A5EC-8CBD680DDCBE}.Debug|x64.ActiveCfg = Debug|x64
{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|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|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
{61BA7D3C-F77D-4D31-B718-1177FE482CF2}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View file

@ -51,7 +51,6 @@ p_spec.c
p_telept.c
p_tick.c
p_user.c
p_haptic.c
p_slopes.c
tables.c
r_bsp.c

View file

@ -188,6 +188,7 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd)
&& !(pcmd->forwardmove || pcmd->sidemove || player->dashspeed)
&& P_IsObjectOnGround(sonic) && P_IsObjectOnGround(tails)
&& !(player->pflags & PF_STASIS)
&& !(player->exiting)
&& bot->charability == CA_FLY)
mem->thinkstate = AI_THINKFLY;
else if (mem->thinkstate == AI_THINKFLY)

View file

@ -12,6 +12,10 @@
#include <stdarg.h>
#include <stddef.h>
#ifdef _MSC_VER
#include <stdint.h>
#endif
#include "luaconf.h"

View file

@ -11,9 +11,7 @@
#include <limits.h>
#include <stddef.h>
#ifdef _MSC_VER
#define INT32 __int32
#else
#ifndef _MSC_VER
#include <stdint.h>
#define INT32 int32_t
#endif
@ -147,7 +145,7 @@
** CHANGE that if ptrdiff_t is not adequate on your machine. (On most
** machines, ptrdiff_t gives a good choice between int or long.)
*/
#define LUA_INTEGER INT32
#define LUA_INTEGER int32_t
/*
@ -509,13 +507,13 @@
*/
//#define LUA_NUMBER_DOUBLE
#define LUA_NUMBER INT32
#define LUA_NUMBER int32_t
/*
@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
@* over a number.
*/
#define LUAI_UACNUMBER INT32
#define LUAI_UACNUMBER int32_t
/*
@ -778,6 +776,4 @@ union luai_Cast { double l_d; long l_l; };
** without modifying the main part of the file.
*/
#endif

View file

@ -150,7 +150,7 @@ FUNCINLINE static ATTRINLINE UINT32 readulong(void *ptr)
#undef DEALIGNED
#define WRITESTRINGN(p, s, n) ({ \
#define WRITESTRINGN(p, s, n) { \
size_t tmp_i; \
\
for (tmp_i = 0; tmp_i < n && s[tmp_i] != '\0'; tmp_i++) \
@ -158,70 +158,70 @@ FUNCINLINE static ATTRINLINE UINT32 readulong(void *ptr)
\
if (tmp_i < n) \
WRITECHAR(p, '\0'); \
})
}
#define WRITESTRINGL(p, s, n) ({ \
#define WRITESTRINGL(p, s, n) { \
size_t tmp_i; \
\
for (tmp_i = 0; tmp_i < n - 1 && s[tmp_i] != '\0'; tmp_i++) \
WRITECHAR(p, s[tmp_i]); \
\
WRITECHAR(p, '\0'); \
})
}
#define WRITESTRING(p, s) ({ \
#define WRITESTRING(p, s) { \
size_t tmp_i; \
\
for (tmp_i = 0; s[tmp_i] != '\0'; tmp_i++) \
WRITECHAR(p, s[tmp_i]); \
\
WRITECHAR(p, '\0'); \
})
}
#define WRITEMEM(p, s, n) ({ \
#define WRITEMEM(p, s, n) { \
memcpy(p, s, n); \
p += n; \
})
}
#define SKIPSTRING(p) while (READCHAR(p) != '\0')
#define SKIPSTRINGN(p, n) ({ \
#define SKIPSTRINGN(p, n) { \
size_t tmp_i = 0; \
\
while (tmp_i < n && READCHAR(p) != '\0') \
tmp_i++; \
})
}
#define SKIPSTRINGL(p, n) SKIPSTRINGN(p, n)
#define READSTRINGN(p, s, n) ({ \
#define READSTRINGN(p, s, n) { \
size_t tmp_i = 0; \
\
while (tmp_i < n && (s[tmp_i] = READCHAR(p)) != '\0') \
tmp_i++; \
\
s[tmp_i] = '\0'; \
})
}
#define READSTRINGL(p, s, n) ({ \
#define READSTRINGL(p, s, n) { \
size_t tmp_i = 0; \
\
while (tmp_i < n - 1 && (s[tmp_i] = READCHAR(p)) != '\0') \
tmp_i++; \
\
s[tmp_i] = '\0'; \
})
}
#define READSTRING(p, s) ({ \
#define READSTRING(p, s) { \
size_t tmp_i = 0; \
\
while ((s[tmp_i] = READCHAR(p)) != '\0') \
tmp_i++; \
\
s[tmp_i] = '\0'; \
})
}
#define READMEM(p, s, n) ({ \
#define READMEM(p, s, n) { \
memcpy(s, p, n); \
p += n; \
})
}

View file

@ -78,6 +78,7 @@ CV_PossibleValue_t CV_Natural[] = {{1, "MIN"}, {999999999, "MAX"}, {0, NULL}};
// Filter consvars by EXECVERSION
// First implementation is 26 (2.1.21), so earlier configs default at 25 (2.1.20)
// Also set CV_HIDEN during runtime, after config is loaded
static boolean execversion_enabled = false;
consvar_t cv_execversion = CVAR_INIT ("execversion","25",CV_CALL,CV_Unsigned, CV_EnforceExecVersion);
@ -1728,9 +1729,13 @@ void CV_SaveVars(UINT8 **p, boolean in_demo)
if ((cvar->flags & CV_NETVAR) && !CV_IsSetToDefault(cvar))
{
if (in_demo)
{
WRITESTRING(*p, cvar->name);
}
else
{
WRITEUINT16(*p, cvar->netid);
}
WRITESTRING(*p, cvar->string);
WRITEUINT8(*p, false);
++count;
@ -2233,12 +2238,12 @@ static boolean CV_FilterJoyAxisVars(consvar_t *v, const char *valstr)
// reset all axis settings to defaults
if (joyaxis_count == 6)
{
COM_BufInsertText(va("%s \"%s\"\n", cv_turnaxis[0].name, cv_turnaxis[0].defaultvalue));
COM_BufInsertText(va("%s \"%s\"\n", cv_moveaxis[0].name, cv_moveaxis[0].defaultvalue));
COM_BufInsertText(va("%s \"%s\"\n", cv_sideaxis[0].name, cv_sideaxis[0].defaultvalue));
COM_BufInsertText(va("%s \"%s\"\n", cv_lookaxis[0].name, cv_lookaxis[0].defaultvalue));
COM_BufInsertText(va("%s \"%s\"\n", cv_fireaxis[0].name, cv_fireaxis[0].defaultvalue));
COM_BufInsertText(va("%s \"%s\"\n", cv_firenaxis[0].name, cv_firenaxis[0].defaultvalue));
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_sideaxis.name, cv_sideaxis.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_firenaxis.name, cv_firenaxis.defaultvalue));
joyaxis_count++;
return false;
}
@ -2292,12 +2297,12 @@ static boolean CV_FilterJoyAxisVars(consvar_t *v, const char *valstr)
// reset all axis settings to defaults
if (joyaxis2_count == 6)
{
COM_BufInsertText(va("%s \"%s\"\n", cv_turnaxis[1].name, cv_turnaxis[1].defaultvalue));
COM_BufInsertText(va("%s \"%s\"\n", cv_moveaxis[1].name, cv_moveaxis[1].defaultvalue));
COM_BufInsertText(va("%s \"%s\"\n", cv_sideaxis[1].name, cv_sideaxis[1].defaultvalue));
COM_BufInsertText(va("%s \"%s\"\n", cv_lookaxis[1].name, cv_lookaxis[1].defaultvalue));
COM_BufInsertText(va("%s \"%s\"\n", cv_fireaxis[1].name, cv_fireaxis[1].defaultvalue));
COM_BufInsertText(va("%s \"%s\"\n", cv_firenaxis[1].name, cv_firenaxis[1].defaultvalue));
COM_BufInsertText(va("%s \"%s\"\n", cv_turnaxis2.name, cv_turnaxis2.defaultvalue));
COM_BufInsertText(va("%s \"%s\"\n", cv_moveaxis2.name, cv_moveaxis2.defaultvalue));
COM_BufInsertText(va("%s \"%s\"\n", cv_sideaxis2.name, cv_sideaxis2.defaultvalue));
COM_BufInsertText(va("%s \"%s\"\n", cv_lookaxis2.name, cv_lookaxis2.defaultvalue));
COM_BufInsertText(va("%s \"%s\"\n", cv_fireaxis2.name, cv_fireaxis2.defaultvalue));
COM_BufInsertText(va("%s \"%s\"\n", cv_firenaxis2.name, cv_firenaxis2.defaultvalue));
joyaxis2_count++;
return false;
}
@ -2307,49 +2312,6 @@ static boolean CV_FilterJoyAxisVars(consvar_t *v, const char *valstr)
return true;
}
#ifndef OLD_GAMEPAD_AXES
static boolean CV_ConvertOldJoyAxisVars(consvar_t *v, const char *valstr)
{
static struct {
const char *old;
const char *new;
} axis_names[] = {
{"X-Axis", "Left Stick X"},
{"Y-Axis", "Left Stick Y"},
{"X-Axis-", "Left Stick X-"},
{"Y-Axis-", "Left Stick Y-"},
{"X-Rudder", "Right Stick X"},
{"Y-Rudder", "Right Stick Y"},
{"X-Rudder-", "Right Stick X-"},
{"Y-Rudder-", "Right Stick Y-"},
{"Z-Axis", "Left Trigger"},
{"Z-Rudder", "Right Trigger"},
{"Z-Axis-", "Left Trigger"},
{"Z-Rudder-", "Right Trigger"},
{NULL, NULL}
};
if (v->PossibleValue != joyaxis_cons_t)
return true;
for (unsigned i = 0;; i++)
{
if (axis_names[i].old == NULL)
{
CV_SetCVar(v, "None", false);
return false;
}
else if (!stricmp(valstr, axis_names[i].old))
{
CV_SetCVar(v, axis_names[i].new, false);
return false;
}
}
return true;
}
#endif
static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr)
{
// True means allow the CV change, False means block it
@ -2378,8 +2340,8 @@ static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr)
&& atoi(valstr) == 35)
return false;
// GAMEPAD DEFAULTS
// use_gamepad was changed from 0 to 1 to automatically use a gamepad if available
// JOYSTICK DEFAULTS
// use_joystick was changed from 0 to 1 to automatically use a joystick if available
#if defined(HAVE_SDL) || defined(_WINDOWS)
if ((!stricmp(v->name, "use_joystick")
|| !stricmp(v->name, "use_joystick2"))
@ -2392,15 +2354,6 @@ static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr)
if (!CV_FilterJoyAxisVars(v, valstr))
return false;
}
#ifndef OLD_GAMEPAD_AXES
if (GETMAJOREXECVERSION(cv_execversion.value) <= 51 && GETMINOREXECVERSION(cv_execversion.value) < 1)
{
if (!CV_ConvertOldJoyAxisVars(v, valstr))
return false;
}
#endif
return true;
}

View file

@ -918,8 +918,7 @@ boolean CON_Responder(event_t *ev)
static INT32 alias_skips;
const char *cmd = NULL;
INT32 key = ev->key;
boolean key_is_console = (key == gamecontrol[GC_CONSOLE][0] || key == gamecontrol[GC_CONSOLE][1]);
INT32 key;
if (chat_on)
return false;
@ -927,18 +926,20 @@ boolean CON_Responder(event_t *ev)
// let go keyup events, don't eat them
if (ev->type != ev_keydown && ev->type != ev_console)
{
if (key_is_console)
if (ev->key == gamecontrol[GC_CONSOLE][0] || ev->key == gamecontrol[GC_CONSOLE][1])
consdown = false;
return false;
}
key = ev->key;
// check for console toggle key
if (ev->type != ev_console)
{
if (modeattacking || metalrecording || marathonmode)
return false;
if (key_is_console)
if (key == gamecontrol[GC_CONSOLE][0] || key == gamecontrol[GC_CONSOLE][1])
{
if (consdown) // ignore repeat
return true;

View file

@ -25,8 +25,7 @@
#include "st_stuff.h"
#include "hu_stuff.h"
#include "keys.h"
#include "g_input.h"
#include "i_gamepad.h"
#include "g_input.h" // JOY1
#include "m_menu.h"
#include "console.h"
#include "d_netfil.h"
@ -34,7 +33,6 @@
#include "p_saveg.h"
#include "z_zone.h"
#include "p_local.h"
#include "p_haptic.h"
#include "m_misc.h"
#include "am_map.h"
#include "m_random.h"
@ -51,7 +49,7 @@
#include "m_perfstats.h"
// aaaaaa
#include "i_gamepad.h"
#include "i_joy.h"
#ifndef NONET
// cl loading screen
@ -655,6 +653,22 @@ static UINT8 Snake_GetOppositeDir(UINT8 dir)
return 12 + 5 - dir;
}
event_t *snakejoyevents[MAXEVENTS];
UINT16 joyeventcount = 0;
// I'm screaming the hack is clean - ashi
static boolean Snake_Joy_Grabber(event_t *ev)
{
if (ev->type == ev_joystick && ev->key == 0)
{
snakejoyevents[joyeventcount] = ev;
joyeventcount++;
return true;
}
else
return false;
}
static void Snake_FindFreeSlot(UINT8 *freex, UINT8 *freey, UINT8 headx, UINT8 heady)
{
UINT8 x, y;
@ -681,17 +695,19 @@ static void Snake_Handle(void)
UINT8 x, y;
UINT8 oldx, oldy;
UINT16 i;
UINT16 j;
UINT16 joystate = 0;
static INT32 pjoyx = 0, pjoyy = 0;
// Handle retry
if (snake->gameover && (G_PlayerInputDown(0, GC_JUMP) || gamekeydown[KEY_ENTER]))
if (snake->gameover && (PLAYER1INPUTDOWN(GC_JUMP) || gamekeydown[KEY_ENTER]))
{
Snake_Initialise();
snake->pausepressed = true; // Avoid accidental pause on respawn
}
// Handle pause
if (G_PlayerInputDown(0, GC_PAUSE) || gamekeydown[KEY_ENTER])
if (PLAYER1INPUTDOWN(GC_PAUSE) || gamekeydown[KEY_ENTER])
{
if (!snake->pausepressed)
snake->paused = !snake->paused;
@ -710,23 +726,58 @@ static void Snake_Handle(void)
oldx = snake->snakex[1];
oldy = snake->snakey[1];
// process the input events in here dear lord
for (j = 0; j < joyeventcount; j++)
{
event_t *ev = snakejoyevents[j];
const INT32 jdeadzone = (JOYAXISRANGE * cv_digitaldeadzone.value) / FRACUNIT;
if (ev->y != INT32_MAX)
{
if (Joystick.bGamepadStyle || abs(ev->y) > jdeadzone)
{
if (ev->y < 0 && pjoyy >= 0)
joystate = 1;
else if (ev->y > 0 && pjoyy <= 0)
joystate = 2;
pjoyy = ev->y;
}
else
pjoyy = 0;
}
if (ev->x != INT32_MAX)
{
if (Joystick.bGamepadStyle || abs(ev->x) > jdeadzone)
{
if (ev->x < 0 && pjoyx >= 0)
joystate = 3;
else if (ev->x > 0 && pjoyx <= 0)
joystate = 4;
pjoyx = ev->x;
}
else
pjoyx = 0;
}
}
joyeventcount = 0;
// Update direction
if (G_PlayerInputDown(0, GC_STRAFELEFT) || gamekeydown[KEY_LEFTARROW] || joystate == 3)
if (PLAYER1INPUTDOWN(GC_STRAFELEFT) || gamekeydown[KEY_LEFTARROW] || joystate == 3)
{
if (snake->snakelength < 2 || x <= oldx)
snake->snakedir[0] = 1;
}
else if (G_PlayerInputDown(0, GC_STRAFERIGHT) || gamekeydown[KEY_RIGHTARROW] || joystate == 4)
else if (PLAYER1INPUTDOWN(GC_STRAFERIGHT) || gamekeydown[KEY_RIGHTARROW] || joystate == 4)
{
if (snake->snakelength < 2 || x >= oldx)
snake->snakedir[0] = 2;
}
else if (G_PlayerInputDown(0, GC_FORWARD) || gamekeydown[KEY_UPARROW] || joystate == 1)
else if (PLAYER1INPUTDOWN(GC_FORWARD) || gamekeydown[KEY_UPARROW] || joystate == 1)
{
if (snake->snakelength < 2 || y <= oldy)
snake->snakedir[0] = 3;
}
else if (G_PlayerInputDown(0, GC_BACKWARD) || gamekeydown[KEY_DOWNARROW] || joystate == 2)
else if (PLAYER1INPUTDOWN(GC_BACKWARD) || gamekeydown[KEY_DOWNARROW] || joystate == 2)
{
if (snake->snakelength < 2 || y >= oldy)
snake->snakedir[0] = 4;
@ -1652,8 +1703,6 @@ static void CL_LoadReceivedSavegame(boolean reloading)
titledemo = false;
automapactive = false;
P_StopRumble(NULL);
// load a base level
if (P_LoadNetGame(reloading))
{
@ -1940,10 +1989,9 @@ void CL_UpdateServerList(boolean internetsearch, INT32 room)
static void M_ConfirmConnect(event_t *ev)
{
#ifndef NONET
if (ev->type == ev_keydown || ev->type == ev_gamepad_down)
if (ev->type == ev_keydown)
{
if ((ev->type == ev_keydown && (ev->key == ' ' || ev->key == 'y' || ev->key == KEY_ENTER)) || (ev->type == ev_gamepad_down && ev->which == 0 && ev->key == GAMEPAD_BUTTON_A))
if (ev->key == ' ' || ev->key == 'y' || ev->key == KEY_ENTER || ev->key == KEY_JOY1)
{
if (totalfilesrequestednum > 0)
{
@ -1958,7 +2006,7 @@ static void M_ConfirmConnect(event_t *ev)
M_ClearMenus(true);
}
else if ((ev->type == ev_keydown && (ev->key == 'n' || ev->key == KEY_ESCAPE)) || (ev->type == ev_gamepad_down && ev->which == 0 && ev->key == GAMEPAD_BUTTON_B))
else if (ev->key == 'n' || ev->key == KEY_ESCAPE || ev->key == KEY_JOY1 + 3)
{
cl_mode = CL_ABORTED;
M_ClearMenus(true);
@ -2392,11 +2440,14 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
// my hand has been forced and I am dearly sorry for this awful hack :vomit:
for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1))
{
G_MapEventsToControls(&events[eventtail]);
#ifndef NONET
if (!Snake_Joy_Grabber(&events[eventtail]))
#endif
G_MapEventsToControls(&events[eventtail]);
}
}
if (gamekeydown[KEY_ESCAPE] || gamepads[0].buttons[GAMEPAD_BUTTON_B] || cl_mode == CL_ABORTED)
if (gamekeydown[KEY_ESCAPE] || gamekeydown[KEY_JOY1+1] || cl_mode == CL_ABORTED)
{
CONS_Printf(M_GetText("Network game synchronization aborted.\n"));
M_StartMessage(M_GetText("Network game synchronization aborted.\n\nPress ESC\n"), NULL, MM_NOTHING);
@ -3469,7 +3520,7 @@ consvar_t cv_resynchattempts = CVAR_INIT ("resynchattempts", "10", CV_SAVE|CV_NE
consvar_t cv_blamecfail = CVAR_INIT ("blamecfail", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL);
// max file size to send to a player (in kilobytes)
static CV_PossibleValue_t maxsend_cons_t[] = {{0, "MIN"}, {51200, "MAX"}, {0, NULL}};
static CV_PossibleValue_t maxsend_cons_t[] = {{0, "MIN"}, {204800, "MAX"}, {0, NULL}};
consvar_t cv_maxsend = CVAR_INIT ("maxsend", "4096", CV_SAVE|CV_NETVAR, maxsend_cons_t, NULL);
consvar_t cv_noticedownload = CVAR_INIT ("noticedownload", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL);
@ -5179,7 +5230,7 @@ static void Local_Maketic(INT32 realtics)
// game responder calls HU_Responder, AM_Responder,
// and G_MapEventsToControls
if (!dedicated) rendergametic = gametic;
// translate inputs (keyboard/mouse/gamepad) into game controls
// translate inputs (keyboard/mouse/joystick) into game controls
G_BuildTiccmd(&localcmds, realtics, 1);
if (splitscreen || botingame)
G_BuildTiccmd(&localcmds2, realtics, 2);

View file

@ -24,21 +24,19 @@ typedef enum
ev_keyup,
ev_console,
ev_mouse,
ev_joystick,
ev_mouse2,
ev_gamepad_up,
ev_gamepad_down,
ev_gamepad_axis
ev_joystick2,
} evtype_t;
// Event structure.
typedef struct
{
evtype_t type;
INT32 key; // key, mouse button, or gamepad button/axis type
INT32 x; // mouse x move, or gamepad axis value
INT32 y; // mouse y move
UINT8 which; // which gamepad or mouse ID
boolean repeated; // is the event repeated?
INT32 key; // keys/mouse/joystick buttons
INT32 x; // mouse/joystick x move
INT32 y; // mouse/joystick y move
boolean repeated; // key repeat
} event_t;
//

View file

@ -43,7 +43,6 @@
#include "i_time.h"
#include "i_threads.h"
#include "i_video.h"
#include "i_gamepad.h"
#include "m_argv.h"
#include "m_menu.h"
#include "m_misc.h"
@ -987,7 +986,6 @@ void D_StartTitle(void)
G_SetGametype(GT_COOP);
paused = false;
advancedemo = false;
P_StopRumble(NULL);
F_InitMenuPresValues();
F_StartTitleScreen();
@ -1398,9 +1396,6 @@ void D_SRB2Main(void)
CONS_Printf("I_InitializeTime()...\n");
I_InitializeTime();
// Initializes the game logic side of gamepads
G_InitGamepads();
// Make backups of some SOCcable tables.
P_BackupTables();
@ -1456,9 +1451,6 @@ void D_SRB2Main(void)
D_RegisterServerCommands();
D_RegisterClientCommands(); // be sure that this is called before D_CheckNetGame
I_InitGamepads();
R_RegisterEngineStuff();
S_RegisterSoundStuff();

View file

@ -21,7 +21,6 @@
#include "g_game.h"
#include "hu_stuff.h"
#include "g_input.h"
#include "i_gamepad.h"
#include "m_menu.h"
#include "r_local.h"
#include "r_skins.h"
@ -50,6 +49,7 @@
#include "m_anigif.h"
#include "md5.h"
#include "m_perfstats.h"
#include "hardware/u_list.h" // TODO: this should be a standard utility class
#ifdef NETGAME_DEVMODE
#define CV_RESTRICT CV_NETVAR
@ -182,6 +182,14 @@ static CV_PossibleValue_t mouse2port_cons_t[] = {{1, "COM1"}, {2, "COM2"}, {3, "
{0, NULL}};
#endif
#ifdef LJOYSTICK
static CV_PossibleValue_t joyport_cons_t[] = {{1, "/dev/js0"}, {2, "/dev/js1"}, {3, "/dev/js2"},
{4, "/dev/js3"}, {0, NULL}};
#else
// accept whatever value - it is in fact the joystick device number
#define usejoystick_cons_t NULL
#endif
static CV_PossibleValue_t teamscramble_cons_t[] = {{0, "Off"}, {1, "Random"}, {2, "Points"}, {0, NULL}};
static CV_PossibleValue_t startingliveslimit_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, NULL}};
@ -240,61 +248,19 @@ INT32 cv_debug;
consvar_t cv_usemouse = CVAR_INIT ("use_mouse", "On", CV_SAVE|CV_CALL,usemouse_cons_t, I_StartupMouse);
consvar_t cv_usemouse2 = CVAR_INIT ("use_mouse2", "Off", CV_SAVE|CV_CALL,usemouse_cons_t, I_StartupMouse2);
// We use cv_usegamepad.string as the USER-SET var
// and cv_usegamepad.value as the INTERNAL var
//
// In practice, if cv_usegamepad.string == 0, this overrides
// cv_usegamepad.value and always disables
static void UseGamepad_OnChange(void)
{
I_ChangeGamepad(0);
}
static void UseGamepad2_OnChange(void)
{
I_ChangeGamepad(1);
}
consvar_t cv_usegamepad[2] = {
CVAR_INIT ("use_gamepad", "1", CV_SAVE|CV_CALL, NULL, UseGamepad_OnChange),
CVAR_INIT ("use_gamepad2", "2", CV_SAVE|CV_CALL, NULL, UseGamepad2_OnChange)
};
static void PadScale_OnChange(void)
{
I_SetGamepadDigital(0, cv_gamepad_scale[0].value == 0);
}
static void PadScale2_OnChange(void)
{
I_SetGamepadDigital(1, cv_gamepad_scale[1].value == 0);
}
consvar_t cv_gamepad_scale[2] = {
CVAR_INIT ("padscale", "1", CV_SAVE|CV_CALL, NULL, PadScale_OnChange),
CVAR_INIT ("padscale2", "1", CV_SAVE|CV_CALL, NULL, PadScale2_OnChange)
};
static void PadRumble_OnChange(void)
{
if (!cv_gamepad_rumble[0].value)
I_StopGamepadRumble(0);
}
static void PadRumble2_OnChange(void)
{
if (!cv_gamepad_rumble[1].value)
I_StopGamepadRumble(1);
}
consvar_t cv_gamepad_rumble[2] = {
CVAR_INIT ("padrumble", "Off", CV_SAVE|CV_CALL, CV_OnOff, PadRumble_OnChange),
CVAR_INIT ("padrumble2", "Off", CV_SAVE|CV_CALL, CV_OnOff, PadRumble2_OnChange)
};
consvar_t cv_gamepad_autopause = CVAR_INIT ("pauseongamepaddisconnect", "On", CV_SAVE, CV_OnOff, NULL);
consvar_t cv_usejoystick = CVAR_INIT ("use_gamepad", "1", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick);
consvar_t cv_usejoystick2 = CVAR_INIT ("use_gamepad2", "2", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick2);
#if (defined (LJOYSTICK) || defined (HAVE_SDL))
#ifdef LJOYSTICK
consvar_t cv_joyport = CVAR_INIT ("padport", "/dev/js0", CV_SAVE, joyport_cons_t, NULL);
consvar_t cv_joyport2 = CVAR_INIT ("padport2", "/dev/js0", CV_SAVE, joyport_cons_t, NULL); //Alam: for later
#endif
consvar_t cv_joyscale = CVAR_INIT ("padscale", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale);
consvar_t cv_joyscale2 = CVAR_INIT ("padscale2", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale2);
#else
consvar_t cv_joyscale = CVAR_INIT ("padscale", "1", CV_SAVE|CV_HIDEN, NULL, NULL); //Alam: Dummy for save
consvar_t cv_joyscale2 = CVAR_INIT ("padscale2", "1", CV_SAVE|CV_HIDEN, NULL, NULL); //Alam: Dummy for save
#endif
#if defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON)
consvar_t cv_mouse2port = CVAR_INIT ("mouse2port", "/dev/gpmdata", CV_SAVE, mouse2port_cons_t, NULL);
consvar_t cv_mouse2opt = CVAR_INIT ("mouse2opt", "0", CV_SAVE, NULL, NULL);
@ -806,26 +772,26 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_pauseifunfocused);
// g_input.c
CV_RegisterVar(&cv_sideaxis[0]);
CV_RegisterVar(&cv_sideaxis[1]);
CV_RegisterVar(&cv_turnaxis[0]);
CV_RegisterVar(&cv_turnaxis[1]);
CV_RegisterVar(&cv_moveaxis[0]);
CV_RegisterVar(&cv_moveaxis[1]);
CV_RegisterVar(&cv_lookaxis[0]);
CV_RegisterVar(&cv_lookaxis[1]);
CV_RegisterVar(&cv_jumpaxis[0]);
CV_RegisterVar(&cv_jumpaxis[1]);
CV_RegisterVar(&cv_spinaxis[0]);
CV_RegisterVar(&cv_spinaxis[1]);
CV_RegisterVar(&cv_fireaxis[0]);
CV_RegisterVar(&cv_fireaxis[1]);
CV_RegisterVar(&cv_firenaxis[0]);
CV_RegisterVar(&cv_firenaxis[1]);
CV_RegisterVar(&cv_deadzone[0]);
CV_RegisterVar(&cv_deadzone[1]);
CV_RegisterVar(&cv_digitaldeadzone[0]);
CV_RegisterVar(&cv_digitaldeadzone[1]);
CV_RegisterVar(&cv_sideaxis);
CV_RegisterVar(&cv_sideaxis2);
CV_RegisterVar(&cv_turnaxis);
CV_RegisterVar(&cv_turnaxis2);
CV_RegisterVar(&cv_moveaxis);
CV_RegisterVar(&cv_moveaxis2);
CV_RegisterVar(&cv_lookaxis);
CV_RegisterVar(&cv_lookaxis2);
CV_RegisterVar(&cv_jumpaxis);
CV_RegisterVar(&cv_jumpaxis2);
CV_RegisterVar(&cv_spinaxis);
CV_RegisterVar(&cv_spinaxis2);
CV_RegisterVar(&cv_fireaxis);
CV_RegisterVar(&cv_fireaxis2);
CV_RegisterVar(&cv_firenaxis);
CV_RegisterVar(&cv_firenaxis2);
CV_RegisterVar(&cv_deadzone);
CV_RegisterVar(&cv_deadzone2);
CV_RegisterVar(&cv_digitaldeadzone);
CV_RegisterVar(&cv_digitaldeadzone2);
// filesrch.c
CV_RegisterVar(&cv_addons_option);
@ -854,14 +820,14 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_mousemove);
CV_RegisterVar(&cv_mousemove2);
for (i = 0; i < 2; i++)
{
CV_RegisterVar(&cv_usegamepad[i]);
CV_RegisterVar(&cv_gamepad_scale[i]);
CV_RegisterVar(&cv_gamepad_rumble[i]);
}
CV_RegisterVar(&cv_gamepad_autopause);
CV_RegisterVar(&cv_usejoystick);
CV_RegisterVar(&cv_usejoystick2);
#ifdef LJOYSTICK
CV_RegisterVar(&cv_joyport);
CV_RegisterVar(&cv_joyport2);
#endif
CV_RegisterVar(&cv_joyscale);
CV_RegisterVar(&cv_joyscale2);
// Analog Control
CV_RegisterVar(&cv_analog[0]);
@ -2250,14 +2216,9 @@ static void Got_Pause(UINT8 **cp, INT32 playernum)
{
if (!menuactive || netgame)
S_PauseAudio();
P_PauseRumble(NULL);
}
else
{
S_ResumeAudio();
P_UnpauseRumble(NULL);
}
}
I_UpdateMouseGrab();
@ -3312,6 +3273,69 @@ static void Got_RunSOCcmd(UINT8 **cp, INT32 playernum)
G_SetGameModified(true);
}
// C++ would make this SO much simpler!
typedef struct addedfile_s
{
struct addedfile_s *next;
struct addedfile_s *prev;
char *value;
} addedfile_t;
static boolean AddedFileContains(addedfile_t *list, const char *value)
{
addedfile_t *node;
for (node = list; node; node = node->next)
{
if (!strcmp(value, node->value))
return true;
}
return false;
}
static void AddedFilesAdd(addedfile_t **list, const char *value)
{
addedfile_t *item = Z_Calloc(sizeof(addedfile_t), PU_STATIC, NULL);
item->value = Z_StrDup(value);
ListAdd(item, (listitem_t**)list);
}
static void AddedFilesRemove(void *pItem, addedfile_t **itemHead)
{
addedfile_t *item = (addedfile_t *)pItem;
if (item == *itemHead) // Start of list
{
*itemHead = item->next;
if (*itemHead)
(*itemHead)->prev = NULL;
}
else if (item->next == NULL) // end of list
{
item->prev->next = NULL;
}
else // Somewhere in between
{
item->prev->next = item->next;
item->next->prev = item->prev;
}
Z_Free(item->value);
Z_Free(item);
}
static void AddedFilesClearList(addedfile_t **itemHead)
{
addedfile_t *item;
addedfile_t *next;
for (item = *itemHead; item; item = next)
{
next = item->next;
AddedFilesRemove(item, itemHead);
}
}
/** Adds a pwad at runtime.
* Searches for sounds, maps, music, new images.
*/
@ -3320,8 +3344,7 @@ static void Command_Addfile(void)
size_t argc = COM_Argc(); // amount of arguments total
size_t curarg; // current argument index
const char *addedfiles[argc]; // list of filenames already processed
size_t numfilesadded = 0; // the amount of filenames processed
addedfile_t *addedfiles = NULL; // list of filenames already processed
if (argc < 2)
{
@ -3336,25 +3359,14 @@ static void Command_Addfile(void)
char buf[256];
char *buf_p = buf;
INT32 i;
size_t ii;
int musiconly; // W_VerifyNMUSlumps isn't boolean
boolean fileadded = false;
fn = COM_Argv(curarg);
// For the amount of filenames previously processed...
for (ii = 0; ii < numfilesadded; ii++)
{
// If this is one of them, don't try to add it.
if (!strcmp(fn, addedfiles[ii]))
{
fileadded = true;
break;
}
}
// If we've added this one, skip to the next one.
if (fileadded)
fileadded = AddedFileContains(addedfiles, fn);
if (fileadded) // If this is one of them, don't try to add it.
{
CONS_Alert(CONS_WARNING, M_GetText("Already processed %s, skipping\n"), fn);
continue;
@ -3363,13 +3375,16 @@ static void Command_Addfile(void)
// Disallow non-printing characters and semicolons.
for (i = 0; fn[i] != '\0'; i++)
if (!isprint(fn[i]) || fn[i] == ';')
{
AddedFilesClearList(&addedfiles);
return;
}
musiconly = W_VerifyNMUSlumps(fn, false);
if (musiconly == -1)
{
addedfiles[numfilesadded++] = fn;
AddedFilesAdd(&addedfiles, fn);
continue;
}
@ -3388,7 +3403,7 @@ static void Command_Addfile(void)
if (!(netgame || multiplayer) || musiconly)
{
P_AddWadFile(fn);
addedfiles[numfilesadded++] = fn;
AddedFilesAdd(&addedfiles, fn);
continue;
}
@ -3403,6 +3418,7 @@ static void Command_Addfile(void)
if (numwadfiles >= MAX_WADFILES)
{
CONS_Alert(CONS_ERROR, M_GetText("Too many files loaded to add %s\n"), fn);
AddedFilesClearList(&addedfiles);
return;
}
@ -3442,13 +3458,15 @@ static void Command_Addfile(void)
WRITEMEM(buf_p, md5sum, 16);
}
addedfiles[numfilesadded++] = fn;
AddedFilesAdd(&addedfiles, fn);
if (IsPlayerAdmin(consoleplayer) && (!server)) // Request to add file
SendNetXCmd(XD_REQADDFILE, buf, buf_p - buf);
else
SendNetXCmd(XD_ADDFILE, buf, buf_p - buf);
}
AddedFilesClearList(&addedfiles);
}
static void Command_Addfolder(void)
@ -3456,8 +3474,7 @@ static void Command_Addfolder(void)
size_t argc = COM_Argc(); // amount of arguments total
size_t curarg; // current argument index
const char *addedfolders[argc]; // list of filenames already processed
size_t numfoldersadded = 0; // the amount of filenames processed
addedfile_t *addedfolders = NULL; // list of filenames already processed
if (argc < 2)
{
@ -3473,24 +3490,13 @@ static void Command_Addfolder(void)
char buf[256];
char *buf_p = buf;
INT32 i, stat;
size_t ii;
boolean folderadded = false;
fn = COM_Argv(curarg);
// For the amount of filenames previously processed...
for (ii = 0; ii < numfoldersadded; ii++)
{
// If this is one of them, don't try to add it.
if (!strcmp(fn, addedfolders[ii]))
{
folderadded = true;
break;
}
}
// If we've added this one, skip to the next one.
if (folderadded)
folderadded = AddedFileContains(addedfolders, fn);
if (folderadded) // If we've added this one, skip to the next one.
{
CONS_Alert(CONS_WARNING, M_GetText("Already processed %s, skipping\n"), fn);
continue;
@ -3499,13 +3505,16 @@ static void Command_Addfolder(void)
// Disallow non-printing characters and semicolons.
for (i = 0; fn[i] != '\0'; i++)
if (!isprint(fn[i]) || fn[i] == ';')
{
AddedFilesClearList(&addedfolders);
return;
}
// Add file on your client directly if you aren't in a netgame.
if (!(netgame || multiplayer))
{
P_AddFolder(fn);
addedfolders[numfoldersadded++] = fn;
AddedFilesAdd(&addedfolders, fn);
continue;
}
@ -3527,6 +3536,7 @@ static void Command_Addfolder(void)
if (numwadfiles >= MAX_WADFILES)
{
CONS_Alert(CONS_ERROR, M_GetText("Too many files loaded to add %s\n"), fn);
AddedFilesClearList(&addedfolders);
return;
}
@ -3572,7 +3582,7 @@ static void Command_Addfolder(void)
Z_Free(fullpath);
addedfolders[numfoldersadded++] = fn;
AddedFilesAdd(&addedfolders, fn);
WRITESTRINGN(buf_p,p,240);
@ -4603,8 +4613,6 @@ void Command_ExitGame_f(void)
emeralds = 0;
memset(&luabanks, 0, sizeof(luabanks));
P_StopRumble(NULL);
if (dirmenu)
closefilemenu(true);

View file

@ -33,10 +33,14 @@ extern consvar_t cv_defaultskin2;
extern consvar_t cv_seenames, cv_allowseenames;
extern consvar_t cv_usemouse;
extern consvar_t cv_usegamepad[2];
extern consvar_t cv_gamepad_scale[2];
extern consvar_t cv_gamepad_rumble[2];
extern consvar_t cv_gamepad_autopause;
extern consvar_t cv_usejoystick;
extern consvar_t cv_usejoystick2;
#ifdef LJOYSTICK
extern consvar_t cv_joyport;
extern consvar_t cv_joyport2;
#endif
extern consvar_t cv_joyscale;
extern consvar_t cv_joyscale2;
// splitscreen with second mouse
extern consvar_t cv_mouse2port;

View file

@ -693,7 +693,8 @@ void readskincolor(MYFILE *f, INT32 num)
if (fastcmp(word, "NAME"))
{
size_t namesize = sizeof(skincolors[num].name);
char truncword[namesize];
char *truncword = malloc(namesize); // Follow C standard - SSNTails
UINT16 dupecheck;
deh_strlcpy(truncword, word2, namesize, va("Skincolor %d: name", num)); // truncate here to check for dupes
@ -701,7 +702,7 @@ void readskincolor(MYFILE *f, INT32 num)
if (truncword[0] != '\0' && (!stricmp(truncword, skincolors[SKINCOLOR_NONE].name) || (dupecheck && dupecheck != num)))
{
size_t lastchar = strlen(truncword);
char oldword[lastchar+1];
char *oldword = malloc(lastchar + 1); // Follow C standard - SSNTails
char dupenum = '1';
strlcpy(oldword, truncword, lastchar+1);
@ -726,9 +727,12 @@ void readskincolor(MYFILE *f, INT32 num)
}
deh_warning("Skincolor %d: name %s is a duplicate of another skincolor's name - renamed to %s", num, oldword, truncword);
free(oldword);
}
strlcpy(skincolors[num].name, truncword, namesize); // already truncated
free(truncword);
}
else if (fastcmp(word, "RAMP"))
{
@ -2759,13 +2763,13 @@ void readframe(MYFILE *f, INT32 num)
{
size_t z;
boolean found = false;
char actiontocompare[32];
size_t actionlen = strlen(word2) + 1;
char *actiontocompare = calloc(actionlen, 1);
memset(actiontocompare, 0x00, sizeof(actiontocompare));
strlcpy(actiontocompare, word2, sizeof (actiontocompare));
strcpy(actiontocompare, word2);
strupr(actiontocompare);
for (z = 0; z < 32; z++)
for (z = 0; z < actionlen; z++)
{
if (actiontocompare[z] == '\n' || actiontocompare[z] == '\r')
{
@ -2798,6 +2802,8 @@ void readframe(MYFILE *f, INT32 num)
if (!found)
deh_warning("Unknown action %s", actiontocompare);
free(actiontocompare);
}
else
deh_warning("Frame %d: unknown word '%s'", num, word1);

View file

@ -22,9 +22,9 @@
#include "v_video.h" // video flags (for lua)
#include "i_sound.h" // musictype_t (for lua)
#include "g_state.h" // gamestate_t (for lua)
#include "g_game.h" // Gamepad axes (for lua)
#include "g_game.h" // Joystick axes (for lua)
#include "i_joy.h"
#include "g_input.h" // Game controls (for lua)
#include "i_gamepad.h"
#include "deh_tables.h"
@ -4841,7 +4841,7 @@ const char *const MENUTYPES_LIST[] = {
"OP_CHANGECONTROLS", // OP_ChangeControlsDef shared with P2
"OP_P1MOUSE",
"OP_P1JOYSTICK",
"OP_JOYSTICKSET", // OP_GamepadSetDef shared with P2
"OP_JOYSTICKSET", // OP_JoystickSetDef shared with P2
"OP_P1CAMERA",
"OP_P2CONTROLS",
@ -5642,7 +5642,7 @@ struct int_const_s const INT_CONST[] = {
{"GS_DEDICATEDSERVER",GS_DEDICATEDSERVER},
{"GS_WAITINGPLAYERS",GS_WAITINGPLAYERS},
// Gamepad axes
// Joystick axes
{"JA_NONE",JA_NONE},
{"JA_TURN",JA_TURN},
{"JA_MOVE",JA_MOVE},
@ -5653,7 +5653,7 @@ struct int_const_s const INT_CONST[] = {
{"JA_SPIN",JA_SPIN},
{"JA_FIRE",JA_FIRE},
{"JA_FIRENORMAL",JA_FIRENORMAL},
{"JOYAXISRANGE",OLDJOYAXISRANGE},
{"JOYAXISRANGE",JOYAXISRANGE},
// Game controls
{"GC_NULL",GC_NULL},

View file

@ -211,7 +211,7 @@ extern char logfilename[1024];
// to an increment in MODVERSION. This might never happen in practice.
// If MODVERSION increases, set MINOREXECVERSION to 0.
#define MAJOREXECVERSION MODVERSION
#define MINOREXECVERSION 1
#define MINOREXECVERSION 0
// (It would have been nice to use VERSION and SUBVERSION but those are zero'd out for DEVELOP builds)
// Macros
@ -558,6 +558,9 @@ UINT32 quickncasehash (const char *p, size_t n)
#define max(x, y) (((x) > (y)) ? (x) : (y))
#endif
// Max gamepad/joysticks that can be detected/used.
#define MAX_JOYSTICKS 4
#ifndef M_PIl
#define M_PIl 3.1415926535897932384626433832795029L
#endif

View file

@ -31,18 +31,8 @@
#include <stdint.h>
#endif
#define UINT8 unsigned __int8
#define SINT8 signed __int8
#define UINT16 unsigned __int16
#define INT16 __int16
#define INT32 __int32
#define UINT32 unsigned __int32
#define INT64 __int64
#define UINT64 unsigned __int64
typedef long ssize_t;
/* Older Visual C++ headers don't have the Win64-compatible typedefs... */

View file

@ -37,7 +37,6 @@
#include "m_cond.h"
#include "p_local.h"
#include "p_setup.h"
#include "p_haptic.h"
#include "st_stuff.h" // hud hiding
#include "fastcmp.h"
#include "console.h"
@ -511,7 +510,6 @@ void F_StartIntro(void)
gameaction = ga_nothing;
paused = false;
CON_ToggleOff();
P_StopRumble(NULL);
F_NewCutscene(introtext[0]);
intro_scenenum = 0;
@ -993,10 +991,9 @@ void F_IntroTicker(void)
//
boolean F_IntroResponder(event_t *event)
{
INT32 type = event->type;
INT32 key = G_RemapGamepadEvent(event, &type);
INT32 key = event->key;
// remap virtual keys (mouse & gamepad buttons)
// remap virtual keys (mouse & joystick buttons)
switch (key)
{
case KEY_MOUSE1:
@ -1005,30 +1002,34 @@ boolean F_IntroResponder(event_t *event)
case KEY_MOUSE1 + 1:
key = KEY_BACKSPACE;
break;
case GAMEPAD_KEY(START):
case GAMEPAD_KEY(A):
case GAMEPAD_KEY(X):
case GAMEPAD_KEY(B):
case KEY_JOY1:
case KEY_JOY1 + 2:
key = KEY_ENTER;
break;
case GAMEPAD_KEY(DPAD_UP):
case KEY_JOY1 + 3:
key = 'n';
break;
case KEY_JOY1 + 1:
key = KEY_BACKSPACE;
break;
case KEY_HAT1:
key = KEY_UPARROW;
break;
case GAMEPAD_KEY(DPAD_DOWN):
case KEY_HAT1 + 1:
key = KEY_DOWNARROW;
break;
case GAMEPAD_KEY(DPAD_LEFT):
case KEY_HAT1 + 2:
key = KEY_LEFTARROW;
break;
case GAMEPAD_KEY(DPAD_RIGHT):
case KEY_HAT1 + 3:
key = KEY_RIGHTARROW;
break;
}
if (type != ev_keydown)
if (event->type != ev_keydown && key != 301)
return false;
if (key != KEY_ESCAPE && key != KEY_ENTER && key != KEY_SPACE && key != KEY_BACKSPACE)
if (key != 27 && key != KEY_ENTER && key != KEY_SPACE && key != KEY_BACKSPACE)
return false;
if (keypressed)
@ -1263,7 +1264,6 @@ void F_StartCredits(void)
gameaction = ga_nothing;
paused = false;
CON_ToggleOff();
P_StopRumble(NULL);
S_StopMusic();
S_StopSounds();
@ -1376,10 +1376,9 @@ void F_CreditTicker(void)
boolean F_CreditResponder(event_t *event)
{
INT32 type = event->type;
INT32 key = G_RemapGamepadEvent(event, &type);
INT32 key = event->key;
// remap virtual keys (mouse & gamepad buttons)
// remap virtual keys (mouse & joystick buttons)
switch (key)
{
case KEY_MOUSE1:
@ -1388,22 +1387,26 @@ boolean F_CreditResponder(event_t *event)
case KEY_MOUSE1 + 1:
key = KEY_BACKSPACE;
break;
case GAMEPAD_KEY(START):
case GAMEPAD_KEY(A):
case GAMEPAD_KEY(X):
case GAMEPAD_KEY(B):
case KEY_JOY1:
case KEY_JOY1 + 2:
key = KEY_ENTER;
break;
case GAMEPAD_KEY(DPAD_UP):
case KEY_JOY1 + 3:
key = 'n';
break;
case KEY_JOY1 + 1:
key = KEY_BACKSPACE;
break;
case KEY_HAT1:
key = KEY_UPARROW;
break;
case GAMEPAD_KEY(DPAD_DOWN):
case KEY_HAT1 + 1:
key = KEY_DOWNARROW;
break;
case GAMEPAD_KEY(DPAD_LEFT):
case KEY_HAT1 + 2:
key = KEY_LEFTARROW;
break;
case GAMEPAD_KEY(DPAD_RIGHT):
case KEY_HAT1 + 3:
key = KEY_RIGHTARROW;
break;
}
@ -1411,7 +1414,7 @@ boolean F_CreditResponder(event_t *event)
if (!(timesBeaten) && !(netgame || multiplayer) && !cv_debug)
return false;
if (type != ev_keydown)
if (event->type != ev_keydown)
return false;
if (key != KEY_ESCAPE && key != KEY_ENTER && key != KEY_SPACE && key != KEY_BACKSPACE)
@ -1452,7 +1455,6 @@ void F_StartGameEvaluation(void)
gameaction = ga_nothing;
paused = false;
CON_ToggleOff();
P_StopRumble(NULL);
finalecount = -1;
sparklloop = 0;
@ -1778,7 +1780,6 @@ void F_StartEnding(void)
gameaction = ga_nothing;
paused = false;
CON_ToggleOff();
P_StopRumble(NULL);
S_StopMusic(); // todo: placeholder
S_StopSounds();
@ -2224,7 +2225,6 @@ void F_StartGameEnd(void)
paused = false;
CON_ToggleOff();
S_StopSounds();
P_StopRumble(NULL);
// In case menus are still up?!!
M_ClearMenus(true);
@ -3567,7 +3567,6 @@ void F_StartContinue(void)
keypressed = false;
paused = false;
CON_ToggleOff();
P_StopRumble(NULL);
// In case menus are still up?!!
M_ClearMenus(true);
@ -3820,26 +3819,24 @@ void F_ContinueTicker(void)
boolean F_ContinueResponder(event_t *event)
{
INT32 key = event->key;
if (keypressed)
return true;
INT32 type = event->type;
INT32 key = G_RemapGamepadEvent(event, &type);
if (timetonext >= 21*TICRATE/2)
return false;
if (event->type != ev_keydown)
return false;
// remap virtual keys (mouse & gamepad buttons)
// remap virtual keys (mouse & joystick buttons)
switch (key)
{
case KEY_ENTER:
case KEY_SPACE:
case KEY_MOUSE1:
case GAMEPAD_KEY(START):
case GAMEPAD_KEY(A):
case GAMEPAD_KEY(X):
case KEY_JOY1:
case KEY_JOY1 + 2:
break;
default:
return false;
@ -3957,7 +3954,6 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset
gameaction = ga_nothing;
paused = false;
CON_ToggleOff();
P_StopRumble(NULL);
F_NewCutscene(cutscenes[cutscenenum]->scene[0].text);

View file

@ -32,7 +32,7 @@
#include "z_zone.h"
#include "i_video.h"
#include "byteptr.h"
#include "i_gamepad.h"
#include "i_joy.h"
#include "r_local.h"
#include "r_skins.h"
#include "y_inter.h"
@ -1527,9 +1527,9 @@ void G_BeginRecording(void)
buf |= 0x08;
pflags |= PF_AUTOBRAKE;
}
if (cv_usegamepad[0].value)
if (cv_usejoystick.value)
buf |= 0x10;
CV_SetValue(&cv_showinputjoy, !!(cv_usegamepad[0].value));
CV_SetValue(&cv_showinputjoy, !!(cv_usejoystick.value));
WRITEUINT8(demo_p,buf);
player->pflags = pflags;

File diff suppressed because it is too large Load diff

View file

@ -68,14 +68,10 @@ typedef enum {
#define P_ControlStyle(player) ((((player)->pflags & PF_ANALOGMODE) ? CS_LMAOGALOG : 0) | (((player)->pflags & PF_DIRECTIONCHAR) ? CS_STANDARD : 0))
extern consvar_t cv_autobrake, cv_autobrake2;
extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_jumpaxis,cv_spinaxis,cv_fireaxis,cv_firenaxis,cv_deadzone,cv_digitaldeadzone;
extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_jumpaxis2,cv_spinaxis2,cv_fireaxis2,cv_firenaxis2,cv_deadzone2,cv_digitaldeadzone2;
extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_ghost_last, cv_ghost_guest;
extern consvar_t cv_sideaxis[2], cv_turnaxis[2], cv_moveaxis[2], cv_lookaxis[2],
cv_jumpaxis[2], cv_spinaxis[2], cv_fireaxis[2], cv_firenaxis[2],
cv_deadzone[2], cv_digitaldeadzone[2];
extern CV_PossibleValue_t joyaxis_cons_t[];
// hi here's some new controls
extern consvar_t cv_cam_shiftfacing[2], cv_cam_turnfacing[2],
cv_cam_turnfacingability[2], cv_cam_turnfacingspindash[2], cv_cam_turnfacinginput[2],
@ -88,12 +84,10 @@ typedef enum
LOCK_INTERESTS = 1<<2,
} lockassist_e;
// Legacy axis stuff
#define JOYAXISSET 4 // 4 Sets of 2 axes
typedef enum
{
JA_NONE,
JA_NONE = 0,
JA_TURN,
JA_MOVE,
JA_LOOK,
@ -107,7 +101,8 @@ typedef enum
JA_FIRENORMAL,
} joyaxis_e;
INT16 G_JoyAxis(UINT8 which, joyaxis_e axissel);
INT32 JoyAxis(joyaxis_e axissel);
INT32 Joy2Axis(joyaxis_e axissel);
// mouseaiming (looking up/down with the mouse or keyboard)
#define KB_LOOKSPEED (1<<25)
@ -127,18 +122,6 @@ ticcmd_t *G_CopyTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n);
// copy ticcmd_t to and fro network packets
ticcmd_t *G_MoveTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n);
// gets the user-set gamepad device for a specific player
INT32 G_GetGamepadDeviceIndex(INT32 player);
// returns a player's gamepad index
INT16 G_GetGamepadForPlayer(player_t *player);
// called when a player's gamepad is connected
void G_OnGamepadConnect(UINT8 which);
// called when a player's gamepad is disconnected
void G_OnGamepadDisconnect(UINT8 which);
// clip the console player aiming to the view
INT16 G_ClipAimingPitch(INT32 *aiming);
INT16 G_SoftwareClipAimingPitch(INT32 *aiming);

File diff suppressed because it is too large Load diff

View file

@ -8,7 +8,7 @@
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file g_input.h
/// \brief handle mouse/keyboard/gamepad inputs,
/// \brief handle mouse/keyboard/joystick inputs,
/// maps inputs to game controls (forward, spin, jump...)
#ifndef __G_INPUT__
@ -17,178 +17,45 @@
#include "d_event.h"
#include "keys.h"
#include "command.h"
#include "m_fixed.h"
// number of total 'button' inputs, include keyboard keys, plus virtual
// keys (mousebuttons and joybuttons becomes keys)
#define NUMKEYS 256
// Max gamepads that can be used by every player
#define NUM_GAMEPADS 2
// Max gamepads that can be detected
#define MAX_CONNECTED_GAMEPADS 4
// Max mouse buttons
#define MOUSEBUTTONS 8
typedef enum
{
GAMEPAD_TYPE_UNKNOWN,
GAMEPAD_TYPE_XBOX360,
GAMEPAD_TYPE_XBOXONE,
GAMEPAD_TYPE_XBOX_SERIES_XS,
GAMEPAD_TYPE_XBOX_ELITE,
GAMEPAD_TYPE_PS3,
GAMEPAD_TYPE_PS4,
GAMEPAD_TYPE_PS5,
GAMEPAD_TYPE_NINTENDO_SWITCH_PRO,
GAMEPAD_TYPE_NINTENDO_SWITCH_JOY_CON_GRIP,
GAMEPAD_TYPE_NINTENDO_SWITCH_JOY_CON_LEFT,
GAMEPAD_TYPE_NINTENDO_SWITCH_JOY_CON_RIGHT,
GAMEPAD_TYPE_GOOGLE_STADIA,
GAMEPAD_TYPE_AMAZON_LUNA,
GAMEPAD_TYPE_STEAM_CONTROLLER,
GAMEPAD_TYPE_VIRTUAL
} gamepadtype_e;
boolean G_GamepadTypeIsXbox(gamepadtype_e type);
boolean G_GamepadTypeIsPlayStation(gamepadtype_e type);
boolean G_GamepadTypeIsNintendoSwitch(gamepadtype_e type);
boolean G_GamepadTypeIsJoyCon(gamepadtype_e type);
const char *G_GamepadTypeToString(gamepadtype_e type);
typedef enum
{
GAMEPAD_BUTTON_A,
GAMEPAD_BUTTON_B,
GAMEPAD_BUTTON_X,
GAMEPAD_BUTTON_Y,
GAMEPAD_BUTTON_BACK,
GAMEPAD_BUTTON_GUIDE,
GAMEPAD_BUTTON_START,
GAMEPAD_BUTTON_LEFTSTICK,
GAMEPAD_BUTTON_RIGHTSTICK,
GAMEPAD_BUTTON_LEFTSHOULDER,
GAMEPAD_BUTTON_RIGHTSHOULDER,
GAMEPAD_BUTTON_DPAD_UP,
GAMEPAD_BUTTON_DPAD_DOWN,
GAMEPAD_BUTTON_DPAD_LEFT,
GAMEPAD_BUTTON_DPAD_RIGHT,
// According to SDL, this button can be:
// the Xbox Series X|S share button
// the PS5 microphone button
// the Nintendo Switch (Pro or Joy-Con) capture button
// the Amazon Luna microphone button
GAMEPAD_BUTTON_MISC1,
// Xbox Elite paddles
GAMEPAD_BUTTON_PADDLE1,
GAMEPAD_BUTTON_PADDLE2,
GAMEPAD_BUTTON_PADDLE3,
GAMEPAD_BUTTON_PADDLE4,
// PS4/PS5 touchpad button
GAMEPAD_BUTTON_TOUCHPAD,
NUM_GAMEPAD_BUTTONS
} gamepad_button_e;
typedef enum
{
GAMEPAD_AXIS_LEFTX,
GAMEPAD_AXIS_LEFTY,
GAMEPAD_AXIS_RIGHTX,
GAMEPAD_AXIS_RIGHTY,
GAMEPAD_AXIS_TRIGGERLEFT,
GAMEPAD_AXIS_TRIGGERRIGHT,
NUM_GAMEPAD_AXES
} gamepad_axis_e;
extern const char *const gamepad_button_names[NUM_GAMEPAD_BUTTONS + 1];
extern const char *const gamepad_axis_names[NUM_GAMEPAD_AXES + 1];
// Haptic effects
typedef struct
{
fixed_t large_magnitude; // Magnitude of the large motor
fixed_t small_magnitude; // Magnitude of the small motor
tic_t duration; // The total duration of the effect, in tics
} haptic_t;
// Gamepad info for each player on the system
typedef struct
{
// Gamepad index
UINT8 num;
// Gamepad is connected and being used by a player
boolean connected;
// What kind of controller this is (Xbox 360, DualShock, Joy-Con, etc.)
gamepadtype_e type;
// Treat this gamepad's axes as if it they were buttons
boolean digital;
struct {
boolean supported; // Gamepad can rumble
boolean active; // Rumble is active
boolean paused; // Rumble is paused
haptic_t data; // Current haptic effect status
} rumble;
UINT8 buttons[NUM_GAMEPAD_BUTTONS]; // Current state of all buttons
INT16 axes[NUM_GAMEPAD_AXES]; // Current state of all axes
} gamepad_t;
void G_InitGamepads(void);
typedef enum
{
GAMEPAD_STRING_DEFAULT, // A
GAMEPAD_STRING_MENU1, // A Button
GAMEPAD_STRING_MENU2 // the A Button
} gamepad_string_e;
const char *G_GetGamepadButtonString(gamepadtype_e type, gamepad_button_e button, gamepad_string_e strtype);
const char *G_GetGamepadAxisString(gamepadtype_e type, gamepad_axis_e button, gamepad_string_e strtype, boolean inv);
extern gamepad_t gamepads[NUM_GAMEPADS];
#define JOYBUTTONS 32 // 32 buttons
#define JOYHATS 4 // 4 hats
#define JOYAXISSET 4 // 4 Sets of 2 axises
//
// mouse and gamepad buttons are handled as 'virtual' keys
// mouse and joystick buttons are handled as 'virtual' keys
//
typedef enum
{
KEY_MOUSE1 = NUMKEYS,
KEY_GAMEPAD = KEY_MOUSE1 + MOUSEBUTTONS,
KEY_AXES = KEY_GAMEPAD + NUM_GAMEPAD_BUTTONS, // Sure, why not.
KEY_INV_AXES = KEY_AXES + NUM_GAMEPAD_AXES,
KEY_JOY1 = KEY_MOUSE1 + MOUSEBUTTONS,
KEY_HAT1 = KEY_JOY1 + JOYBUTTONS,
KEY_DBLMOUSE1 = KEY_INV_AXES + NUM_GAMEPAD_AXES, // double clicks
KEY_DBLMOUSE1 =KEY_HAT1 + JOYHATS*4, // double clicks
KEY_DBLJOY1 = KEY_DBLMOUSE1 + MOUSEBUTTONS,
KEY_DBLHAT1 = KEY_DBLJOY1 + JOYBUTTONS,
KEY_2MOUSE1 = KEY_DBLMOUSE1 + MOUSEBUTTONS,
KEY_DBL2MOUSE1 = KEY_2MOUSE1 + MOUSEBUTTONS,
KEY_2MOUSE1 = KEY_DBLHAT1 + JOYHATS*4,
KEY_2JOY1 = KEY_2MOUSE1 + MOUSEBUTTONS,
KEY_2HAT1 = KEY_2JOY1 + JOYBUTTONS,
KEY_MOUSEWHEELUP = KEY_DBL2MOUSE1 + MOUSEBUTTONS,
KEY_MOUSEWHEELDOWN,
KEY_2MOUSEWHEELUP,
KEY_2MOUSEWHEELDOWN,
KEY_DBL2MOUSE1 = KEY_2HAT1 + JOYHATS*4,
KEY_DBL2JOY1 = KEY_DBL2MOUSE1 + MOUSEBUTTONS,
KEY_DBL2HAT1 = KEY_DBL2JOY1 + JOYBUTTONS,
NUMINPUTS
KEY_MOUSEWHEELUP = KEY_DBL2HAT1 + JOYHATS*4,
KEY_MOUSEWHEELDOWN = KEY_MOUSEWHEELUP + 1,
KEY_2MOUSEWHEELUP = KEY_MOUSEWHEELDOWN + 1,
KEY_2MOUSEWHEELDOWN = KEY_2MOUSEWHEELUP + 1,
NUMINPUTS = KEY_2MOUSEWHEELDOWN + 1,
} key_input_e;
#define GAMEPAD_KEY(key) (KEY_GAMEPAD + GAMEPAD_BUTTON_##key)
typedef enum
{
GC_NULL = 0, // a key/button mapped to GC_NULL has no effect
@ -274,22 +141,19 @@ typedef struct
extern mouse_t mouse;
extern mouse_t mouse2;
extern INT32 joyxmove[JOYAXISSET], joyymove[JOYAXISSET], joy2xmove[JOYAXISSET], joy2ymove[JOYAXISSET];
// current state of the keys: true if pushed
extern UINT8 gamekeydown[NUMINPUTS];
// two key codes (or virtual key) per game control
extern INT32 gamecontrol[NUM_GAMECONTROLS][2];
extern INT32 gamecontrolbis[NUM_GAMECONTROLS][2]; // secondary splitscreen player
// default control storage, use 0 (gcs_custom) for memory retention
extern INT32 gamecontroldefault[num_gamecontrolschemes][NUM_GAMECONTROLS][2];
extern INT32 gamecontroldefault[num_gamecontrolschemes][NUM_GAMECONTROLS][2]; // default control storage, use 0 (gcs_custom) for memory retention
extern INT32 gamecontrolbisdefault[num_gamecontrolschemes][NUM_GAMECONTROLS][2];
boolean G_PlayerInputDown(UINT8 which, gamecontrols_e gc);
boolean G_CheckDigitalPlayerInput(UINT8 which, gamecontrols_e gc);
SINT8 G_PlayerInputIsAnalog(UINT8 which, gamecontrols_e gc, UINT8 settings);
INT16 G_GetAnalogPlayerInput(UINT8 which, gamecontrols_e gc, UINT8 settings);
#define PLAYER1INPUTDOWN(gc) (gamekeydown[gamecontrol[gc][0]] || gamekeydown[gamecontrol[gc][1]])
#define PLAYER2INPUTDOWN(gc) (gamekeydown[gamecontrolbis[gc][0]] || gamekeydown[gamecontrolbis[gc][1]])
#define PLAYERINPUTDOWN(p, gc) ((p) == 2 ? PLAYER2INPUTDOWN(gc) : PLAYER1INPUTDOWN(gc))
#define num_gcl_tutorial_check 6
#define num_gcl_tutorial_used 8
@ -317,37 +181,13 @@ extern const INT32 gcl_jump_spin[num_gcl_jump_spin];
// remaps the input event to a game control.
void G_MapEventsToControls(event_t *ev);
boolean G_RumbleSupported(UINT8 which);
boolean G_RumbleGamepad(UINT8 which, fixed_t large_magnitude, fixed_t small_magnitude, tic_t duration);
void G_StopGamepadRumble(UINT8 which);
fixed_t G_GetLargeMotorFreq(UINT8 which);
fixed_t G_GetSmallMotorFreq(UINT8 which);
boolean G_GetGamepadRumblePaused(UINT8 which);
boolean G_SetLargeMotorFreq(UINT8 which, fixed_t freq);
boolean G_SetSmallMotorFreq(UINT8 which, fixed_t freq);
void G_SetGamepadRumblePaused(UINT8 which, boolean pause);
INT16 G_GamepadAxisEventValue(UINT8 which, INT16 value);
INT16 G_GetGamepadAxisValue(UINT8 which, gamepad_axis_e axis);
fixed_t G_GetAdjustedGamepadAxis(UINT8 which, gamepad_axis_e axis, boolean applyDeadzone);
UINT16 G_GetGamepadDeadZone(UINT8 which);
UINT16 G_GetGamepadDigitalDeadZone(UINT8 which);
INT32 G_BasicDeadZoneCalculation(INT32 magnitude, const UINT16 jdeadzone);
INT32 G_RemapGamepadEvent(event_t *event, INT32 *type);
// returns the name of a key
const char *G_KeyNumToName(INT32 keynum);
INT32 G_KeyNameToNum(const char *keystr);
const char *G_GetDisplayNameForKey(INT32 keynum);
// 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 G_DefineDefaultControls(void);

View file

@ -5180,7 +5180,15 @@ static void HWR_ProjectSprite(mobj_t *thing)
if (thing->rollangle
&& !(splat && !(thing->renderflags & RF_NOSPLATROLLANGLE)))
{
rollangle = R_GetRollAngle(thing->rollangle);
if (papersprite)
{
// a positive rollangle should should pitch papersprites upwards relative to their facing angle
rollangle = R_GetRollAngle(InvAngle(thing->rollangle));
}
else
{
rollangle = R_GetRollAngle(thing->rollangle);
}
rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, false, sprinfo, rollangle);
if (rotsprite != NULL)
@ -5232,9 +5240,9 @@ static void HWR_ProjectSprite(mobj_t *thing)
if (caster && !P_MobjWasRemoved(caster))
{
interpmobjstate_t casterinterp = {};
interpmobjstate_t casterinterp = { 0 };
fixed_t groundz;
fixed_t floordiff;
fixed_t floordiff;
if (R_UsingFrameInterpolation() && !paused)
{
@ -5244,7 +5252,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
{
R_InterpolateMobjState(caster, FRACUNIT, &casterinterp);
}
groundz = R_GetShadowZ(thing, NULL);
floordiff = abs(((thing->eflags & MFE_VERTICALFLIP) ? caster->height : 0) + casterinterp.z - groundz);
@ -5340,7 +5348,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer)
{
interpmobjstate_t tracer_interp = {};
interpmobjstate_t tracer_interp = { 0 };
if (! R_ThingVisible(thing->tracer))
return;

View file

@ -38,51 +38,51 @@
<ProjectName>r_opengl</ProjectName>
<ProjectGuid>{51137D5C-4E81-4955-AACF-EA3092006051}</ProjectGuid>
<RootNamespace>r_opengl</RootNamespace>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WindowsSDKDesktopARMSupport>true</WindowsSDKDesktopARMSupport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WindowsSDKDesktopARMSupport>true</WindowsSDKDesktopARMSupport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

View file

@ -1130,7 +1130,7 @@ static void GLPerspective(GLfloat fovy, GLfloat aspect)
const GLfloat zNear = NEAR_CLIPPING_PLANE;
const GLfloat zFar = FAR_CLIPPING_PLANE;
const GLfloat radians = (GLfloat)(fovy / 2.0f * M_PIl / 180.0f);
const GLfloat sine = sin(radians);
const GLfloat sine = (GLfloat)sin(radians);
const GLfloat deltaZ = zFar - zNear;
GLfloat cotangent;
@ -2042,9 +2042,9 @@ static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAF
if (Surface != NULL)
{
UNIFORM_1(shader->uniforms[gluniform_lighting], Surface->LightInfo.light_level, pglUniform1f);
UNIFORM_1(shader->uniforms[gluniform_fade_start], Surface->LightInfo.fade_start, pglUniform1f);
UNIFORM_1(shader->uniforms[gluniform_fade_end], Surface->LightInfo.fade_end, pglUniform1f);
UNIFORM_1(shader->uniforms[gluniform_lighting], (GLfloat)Surface->LightInfo.light_level, pglUniform1f);
UNIFORM_1(shader->uniforms[gluniform_fade_start], (GLfloat)Surface->LightInfo.fade_start, pglUniform1f);
UNIFORM_1(shader->uniforms[gluniform_fade_end], (GLfloat)Surface->LightInfo.fade_end, pglUniform1f);
}
UNIFORM_1(shader->uniforms[gluniform_leveltime], shader_leveltime, pglUniform1f);
@ -3038,7 +3038,7 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform)
if (special_splitscreen)
{
used_fov = atan(tan(used_fov*M_PI/360)*0.8)*360/M_PI;
used_fov = (float)(atan(tan(used_fov*M_PI/360)*0.8)*360/M_PI);
GLPerspective(used_fov, 2*ASPECT_RATIO);
}
else

View file

@ -38,52 +38,52 @@
<ProjectName>s_openal</ProjectName>
<ProjectGuid>{E662D0B3-412D-4D55-A5EC-8CBD680DDCBE}</ProjectGuid>
<RootNamespace>s_openal</RootNamespace>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">

View file

@ -65,6 +65,8 @@ static I_mutex hms_api_mutex;
static char *hms_server_token;
static char hms_useragent[512];
struct HMS_buffer
{
CURL *curl;
@ -81,6 +83,22 @@ Contact_error (void)
);
}
static void
get_user_agent(char *buf, size_t len)
{
if (snprintf(buf, len, "%s/%s (%s; %s; %i; %i) SRB2BASE/%i", SRB2APPLICATION, VERSIONSTRING, compbranch, comprevision, MODID, MODVERSION, CODEBASE) < 0)
I_Error("http-mserv: get_user_agent failed");
}
static void
init_user_agent_once(void)
{
if (hms_useragent[0] != '\0')
return;
get_user_agent(hms_useragent, 512);
}
static size_t
HMS_on_read (char *s, size_t _1, size_t n, void *userdata)
{
@ -156,6 +174,8 @@ HMS_connect (const char *format, ...)
I_lock_mutex(&hms_api_mutex);
#endif
init_user_agent_once();
seek = strlen(hms_api) + 1;/* + '/' */
va_start (ap, format);
@ -202,6 +222,8 @@ HMS_connect (const char *format, ...)
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HMS_on_read);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, buffer);
curl_easy_setopt(curl, CURLOPT_USERAGENT, hms_useragent);
curl_free(quack_token);
free(url);

View file

@ -877,7 +877,7 @@ void HU_Ticker(void)
hu_tick++;
hu_tick &= 7; // currently only to blink chat input cursor
if (G_PlayerInputDown(0, GC_SCORES))
if (PLAYER1INPUTDOWN(GC_SCORES))
hu_showscores = !chat_on;
else
hu_showscores = false;
@ -1052,6 +1052,26 @@ boolean HU_Responder(event_t *ev)
// only KeyDown events now...
/*// Shoot, to prevent P1 chatting from ruining the game for everyone else, it's either:
// A. completely disallow opening chat entirely in online splitscreen
// or B. iterate through all controls to make sure it's bound to player 1 before eating
// You can see which one I chose.
// (Unless if you're sharing a keyboard, since you probably establish when you start chatting that you have dibs on it...)
// (Ahhh, the good ol days when I was a kid who couldn't afford an extra USB controller...)
if (ev->key >= KEY_MOUSE1)
{
INT32 i;
for (i = 0; i < NUM_GAMECONTROLS; i++)
{
if (gamecontrol[i][0] == ev->key || gamecontrol[i][1] == ev->key)
break;
}
if (i == NUM_GAMECONTROLS)
return false;
}*/ //We don't actually care about that unless we get splitscreen netgames. :V
#ifndef NONET
c = (INT32)ev->key;

View file

@ -1,58 +0,0 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2022 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file i_gamepad.h
/// \brief Gamepads
#ifndef __I_GAMEPAD_H__
#define __I_GAMEPAD_H__
#include "g_input.h"
#include "p_haptic.h"
// So m_menu knows whether to store cv_usegamepad value or string
#define GAMEPAD_HOTPLUG
// Value range for axes
#define JOYAXISRANGE INT16_MAX
#define OLDJOYAXISRANGE 1023
// Starts all gamepads
void I_InitGamepads(void);
// Returns the number of gamepads on the system
INT32 I_NumGamepads(void);
// Changes a gamepad's device
void I_ChangeGamepad(UINT8 which);
// Toggles a gamepad's digital axis setting
void I_SetGamepadDigital(UINT8 which, boolean enable);
// Shuts down all gamepads
void I_ShutdownGamepads(void);
// Returns the name of a gamepad from its index
const char *I_GetGamepadName(INT32 joyindex);
// Gamepad rumble interface
boolean I_RumbleSupported(void);
boolean I_RumbleGamepad(UINT8 which, const haptic_t *effect);
boolean I_GetGamepadRumblePaused(UINT8 which);
boolean I_SetGamepadLargeMotorFreq(UINT8 which, fixed_t freq);
boolean I_SetGamepadSmallMotorFreq(UINT8 which, fixed_t freq);
void I_SetGamepadRumblePaused(UINT8 which, boolean pause);
boolean I_GetGamepadRumbleSupported(UINT8 which);
void I_StopGamepadRumble(UINT8 which);
#endif // __I_GAMEPAD_H__

58
src/i_joy.h Normal file
View file

@ -0,0 +1,58 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2022 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file i_joy.h
/// \brief share joystick information with game control code
#ifndef __I_JOY_H__
#define __I_JOY_H__
#include "g_input.h"
/*!
\brief -JOYAXISRANGE to +JOYAXISRANGE for each axis
(1024-1) so we can do a right shift instead of division
(doesnt matter anyway, just give enough precision)
a gamepad will return -1, 0, or 1 in the event data
an analog type joystick will return a value
from -JOYAXISRANGE to +JOYAXISRANGE for each axis
*/
#define JOYAXISRANGE 1023
// detect a bug if we increase JOYBUTTONS above DIJOYSTATE's number of buttons
#if (JOYBUTTONS > 64)
"JOYBUTTONS is greater than INT64 bits can hold"
#endif
/** \brief The struct JoyType_s
share some joystick information (maybe 2 for splitscreen), to the game input code,
actually, we need to know if it is a gamepad or analog controls
*/
struct JoyType_s
{
/*! if true, we MUST Poll() to get new joystick data,
that is: we NEED the DIRECTINPUTDEVICE2 ! (watchout NT compatibility) */
INT32 bJoyNeedPoll;
/*! this joystick is a gamepad, read: digital axes
if FALSE, interpret the joystick event data as JOYAXISRANGE (see above) */
INT32 bGamepadStyle;
};
typedef struct JoyType_s JoyType_t;
/** \brief Joystick info
for palyer 1 and 2's joystick/gamepad
*/
extern JoyType_t Joystick, Joystick2;
#endif // __I_JOY_H__

View file

@ -101,6 +101,90 @@ ticcmd_t *I_BaseTiccmd2(void);
*/
void I_Quit(void) FUNCNORETURN;
typedef enum
{
EvilForce = -1,
//Constant
ConstantForce = 0,
//Ramp
RampForce,
//Periodics
SquareForce,
SineForce,
TriangleForce,
SawtoothUpForce,
SawtoothDownForce,
//MAX
NumberofForces,
} FFType;
typedef struct JoyFF_s
{
INT32 ForceX; ///< The X of the Force's Vel
INT32 ForceY; ///< The Y of the Force's Vel
//All
UINT32 Duration; ///< The total duration of the effect, in microseconds
INT32 Gain; //< /The gain to be applied to the effect, in the range from 0 through 10,000.
//All, CONSTANTFORCE -10,000 to 10,000
INT32 Magnitude; ///< Magnitude of the effect, in the range from 0 through 10,000.
//RAMPFORCE
INT32 Start; ///< Magnitude at the start of the effect, in the range from -10,000 through 10,000.
INT32 End; ///< Magnitude at the end of the effect, in the range from -10,000 through 10,000.
//PERIODIC
INT32 Offset; ///< Offset of the effect.
UINT32 Phase; ///< Position in the cycle of the periodic effect at which playback begins, in the range from 0 through 35,999
UINT32 Period; ///< Period of the effect, in microseconds.
} JoyFF_t;
/** \brief Forcefeedback for the first joystick
\param Type what kind of Effect
\param Effect Effect Info
\return void
*/
void I_Tactile(FFType Type, const JoyFF_t *Effect);
/** \brief Forcefeedback for the second joystick
\param Type what kind of Effect
\param Effect Effect Info
\return void
*/
void I_Tactile2(FFType Type, const JoyFF_t *Effect);
/** \brief to set up the first joystick scale
*/
void I_JoyScale(void);
/** \brief to set up the second joystick scale
*/
void I_JoyScale2(void);
// Called by D_SRB2Main.
/** \brief to startup the first joystick
*/
void I_InitJoystick(void);
/** \brief to startup the second joystick
*/
void I_InitJoystick2(void);
/** \brief return the number of joystick on the system
*/
INT32 I_NumJoys(void);
/** \brief The *I_GetJoyName function
\param joyindex which joystick
\return joystick name
*/
const char *I_GetJoyName(INT32 joyindex);
#ifndef NOMUMBLE
#include "p_mobj.h" // mobj_t
#include "s_sound.h" // listener_t
@ -209,7 +293,15 @@ const CPUInfoFlags *I_CPUInfo(void);
*/
const char *I_LocateWad(void);
/** \brief Mice events
/** \brief First Joystick's events
*/
void I_GetJoystickEvents(void);
/** \brief Second Joystick's events
*/
void I_GetJoystick2Events(void);
/** \brief Mouses events
*/
void I_GetMouseEvents(void);

View file

@ -1758,14 +1758,14 @@ state_t states[NUMSTATES] =
// Metal Sonic
{SPR_PLAY, SPR2_STND, -1, {NULL}, 0, 0, S_METALSONIC_RACE}, // S_METALSONIC_RACE
{SPR_METL, 4, -1, {NULL}, 0, 0, S_NULL}, // S_METALSONIC_FLOAT
{SPR_METL, 4, -1, {NULL}, 0, 0, S_METALSONIC_FLOAT}, // S_METALSONIC_FLOAT
{SPR_METL, 16|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_METALSONIC_STUN}, // S_METALSONIC_VECTOR
{SPR_METL, 15, -1, {NULL}, 0, 0, S_METALSONIC_FLOAT}, // S_METALSONIC_STUN
{SPR_METL, 17, 20, {NULL}, 0, 0, S_METALSONIC_GATHER},// S_METALSONIC_RAISE
{SPR_METL, 18, -1, {NULL}, 0, 0, S_NULL}, // S_METALSONIC_GATHER
{SPR_METL, 18, -1, {NULL}, 0, 0, S_METALSONIC_FLOAT}, // S_METALSONIC_GATHER
{SPR_METL, 6|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 1, 2, S_METALSONIC_BOUNCE},// S_METALSONIC_DASH
{SPR_METL, 18|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 1, 2, S_NULL}, // S_METALSONIC_BOUNCE
{SPR_METL, 14, -1, {NULL}, 0, 0, S_NULL}, // S_METALSONIC_BADBOUNCE
{SPR_METL, 18|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 1, 2, S_METALSONIC_FLOAT}, // S_METALSONIC_BOUNCE
{SPR_METL, 14, -1, {NULL}, 0, 0, S_METALSONIC_FLOAT}, // S_METALSONIC_BADBOUNCE
{SPR_METL, 17, -1, {NULL}, 0, 0, S_METALSONIC_GATHER},// S_METALSONIC_SHOOT
{SPR_METL, 15, 40, {A_Pain}, 0, 0, S_METALSONIC_FLOAT}, // S_METALSONIC_PAIN
{SPR_METL, 17, 2, {A_Fall}, 0, 0, S_METALSONIC_DEATH2},// S_METALSONIC_DEATH1

View file

@ -15,7 +15,6 @@
#include "p_local.h"
#include "p_setup.h" // So we can have P_SetupLevelSky
#include "p_slopes.h" // P_GetSlopeZAt
#include "p_haptic.h"
#include "z_zone.h"
#include "r_main.h"
#include "r_draw.h"
@ -221,7 +220,6 @@ static const struct {
{META_LUABANKS, "luabanks[]"},
{META_KEYEVENT, "keyevent_t"},
{META_GAMEPAD, "gamepad_t"},
{META_MOUSE, "mouse_t"},
{NULL, NULL}
};
@ -1734,78 +1732,6 @@ static int lib_pPlayerShouldUseSpinHeight(lua_State *L)
return 1;
}
// P_HAPTIC
///////////
#define GET_OPTIONAL_PLAYER(arg) \
player_t *player = NULL; \
if (!lua_isnoneornil(L, arg)) { \
player = *((player_t **)luaL_checkudata(L, arg, META_PLAYER)); \
if (!player) \
return LUA_ErrInvalid(L, "player_t"); \
}
static int lib_pDoRumble(lua_State *L)
{
GET_OPTIONAL_PLAYER(1);
fixed_t large_magnitude = luaL_checkfixed(L, 2);
fixed_t small_magnitude = luaL_optfixed(L, 3, large_magnitude);
tic_t duration = luaL_optinteger(L, 4, 0);
#define CHECK_MAGNITUDE(which) \
if (which##_magnitude < 0 || which##_magnitude > FRACUNIT) \
return luaL_error(L, va(#which " motor frequency %f out of range (minimum is 0.0, maximum is 1.0)", \
FixedToFloat(which##_magnitude)))
CHECK_MAGNITUDE(large);
CHECK_MAGNITUDE(small);
#undef CHECK_MAGNITUDE
lua_pushboolean(L, P_DoRumble(player, large_magnitude, small_magnitude, duration));
return 1;
}
static int lib_pPauseRumble(lua_State *L)
{
GET_OPTIONAL_PLAYER(1);
P_PauseRumble(player);
return 0;
}
static int lib_pUnpauseRumble(lua_State *L)
{
GET_OPTIONAL_PLAYER(1);
P_UnpauseRumble(player);
return 0;
}
static int lib_pIsRumbleEnabled(lua_State *L)
{
GET_OPTIONAL_PLAYER(1);
if (player && P_IsLocalPlayer(player))
lua_pushboolean(L, P_IsRumbleEnabled(player));
else
lua_pushnil(L);
return 1;
}
static int lib_pIsRumblePaused(lua_State *L)
{
GET_OPTIONAL_PLAYER(1);
if (player && P_IsLocalPlayer(player))
lua_pushboolean(L, P_IsRumblePaused(player));
else
lua_pushnil(L);
return 1;
}
static int lib_pStopRumble(lua_State *L)
{
GET_OPTIONAL_PLAYER(1);
P_StopRumble(player);
return 0;
}
// P_MAP
///////////
@ -3442,6 +3368,7 @@ static int lib_sResumeMusic(lua_State *L)
// G_GAME
////////////
// Copypasted from lib_cvRegisterVar :]
static int lib_gAddGametype(lua_State *L)
{
const char *k;
@ -4163,14 +4090,6 @@ static luaL_Reg lib[] = {
{"P_PlayerCanEnterSpinGaps",lib_pPlayerCanEnterSpinGaps},
{"P_PlayerShouldUseSpinHeight",lib_pPlayerShouldUseSpinHeight},
// p_haptic
{"P_DoRumble",lib_pDoRumble},
{"P_PauseRumble",lib_pPauseRumble},
{"P_UnpauseRumble",lib_pUnpauseRumble},
{"P_IsRumbleEnabled",lib_pIsRumbleEnabled},
{"P_IsRumblePaused",lib_pIsRumblePaused},
{"P_StopRumble",lib_pStopRumble},
// p_map
{"P_CheckPosition",lib_pCheckPosition},
{"P_TryMove",lib_pTryMove},

View file

@ -41,6 +41,7 @@ automatically.
X (MobjMoveBlocked),/* P_XYMovement (when movement is blocked) */\
X (MapThingSpawn),/* P_SpawnMapThing */\
X (FollowMobj),/* P_PlayerAfterThink Smiles mobj-following */\
X (HurtMsg),/* imhurttin */\
#define HOOK_LIST(X) \
X (NetVars),/* add to archive table (netsave) */\
@ -56,7 +57,6 @@ automatically.
X (JumpSpinSpecial),/* P_DoJumpStuff (Spin button effect (mid-air)) */\
X (BotTiccmd),/* B_BuildTiccmd */\
X (PlayerMsg),/* chat messages */\
X (HurtMsg),/* imhurttin */\
X (PlayerSpawn),/* G_SpawnPlayer */\
X (ShieldSpawn),/* P_SpawnShieldOrb */\
X (ShieldSpecial),/* shield abilities */\
@ -74,10 +74,6 @@ automatically.
X (PlayerCanEnterSpinGaps),\
X (KeyDown),\
X (KeyUp),\
X (GamepadButtonDown),\
X (GamepadButtonUp),\
X (GamepadAdded),\
X (GamepadRemoved),\
#define STRING_HOOK_LIST(X) \
X (BotAI),/* B_BuildTailsTiccmd by skin name */\
@ -129,8 +125,6 @@ void LUA_HookBool(boolean value, int hook);
int LUA_HookPlayer(player_t *, int hook);
int LUA_HookTiccmd(player_t *, ticcmd_t *, int hook);
int LUA_HookKey(event_t *event, int hook); // Hooks for key events
int LUA_HookGamepadButton(event_t *event, int hook);
void LUA_HookGamepadEvent(UINT8 which, int hook);
void LUA_HookThinkFrame(void);
int LUA_HookMobjLineCollide(mobj_t *, line_t *);

View file

@ -14,7 +14,6 @@
#include "doomstat.h"
#include "p_mobj.h"
#include "g_game.h"
#include "g_input.h"
#include "r_skins.h"
#include "b_bot.h"
#include "z_zone.h"
@ -73,7 +72,7 @@ static boolean mobj_hook_available(int hook_type, mobjtype_t mobj_type)
return
(
mobjHookIds [MT_NULL] [hook_type].numHooks > 0 ||
mobjHookIds[mobj_type][hook_type].numHooks > 0
(mobj_type < NUMMOBJTYPES && mobjHookIds[mobj_type][hook_type].numHooks > 0)
);
}
@ -344,8 +343,11 @@ static boolean prepare_mobj_hook
Hook_State * hook,
int default_status,
int hook_type,
mobjtype_t mobj_type
mobj_t * primary_mobj
){
const mobjtype_t mobj_type =
primary_mobj ? primary_mobj->type : NUMMOBJTYPES;
#ifdef PARANOIA
if (mobj_type == MT_NULL)
I_Error("MT_NULL has been passed to a mobj hook\n");
@ -506,7 +508,9 @@ static int call_hooks
{
/* call generic mobj hooks first */
calls += call_mobj_type_hooks(hook, MT_NULL);
calls += call_mobj_type_hooks(hook, hook->mobj_type);
if (hook->mobj_type < NUMMOBJTYPES)
calls += call_mobj_type_hooks(hook, hook->mobj_type);
ps_lua_mobjhooks.value.i += calls;
}
@ -554,7 +558,7 @@ static void res_force(Hook_State *hook)
int LUA_HookMobj(mobj_t *mobj, int hook_type)
{
Hook_State hook;
if (prepare_mobj_hook(&hook, false, hook_type, mobj->type))
if (prepare_mobj_hook(&hook, false, hook_type, mobj))
{
LUA_PushUserdata(gL, mobj, META_MOBJ);
call_hooks(&hook, 1, res_true);
@ -565,7 +569,7 @@ int LUA_HookMobj(mobj_t *mobj, int hook_type)
int LUA_Hook2Mobj(mobj_t *t1, mobj_t *t2, int hook_type)
{
Hook_State hook;
if (prepare_mobj_hook(&hook, 0, hook_type, t1->type))
if (prepare_mobj_hook(&hook, 0, hook_type, t1))
{
LUA_PushUserdata(gL, t1, META_MOBJ);
LUA_PushUserdata(gL, t2, META_MOBJ);
@ -642,28 +646,6 @@ int LUA_HookKey(event_t *event, int hook_type)
return hook.status;
}
int LUA_HookGamepadButton(event_t *event, int hook_type)
{
Hook_State hook;
if (prepare_hook(&hook, false, hook_type))
{
LUA_PushUserdata(gL, &gamepads[event->which], META_GAMEPAD);
lua_pushstring(gL, gamepad_button_names[event->key]);
call_hooks(&hook, 1, res_true);
}
return hook.status;
}
void LUA_HookGamepadEvent(UINT8 which, int hook_type)
{
Hook_State hook;
if (prepare_hook(&hook, 0, hook_type))
{
LUA_PushUserdata(gL, &gamepads[which], META_GAMEPAD);
call_hooks(&hook, 0, res_none);
}
}
void LUA_HookHUD(int hook_type, huddrawlist_h list)
{
const hook_t * map = &hudHookIds[hook_type];
@ -735,7 +717,7 @@ void LUA_HookThinkFrame(void)
int LUA_HookMobjLineCollide(mobj_t *mobj, line_t *line)
{
Hook_State hook;
if (prepare_mobj_hook(&hook, 0, MOBJ_HOOK(MobjLineCollide), mobj->type))
if (prepare_mobj_hook(&hook, 0, MOBJ_HOOK(MobjLineCollide), mobj))
{
LUA_PushUserdata(gL, mobj, META_MOBJ);
LUA_PushUserdata(gL, line, META_LINE);
@ -747,7 +729,7 @@ int LUA_HookMobjLineCollide(mobj_t *mobj, line_t *line)
int LUA_HookTouchSpecial(mobj_t *special, mobj_t *toucher)
{
Hook_State hook;
if (prepare_mobj_hook(&hook, false, MOBJ_HOOK(TouchSpecial), special->type))
if (prepare_mobj_hook(&hook, false, MOBJ_HOOK(TouchSpecial), special))
{
LUA_PushUserdata(gL, special, META_MOBJ);
LUA_PushUserdata(gL, toucher, META_MOBJ);
@ -767,7 +749,7 @@ static int damage_hook
Hook_Callback results_handler
){
Hook_State hook;
if (prepare_mobj_hook(&hook, 0, hook_type, target->type))
if (prepare_mobj_hook(&hook, 0, hook_type, target))
{
LUA_PushUserdata(gL, target, META_MOBJ);
LUA_PushUserdata(gL, inflictor, META_MOBJ);
@ -801,7 +783,7 @@ int LUA_HookMobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 d
int LUA_HookMobjMoveBlocked(mobj_t *t1, mobj_t *t2, line_t *line)
{
Hook_State hook;
if (prepare_mobj_hook(&hook, 0, MOBJ_HOOK(MobjMoveBlocked), t1->type))
if (prepare_mobj_hook(&hook, 0, MOBJ_HOOK(MobjMoveBlocked), t1))
{
LUA_PushUserdata(gL, t1, META_MOBJ);
LUA_PushUserdata(gL, t2, META_MOBJ);
@ -928,7 +910,7 @@ int LUA_HookPlayerMsg(int source, int target, int flags, char *msg)
int LUA_HookHurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 damagetype)
{
Hook_State hook;
if (prepare_hook(&hook, false, HOOK(HurtMsg)))
if (prepare_mobj_hook(&hook, false, MOBJ_HOOK(HurtMsg), inflictor))
{
LUA_PushUserdata(gL, player, META_PLAYER);
LUA_PushUserdata(gL, inflictor, META_MOBJ);
@ -972,7 +954,7 @@ void LUA_HookNetArchive(lua_CFunction archFunc)
int LUA_HookMapThingSpawn(mobj_t *mobj, mapthing_t *mthing)
{
Hook_State hook;
if (prepare_mobj_hook(&hook, false, MOBJ_HOOK(MapThingSpawn), mobj->type))
if (prepare_mobj_hook(&hook, false, MOBJ_HOOK(MapThingSpawn), mobj))
{
LUA_PushUserdata(gL, mobj, META_MOBJ);
LUA_PushUserdata(gL, mthing, META_MAPTHING);
@ -984,7 +966,7 @@ int LUA_HookMapThingSpawn(mobj_t *mobj, mapthing_t *mthing)
int LUA_HookFollowMobj(player_t *player, mobj_t *mobj)
{
Hook_State hook;
if (prepare_mobj_hook(&hook, false, MOBJ_HOOK(FollowMobj), mobj->type))
if (prepare_mobj_hook(&hook, false, MOBJ_HOOK(FollowMobj), mobj))
{
LUA_PushUserdata(gL, player, META_PLAYER);
LUA_PushUserdata(gL, mobj, META_MOBJ);

View file

@ -15,7 +15,6 @@
#include "g_game.h"
#include "hu_stuff.h"
#include "i_system.h"
#include "i_gamepad.h"
#include "lua_script.h"
#include "lua_libs.h"
@ -31,7 +30,7 @@ static int lib_gameControlDown(lua_State *L)
int i = luaL_checkinteger(L, 1);
if (i < 0 || i >= NUM_GAMECONTROLS)
return luaL_error(L, "GC_* constant %d out of range (0 - %d)", i, NUM_GAMECONTROLS-1);
lua_pushinteger(L, G_PlayerInputDown(0, i));
lua_pushinteger(L, PLAYER1INPUTDOWN(i));
return 1;
}
@ -40,7 +39,7 @@ static int lib_gameControl2Down(lua_State *L)
int i = luaL_checkinteger(L, 1);
if (i < 0 || i >= NUM_GAMECONTROLS)
return luaL_error(L, "GC_* constant %d out of range (0 - %d)", i, NUM_GAMECONTROLS-1);
lua_pushinteger(L, G_PlayerInputDown(1, i));
lua_pushinteger(L, PLAYER2INPUTDOWN(i));
return 1;
}
@ -67,14 +66,14 @@ static int lib_gameControl2ToKeyNum(lua_State *L)
static int lib_joyAxis(lua_State *L)
{
int i = luaL_checkinteger(L, 1);
lua_pushinteger(L, G_JoyAxis(0, i) / 32);
lua_pushinteger(L, JoyAxis(i));
return 1;
}
static int lib_joy2Axis(lua_State *L)
{
int i = luaL_checkinteger(L, 1);
lua_pushinteger(L, G_JoyAxis(1, i) / 32);
lua_pushinteger(L, Joy2Axis(i));
return 1;
}
@ -129,21 +128,6 @@ static int lib_getCursorPosition(lua_State *L)
return 2;
}
static int lib_getPlayerGamepad(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
if (!player)
return LUA_ErrInvalid(L, "player_t");
INT16 which = G_GetGamepadForPlayer(player);
if (which >= 0)
LUA_PushUserdata(L, &gamepads[which], META_GAMEPAD);
else
lua_pushnil(L);
return 1;
}
static luaL_Reg lib[] = {
{"gameControlDown", lib_gameControlDown},
{"gameControl2Down", lib_gameControl2Down},
@ -158,7 +142,6 @@ static luaL_Reg lib[] = {
{"getMouseGrab", lib_getMouseGrab},
{"setMouseGrab", lib_setMouseGrab},
{"getCursorPosition", lib_getCursorPosition},
{"getPlayerGamepad", lib_getPlayerGamepad},
{NULL, NULL}
};
@ -214,341 +197,6 @@ static int keyevent_get(lua_State *L)
return 1;
}
/////////////
// GAMEPAD //
/////////////
enum gamepad_leftright_e {
gamepad_opt_left,
gamepad_opt_right
};
static const char *const gamepad_leftright_opt[] = {
"left",
"right",
NULL};
// Buttons
static int gamepad_isButtonDown(lua_State *L)
{
gamepad_t *gamepad = *((gamepad_t **)luaL_checkudata(L, 1, META_GAMEPAD));
gamepad_button_e button = luaL_checkoption(L, 2, NULL, gamepad_button_names);
lua_pushboolean(L, gamepad->buttons[button] == 1);
return 1;
}
// Axes
static int gamepad_getAxis(lua_State *L)
{
gamepad_t *gamepad = *((gamepad_t **)luaL_checkudata(L, 1, META_GAMEPAD));
gamepad_axis_e axis = luaL_checkoption(L, 2, NULL, gamepad_axis_names);
boolean applyDeadzone = luaL_opt(L, luaL_checkboolean, 3, true);
lua_pushfixed(L, G_GetAdjustedGamepadAxis(gamepad->num, axis, applyDeadzone));
return 1;
}
// Sticks
static int gamepad_getStick(lua_State *L)
{
gamepad_t *gamepad = *((gamepad_t **)luaL_checkudata(L, 1, META_GAMEPAD));
enum gamepad_leftright_e stick = luaL_checkoption(L, 2, NULL, gamepad_leftright_opt);
boolean applyDeadzone = luaL_opt(L, luaL_checkboolean, 3, true);
switch (stick)
{
case gamepad_opt_left:
lua_pushfixed(L, G_GetAdjustedGamepadAxis(gamepad->num, GAMEPAD_AXIS_LEFTX, applyDeadzone));
lua_pushfixed(L, G_GetAdjustedGamepadAxis(gamepad->num, GAMEPAD_AXIS_LEFTY, applyDeadzone));
break;
case gamepad_opt_right:
lua_pushfixed(L, G_GetAdjustedGamepadAxis(gamepad->num, GAMEPAD_AXIS_RIGHTX, applyDeadzone));
lua_pushfixed(L, G_GetAdjustedGamepadAxis(gamepad->num, GAMEPAD_AXIS_RIGHTY, applyDeadzone));
break;
}
return 2;
}
// Triggers
static int gamepad_getTrigger(lua_State *L)
{
gamepad_t *gamepad = *((gamepad_t **)luaL_checkudata(L, 1, META_GAMEPAD));
enum gamepad_leftright_e stick = luaL_checkoption(L, 2, NULL, gamepad_leftright_opt);
boolean applyDeadzone = luaL_opt(L, luaL_checkboolean, 3, true);
gamepad_axis_e axis = 0;
switch (stick)
{
case gamepad_opt_left:
axis = GAMEPAD_AXIS_TRIGGERLEFT;
break;
case gamepad_opt_right:
axis = GAMEPAD_AXIS_TRIGGERRIGHT;
break;
}
lua_pushfixed(L, G_GetAdjustedGamepadAxis(gamepad->num, axis, applyDeadzone));
return 1;
}
// Button and axis names
static int gamepad_getButtonName(lua_State *L)
{
gamepad_t *gamepad = *((gamepad_t **)luaL_checkudata(L, 1, META_GAMEPAD));
gamepad_button_e button = luaL_checkoption(L, 2, NULL, gamepad_button_names);
lua_pushstring(L, G_GetGamepadButtonString(gamepad->type, button, GAMEPAD_STRING_DEFAULT));
return 1;
}
static int gamepad_getAxisName(lua_State *L)
{
gamepad_t *gamepad = *((gamepad_t **)luaL_checkudata(L, 1, META_GAMEPAD));
gamepad_axis_e axis = luaL_checkoption(L, 2, NULL, gamepad_axis_names);
lua_pushstring(L, G_GetGamepadAxisString(gamepad->type, axis, GAMEPAD_STRING_DEFAULT, false));
return 1;
}
static int gamepad_getTriggerName(lua_State *L)
{
gamepad_t *gamepad = *((gamepad_t **)luaL_checkudata(L, 1, META_GAMEPAD));
enum gamepad_leftright_e stick = luaL_checkoption(L, 2, NULL, gamepad_leftright_opt);
gamepad_axis_e axis = 0;
switch (stick)
{
case gamepad_opt_left:
axis = GAMEPAD_AXIS_TRIGGERLEFT;
break;
case gamepad_opt_right:
axis = GAMEPAD_AXIS_TRIGGERRIGHT;
break;
}
lua_pushstring(L, G_GetGamepadAxisString(gamepad->type, axis, GAMEPAD_STRING_DEFAULT, false));
return 1;
}
// Rumble
static int gamepad_doRumble(lua_State *L)
{
gamepad_t *gamepad = *((gamepad_t **)luaL_checkudata(L, 1, META_GAMEPAD));
fixed_t large_magnitude = luaL_checkfixed(L, 2);
fixed_t small_magnitude = luaL_optfixed(L, 3, large_magnitude);
tic_t duration = luaL_optinteger(L, 4, 0);
#define CHECK_MAGNITUDE(which) \
if (which##_magnitude < 0 || which##_magnitude > FRACUNIT) \
return luaL_error(L, va(#which " motor frequency %f out of range (minimum is 0.0, maximum is 1.0)", \
FixedToFloat(which##_magnitude)))
CHECK_MAGNITUDE(large);
CHECK_MAGNITUDE(small);
#undef CHECK_MAGNITUDE
lua_pushboolean(L, G_RumbleGamepad(gamepad->num, large_magnitude, small_magnitude, duration));
return 1;
}
static int gamepad_stopRumble(lua_State *L)
{
gamepad_t *gamepad = *((gamepad_t **)luaL_checkudata(L, 1, META_GAMEPAD));
G_StopGamepadRumble(gamepad->num);
return 0;
}
// Accessing gamepad userdata
enum gamepad_opt_e {
gamepad_opt_connected,
gamepad_opt_type,
gamepad_opt_isXbox,
gamepad_opt_isPlayStation,
gamepad_opt_isNintendoSwitch,
gamepad_opt_isJoyCon,
gamepad_opt_hasRumble,
gamepad_opt_isRumbling,
gamepad_opt_isRumblePaused,
gamepad_opt_largeMotorFrequency,
gamepad_opt_smallMotorFrequency,
gamepad_opt_isButtonDown,
gamepad_opt_getAxis,
gamepad_opt_getStick,
gamepad_opt_getTrigger,
gamepad_opt_getButtonName,
gamepad_opt_getAxisName,
gamepad_opt_getTriggerName,
gamepad_opt_rumble,
gamepad_opt_stopRumble
};
static const char *const gamepad_opt[] = {
"connected",
"type",
"isXbox",
"isPlayStation",
"isNintendoSwitch",
"isJoyCon",
"hasRumble",
"isRumbling",
"isRumblePaused",
"largeMotorFrequency",
"smallMotorFrequency",
"isButtonDown",
"getAxis",
"getStick",
"getTrigger",
"getButtonName",
"getAxisName",
"getTriggerName",
"rumble",
"stopRumble",
NULL};
static int (*gamepad_fn_list[9])(lua_State *L) = {
gamepad_isButtonDown,
gamepad_getAxis,
gamepad_getStick,
gamepad_getTrigger,
gamepad_getButtonName,
gamepad_getAxisName,
gamepad_getTriggerName,
gamepad_doRumble,
gamepad_stopRumble
};
static int gamepad_get(lua_State *L)
{
gamepad_t *gamepad = *((gamepad_t **)luaL_checkudata(L, 1, META_GAMEPAD));
enum gamepad_opt_e field = luaL_checkoption(L, 2, NULL, gamepad_opt);
switch (field)
{
case gamepad_opt_connected:
lua_pushboolean(L, gamepad->connected);
break;
case gamepad_opt_type:
lua_pushstring(L, G_GamepadTypeToString(gamepad->type));
break;
case gamepad_opt_isXbox:
lua_pushboolean(L, G_GamepadTypeIsXbox(gamepad->type));
break;
case gamepad_opt_isPlayStation:
lua_pushboolean(L, G_GamepadTypeIsPlayStation(gamepad->type));
break;
case gamepad_opt_isNintendoSwitch:
lua_pushboolean(L, G_GamepadTypeIsNintendoSwitch(gamepad->type));
break;
case gamepad_opt_isJoyCon:
// No, this does not include the grip.
lua_pushboolean(L, G_GamepadTypeIsJoyCon(gamepad->type));
break;
case gamepad_opt_hasRumble:
lua_pushboolean(L, G_RumbleSupported(gamepad->num));
break;
case gamepad_opt_isRumbling:
lua_pushboolean(L, gamepad->rumble.active);
break;
case gamepad_opt_isRumblePaused:
lua_pushboolean(L, G_GetGamepadRumblePaused(gamepad->num));
break;
case gamepad_opt_largeMotorFrequency:
lua_pushfixed(L, G_GetLargeMotorFreq(gamepad->num));
break;
case gamepad_opt_smallMotorFrequency:
lua_pushfixed(L, G_GetSmallMotorFreq(gamepad->num));
break;
case gamepad_opt_isButtonDown:
case gamepad_opt_getAxis:
case gamepad_opt_getStick:
case gamepad_opt_getTrigger:
case gamepad_opt_getButtonName:
case gamepad_opt_getAxisName:
case gamepad_opt_getTriggerName:
case gamepad_opt_rumble:
case gamepad_opt_stopRumble:
lua_pushcfunction(L, gamepad_fn_list[field - gamepad_opt_isButtonDown]);
break;
}
return 1;
}
static int gamepad_set(lua_State *L)
{
gamepad_t *gamepad = *((gamepad_t **)luaL_checkudata(L, 1, META_GAMEPAD));
enum gamepad_opt_e field = luaL_checkoption(L, 2, NULL, gamepad_opt);
switch (field)
{
case gamepad_opt_isRumblePaused:
G_SetGamepadRumblePaused(gamepad->num, luaL_checkboolean(L, 3));
break;
case gamepad_opt_largeMotorFrequency:
G_SetLargeMotorFreq(gamepad->num, luaL_checkfixed(L, 3));
break;
case gamepad_opt_smallMotorFrequency:
G_SetSmallMotorFreq(gamepad->num, luaL_checkfixed(L, 3));
break;
default:
return luaL_error(L, LUA_QL("gamepad") " field " LUA_QS " should not be set directly.", gamepad_opt[field]);
}
return 1;
}
static int gamepad_num(lua_State *L)
{
gamepad_t *gamepad = *((gamepad_t **)luaL_checkudata(L, 1, META_GAMEPAD));
lua_pushinteger(L, gamepad->num + 1);
return 1;
}
static int lib_iterateGamepads(lua_State *L)
{
INT32 i = -1;
if (lua_gettop(L) < 2)
{
lua_pushcfunction(L, lib_iterateGamepads);
return 1;
}
lua_settop(L, 2);
lua_remove(L, 1); // State is unused
if (!lua_isnil(L, 1))
i = (INT32)(*((gamepad_t **)luaL_checkudata(L, 1, META_GAMEPAD)) - gamepads);
for (i++; i < NUM_GAMEPADS; i++)
{
if (!gamepads[i].connected)
continue;
LUA_PushUserdata(L, &gamepads[i], META_GAMEPAD);
return 1;
}
return 0;
}
static int lib_getGamepad(lua_State *L)
{
if (lua_type(L, 2) == LUA_TNUMBER)
{
lua_Integer i = luaL_checkinteger(L, 2);
if (i < 1 || i > NUM_GAMEPADS)
return luaL_error(L, "gamepads[] index %d out of range (1 - %d)", i, NUM_GAMEPADS);
LUA_PushUserdata(L, &gamepads[i - 1], META_GAMEPAD);
return 1;
}
if (fastcmp(luaL_checkstring(L, 2), "iterate"))
{
lua_pushcfunction(L, lib_iterateGamepads);
return 1;
}
return 0;
}
static int lib_lenGamepad(lua_State *L)
{
lua_pushinteger(L, NUM_GAMEPADS);
return 1;
}
///////////
// MOUSE //
///////////
@ -609,27 +257,6 @@ int LUA_InputLib(lua_State *L)
lua_setfield(L, -2, "__index");
lua_pop(L, 1);
luaL_newmetatable(L, META_GAMEPAD);
lua_pushcfunction(L, gamepad_get);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, gamepad_set);
lua_setfield(L, -2, "__newindex");
lua_pushcfunction(L, gamepad_num);
lua_setfield(L, -2, "__len");
lua_pop(L, 1);
lua_newuserdata(L, 0);
lua_createtable(L, 0, 2);
lua_pushcfunction(L, lib_getGamepad);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, lib_lenGamepad);
lua_setfield(L, -2, "__len");
lua_setmetatable(L, -2);
lua_setglobal(L, "gamepads");
luaL_newmetatable(L, META_MOUSE);
lua_pushcfunction(L, mouse_get);
lua_setfield(L, -2, "__index");

View file

@ -91,7 +91,6 @@ extern boolean mousegrabbedbylua;
#define META_LUABANKS "LUABANKS[]*"
#define META_KEYEVENT "KEYEVENT_T*"
#define META_GAMEPAD "GAMEPAD_T*"
#define META_MOUSE "MOUSE_T*"
boolean luaL_checkboolean(lua_State *L, int narg);

View file

@ -949,7 +949,6 @@ enum
ARCH_MAPHEADER,
ARCH_SKINCOLOR,
ARCH_MOUSE,
ARCH_GAMEPAD,
ARCH_TEND=0xFF,
};
@ -977,7 +976,6 @@ static const struct {
{META_SLOPE, ARCH_SLOPE},
{META_MAPHEADER, ARCH_MAPHEADER},
{META_SKINCOLOR, ARCH_SKINCOLOR},
{META_GAMEPAD, ARCH_GAMEPAD},
{META_MOUSE, ARCH_MOUSE},
{NULL, ARCH_NULL}
};
@ -1293,13 +1291,6 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
WRITEUINT16(save_p, info - skincolors);
break;
}
case ARCH_GAMEPAD:
{
gamepad_t *gamepad = *((gamepad_t **)lua_touserdata(gL, myindex));
WRITEUINT8(save_p, ARCH_GAMEPAD);
WRITEUINT8(save_p, gamepad->num);
break;
}
case ARCH_MOUSE:
{
mouse_t *m = *((mouse_t **)lua_touserdata(gL, myindex));
@ -1550,15 +1541,6 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
case ARCH_SKINCOLOR:
LUA_PushUserdata(gL, &skincolors[READUINT16(save_p)], META_SKINCOLOR);
break;
case ARCH_GAMEPAD:
{
UINT8 which = READUINT8(save_p);
if (which < NUM_GAMEPADS)
LUA_PushUserdata(gL, &gamepads[which], META_GAMEPAD);
else // Wait, what?
lua_pushnil(gL);
break;
}
case ARCH_MOUSE:
LUA_PushUserdata(gL, READUINT16(save_p) == 1 ? &mouse : &mouse2, META_MOUSE);
break;

View file

@ -30,13 +30,11 @@
// TODO add some distinction between fixed numbers and integer numbers
// for at least the purpose of printing and maybe math.
#define luaL_checkfixed(L, i) luaL_checkinteger(L, i)
#define luaL_optfixed(L, i, o) luaL_optinteger(L, i, o)
#define lua_pushfixed(L, f) lua_pushinteger(L, f)
// angle_t casting
// TODO deal with signedness
#define luaL_checkangle(L, i) ((angle_t)luaL_checkinteger(L, i))
#define luaL_optangle(L, i, o) ((angle_t)luaL_optinteger(L, i, o))
#define lua_pushangle(L, a) lua_pushinteger(L, a)
#ifdef _DEBUG

View file

@ -199,41 +199,39 @@ static UINT8 cht_CheckCheat(cheatseq_t *cht, char key)
boolean cht_Responder(event_t *ev)
{
UINT8 ch = 0;
UINT8 ret = 0, ch = 0;
if (ev->type != ev_keydown)
return false;
if (ev->type == ev_gamepad_down)
if (ev->key > 0xFF)
{
// map some fake (joy) inputs into keys
// map joy inputs into keys
switch (ev->key)
{
case GAMEPAD_BUTTON_DPAD_UP:
case KEY_JOY1:
case KEY_JOY1 + 2:
ch = KEY_ENTER;
break;
case KEY_HAT1:
ch = KEY_UPARROW;
break;
case GAMEPAD_BUTTON_DPAD_DOWN:
case KEY_HAT1 + 1:
ch = KEY_DOWNARROW;
break;
case GAMEPAD_BUTTON_DPAD_LEFT:
case KEY_HAT1 + 2:
ch = KEY_LEFTARROW;
break;
case GAMEPAD_BUTTON_DPAD_RIGHT:
case KEY_HAT1 + 3:
ch = KEY_RIGHTARROW;
break;
case GAMEPAD_BUTTON_START:
ch = KEY_ENTER;
break;
default:
// no mapping
return false;
}
}
else if (ev->type == ev_keydown)
{
if (ev->key > 0xFF)
return false;
else
ch = (UINT8)ev->key;
}
UINT8 ret = 0;
ret += cht_CheckCheat(&cheat_ultimate, (char)ch);
ret += cht_CheckCheat(&cheat_ultimate_joy, (char)ch);

File diff suppressed because it is too large Load diff

View file

@ -223,9 +223,8 @@ typedef enum
{
MM_NOTHING = 0, // is just displayed until the user do someting
MM_YESNO, // routine is called with only 'y' or 'n' in param
MM_KEYHANDLER, // the same of above but without 'y' or 'n' restriction
MM_EVENTHANDLER // the same of above but routine is void routine(event_t *)
// (ex: set control)
MM_EVENTHANDLER // the same of above but without 'y' or 'n' restriction
// and routine is void routine(event_t *) (ex: set control)
} menumessagetype_t;
void M_StartMessage(const char *string, void *routine, menumessagetype_t itemtype);
@ -362,11 +361,9 @@ extern menu_t *currentMenu;
extern menu_t MainDef;
extern menu_t SP_LoadDef;
// Call when a gamepad is connected or disconnected
void M_UpdateGamepadMenu(void);
// Returns true if the player is on the gamepad selection menu
boolean M_OnGamepadMenu(void);
// Call upon joystick hotplug
void M_SetupJoystickMenu(INT32 choice);
extern menu_t OP_JoystickSetDef;
// Stuff for customizing the player select screen
typedef struct
@ -541,19 +538,6 @@ void M_FreePlayerSetupColors(void);
NULL\
}
#define GAMEPADMENUSTYLE(id, header, source, prev, x, y)\
{\
id,\
header,\
sizeof(source)/sizeof(menuitem_t),\
prev,\
source,\
M_DrawGamepadMenu,\
x, y,\
0,\
NULL\
}
#define MAPPLATTERMENUSTYLE(id, header, source)\
{\
id,\
@ -574,7 +558,7 @@ void M_FreePlayerSetupColors(void);
sizeof (source)/sizeof (menuitem_t),\
prev,\
source,\
M_DrawControlConfigMenu,\
M_DrawControl,\
24, 40,\
0,\
NULL\

View file

@ -2671,7 +2671,7 @@ void A_LobShot(mobj_t *actor)
fixed_t z;
fixed_t dist;
fixed_t vertical, horizontal;
fixed_t airtime = var2 & 65535;
fixed_t airtime = max(1, var2 & 65535);
if (LUA_CallAction(A_LOBSHOT, actor))
return;
@ -4859,12 +4859,12 @@ void A_FishJump(mobj_t *actor)
else
{
if (actor->spawnpoint && actor->spawnpoint->args[0])
jumpval = actor->spawnpoint->args[0];
jumpval = actor->spawnpoint->args[0] << (FRACBITS - 2);
else
jumpval = 44;
jumpval = 44 << (FRACBITS - 2);
}
actor->momz = FixedMul(jumpval << (FRACBITS - 2), actor->scale);
actor->momz = FixedMul(jumpval, actor->scale);
P_SetMobjStateNF(actor, actor->info->seestate);
}

View file

@ -1,115 +0,0 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2021-2022 by Jaime "Lactozilla" Passos.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file p_haptic.c
/// \brief Haptic feedback
#include "p_haptic.h"
#include "g_game.h"
#include "d_netcmd.h"
#include "i_gamepad.h"
#include "doomstat.h"
// Helper function: Returns the gamepad index for a player if it's enabled
static INT16 GetGamepadIndex(player_t *player)
{
INT16 index = G_GetGamepadForPlayer(player);
if (index >= 0 && cv_usegamepad[index].value)
return index;
return -1;
}
// Rumbles a player's gamepad, or all gamepads
boolean P_DoRumble(player_t *player, fixed_t large_magnitude, fixed_t small_magnitude, tic_t duration)
{
if (!I_RumbleSupported())
return false;
// Rumble every gamepad
if (player == NULL)
{
for (UINT8 i = 0; i < NUM_GAMEPADS; i++)
{
if (cv_gamepad_rumble[i].value)
G_RumbleGamepad(i, large_magnitude, small_magnitude, duration);
}
return true;
}
INT16 which = GetGamepadIndex(player);
if (which < 0 || !cv_gamepad_rumble[which].value)
return false;
return G_RumbleGamepad((UINT8)which, large_magnitude, small_magnitude, duration);
}
// Pauses or unpauses gamepad rumble for a player (or all of them)
// Rumble is paused or unpaused regardless if it's enabled or not
static void SetRumblePaused(player_t *player, boolean pause)
{
INT16 which = GetGamepadIndex(player);
if (which >= 0)
G_SetGamepadRumblePaused((UINT8)which, pause);
else if (player == NULL)
{
// Pause or unpause every gamepad
for (UINT8 i = 0; i < NUM_GAMEPADS; i++)
G_SetGamepadRumblePaused(i, pause);
}
}
void P_PauseRumble(player_t *player)
{
SetRumblePaused(player, true);
}
void P_UnpauseRumble(player_t *player)
{
SetRumblePaused(player, false);
}
boolean P_IsRumbleEnabled(player_t *player)
{
INT16 which = GetGamepadIndex(player);
if (which < 0 || !cv_gamepad_rumble[which].value)
return false;
return G_RumbleSupported((UINT8)which);
}
boolean P_IsRumblePaused(player_t *player)
{
INT16 which = GetGamepadIndex(player);
if (which < 0 || !cv_gamepad_rumble[which].value)
return false;
return G_GetGamepadRumblePaused((UINT8)which);
}
// Stops gamepad rumble for a player (or all of them)
void P_StopRumble(player_t *player)
{
if (!I_RumbleSupported())
return;
if (player)
{
INT16 which = GetGamepadIndex(player);
if (which >= 0)
G_StopGamepadRumble((UINT8)which);
return;
}
// Stop every gamepad instead
for (UINT8 i = 0; i < NUM_GAMEPADS; i++)
G_StopGamepadRumble(i);
}

View file

@ -1,27 +0,0 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2021-2022 by Jaime "Lactozilla" Passos.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file p_haptic.h
/// \brief Haptic feedback
#ifndef __P_HAPTIC__
#define __P_HAPTIC__
#include "doomdef.h"
#include "p_local.h"
boolean P_DoRumble(player_t *player, fixed_t large_magnitude, fixed_t small_magnitude, tic_t duration);
void P_PauseRumble(player_t *player);
void P_UnpauseRumble(player_t *player);
boolean P_IsRumbleEnabled(player_t *player);
boolean P_IsRumblePaused(player_t *player);
void P_StopRumble(player_t *player);
#define P_DoRumbleCombined(player, magnitude, dur) P_DoRumble(player, magnitude, magnitude, dur);
#endif // __P_HAPTIC__

View file

@ -13,7 +13,6 @@
#include "doomdef.h"
#include "i_system.h"
#include "i_gamepad.h"
#include "am_map.h"
#include "g_game.h"
#include "m_random.h"
@ -25,7 +24,6 @@
#include "lua_hook.h"
#include "m_cond.h" // unlockables, emblems, etc
#include "p_setup.h"
#include "p_haptic.h"
#include "m_cheat.h" // objectplace
#include "m_misc.h"
#include "v_video.h" // video flags for CEchos
@ -35,6 +33,54 @@
#define CTFTEAMCODE(pl) pl->ctfteam ? (pl->ctfteam == 1 ? "\x85" : "\x84") : ""
#define CTFTEAMENDCODE(pl) pl->ctfteam ? "\x80" : ""
void P_ForceFeed(const player_t *player, INT32 attack, INT32 fade, tic_t duration, INT32 period)
{
BasicFF_t Basicfeed;
if (!player)
return;
Basicfeed.Duration = (UINT32)(duration * (100L/TICRATE));
Basicfeed.ForceX = Basicfeed.ForceY = 1;
Basicfeed.Gain = 25000;
Basicfeed.Magnitude = period*10;
Basicfeed.player = player;
/// \todo test FFB
P_RampConstant(&Basicfeed, attack, fade);
}
void P_ForceConstant(const BasicFF_t *FFInfo)
{
JoyFF_t ConstantQuake;
if (!FFInfo || !FFInfo->player)
return;
ConstantQuake.ForceX = FFInfo->ForceX;
ConstantQuake.ForceY = FFInfo->ForceY;
ConstantQuake.Duration = FFInfo->Duration;
ConstantQuake.Gain = FFInfo->Gain;
ConstantQuake.Magnitude = FFInfo->Magnitude;
if (FFInfo->player == &players[consoleplayer])
I_Tactile(ConstantForce, &ConstantQuake);
else if (splitscreen && FFInfo->player == &players[secondarydisplayplayer])
I_Tactile2(ConstantForce, &ConstantQuake);
}
void P_RampConstant(const BasicFF_t *FFInfo, INT32 Start, INT32 End)
{
JoyFF_t RampQuake;
if (!FFInfo || !FFInfo->player)
return;
RampQuake.ForceX = FFInfo->ForceX;
RampQuake.ForceY = FFInfo->ForceY;
RampQuake.Duration = FFInfo->Duration;
RampQuake.Gain = FFInfo->Gain;
RampQuake.Magnitude = FFInfo->Magnitude;
RampQuake.Start = Start;
RampQuake.End = End;
if (FFInfo->player == &players[consoleplayer])
I_Tactile(ConstantForce, &RampQuake);
else if (splitscreen && FFInfo->player == &players[secondarydisplayplayer])
I_Tactile2(ConstantForce, &RampQuake);
}
//
// GET STUFF
//
@ -3011,8 +3057,6 @@ static boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, IN
player_t *player = target->player;
(void)damage; //unused parm
P_DoRumbleCombined(player, FRACUNIT, TICRATE / 6);
// If flashing or invulnerable, ignore the tag,
if (player->powers[pw_flashing] || player->powers[pw_invulnerability])
return false;
@ -3116,8 +3160,6 @@ static boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj_t *sou
{
player_t *player = target->player;
(void)damage;
if (!(damagetype & DMG_CANHURTSELF))
{
// You can't kill yourself, idiot...
@ -3180,8 +3222,6 @@ static boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj_t *sou
static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
{
(void)damage;
player->pflags &= ~PF_SLIDING;
player->powers[pw_carry] = CR_NONE;
@ -3202,7 +3242,7 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
// Get rid of emeralds
player->powers[pw_emeralds] = 0;
P_DoRumbleCombined(player, FRACUNIT, TICRATE / 3);
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
P_ResetPlayer(player);
@ -3242,9 +3282,7 @@ static void P_SuperDamage(player_t *player, mobj_t *inflictor, mobj_t *source, I
fixed_t fallbackspeed;
angle_t ang;
(void)damage;
P_DoRumbleCombined(player, FRACUNIT, TICRATE / 6);
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
if (player->mo->eflags & MFE_VERTICALFLIP)
player->mo->z--;
@ -3325,14 +3363,12 @@ void P_RemoveShield(player_t *player)
static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype)
{
(void)damage;
// Must do pain first to set flashing -- P_RemoveShield can cause damage
P_DoPlayerPain(player, source, inflictor);
P_RemoveShield(player);
P_DoRumbleCombined(player, FRACUNIT, TICRATE / 6);
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
if (damagetype == DMG_SPIKE) // spikes
S_StartSound(player->mo, sfx_spkdth);
@ -3361,7 +3397,7 @@ static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, IN
{
P_DoPlayerPain(player, source, inflictor);
P_DoRumbleCombined(player, FRACUNIT, TICRATE / 6);
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
if (damagetype == DMG_SPIKE) // spikes
S_StartSound(player->mo, sfx_spkdth);
@ -3692,6 +3728,8 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
damage = 1;
P_KillPlayer(player, source, damage);
}
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
}
// Killing dead. Just for kicks.

View file

@ -453,6 +453,18 @@ extern mobj_t **blocklinks; // for thing chains
//
// P_INTER
//
typedef struct BasicFF_s
{
INT32 ForceX; ///< The X of the Force's Vel
INT32 ForceY; ///< The Y of the Force's Vel
const player_t *player; ///< Player of Rumble
//All
UINT32 Duration; ///< The total duration of the effect, in microseconds
INT32 Gain; ///< /The gain to be applied to the effect, in the range from 0 through 10,000.
//All, CONSTANTFORCE <20>10,000 to 10,000
INT32 Magnitude; ///< Magnitude of the effect, in the range from 0 through 10,000.
} BasicFF_t;
/* Damage/death types, for P_DamageMobj and related */
//// Damage types
//#define DMG_NORMAL 0 (unneeded?)
@ -473,6 +485,9 @@ extern mobj_t **blocklinks; // for thing chains
#define DMG_CANHURTSELF 0x40 // Flag - can hurt self/team indirectly, such as through mines
#define DMG_DEATHMASK DMG_INSTAKILL // if bit 7 is set, this is a death type instead of a damage type
void P_ForceFeed(const player_t *player, INT32 attack, INT32 fade, tic_t duration, INT32 period);
void P_ForceConstant(const BasicFF_t *FFInfo);
void P_RampConstant(const BasicFF_t *FFInfo, INT32 Start, INT32 End);
void P_RemoveShield(player_t *player);
void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source);
boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype);

View file

@ -3989,12 +3989,11 @@ void P_NullPrecipThinker(precipmobj_t *mobj)
{
//(void)mobj;
mobj->precipflags &= ~PCF_THUNK;
R_ResetPrecipitationMobjInterpolationState(mobj);
}
void P_SnowThinker(precipmobj_t *mobj)
{
R_ResetPrecipitationMobjInterpolationState(mobj);
P_CycleStateAnimation((mobj_t *)mobj);
// adjust height
@ -4007,8 +4006,6 @@ void P_SnowThinker(precipmobj_t *mobj)
void P_RainThinker(precipmobj_t *mobj)
{
R_ResetPrecipitationMobjInterpolationState(mobj);
P_CycleStateAnimation((mobj_t *)mobj);
if (mobj->state != &states[S_RAIN1])
@ -5664,6 +5661,8 @@ static void P_Boss9Thinker(mobj_t *mobj)
{
mobj_t *missile = P_SpawnMissile(spawner, mobj, MT_MSGATHER);
missile->fuse = (dist/P_AproxDistance(missile->momx, missile->momy));
if (missile->fuse <= 0) // Prevents a division by zero when calculating missile->scalespeed
missile->fuse = 1;
if (missile->fuse > mobj->fuse)
P_RemoveMobj(missile);
@ -11195,21 +11194,41 @@ void P_RemovePrecipMobj(precipmobj_t *mobj)
void P_RemoveSavegameMobj(mobj_t *mobj)
{
// unlink from sector and block lists
P_UnsetThingPosition(mobj);
// Remove touching_sectorlist from mobj.
if (sector_list)
if (((thinker_t *)mobj)->function.acp1 == (actionf_p1)P_NullPrecipThinker)
{
P_DelSeclist(sector_list);
sector_list = NULL;
P_UnsetPrecipThingPosition((precipmobj_t *)mobj);
if (precipsector_list)
{
P_DelPrecipSeclist(precipsector_list);
precipsector_list = NULL;
}
}
else
{
// unlink from sector and block lists
P_UnsetThingPosition(mobj);
// Remove touching_sectorlist from mobj.
if (sector_list)
{
P_DelSeclist(sector_list);
sector_list = NULL;
}
}
// stop any playing sound
S_StopSound(mobj);
R_RemoveMobjInterpolator(mobj);
// free block
P_RemoveThinker((thinker_t *)mobj);
R_RemoveMobjInterpolator(mobj);
// Here we use the same code as R_RemoveThinkerDelayed, but without reference counting (we're removing everything so it shouldn't matter) and without touching currentthinker since we aren't in P_RunThinkers
{
thinker_t *thinker = (thinker_t *)mobj;
thinker_t *next = thinker->next;
(next->prev = thinker->prev)->next = next;
Z_Free(thinker);
}
}
static CV_PossibleValue_t respawnitemtime_cons_t[] = {{1, "MIN"}, {300, "MAX"}, {0, NULL}};
@ -13506,7 +13525,7 @@ static void P_SpawnItemRow(mapthing_t *mthing, mobjtype_t *itemtypes, UINT8 numi
static void P_SpawnSingularItemRow(mapthing_t *mthing, mobjtype_t itemtype, INT32 numitems, fixed_t horizontalspacing, fixed_t verticalspacing, INT16 fixedangle, boolean bonustime)
{
mobjtype_t itemtypes[1] = { itemtype };
return P_SpawnItemRow(mthing, itemtypes, 1, numitems, horizontalspacing, verticalspacing, fixedangle, bonustime);
P_SpawnItemRow(mthing, itemtypes, 1, numitems, horizontalspacing, verticalspacing, fixedangle, bonustime);
}
static void P_SpawnItemCircle(mapthing_t *mthing, mobjtype_t *itemtypes, UINT8 numitemtypes, INT32 numitems, fixed_t size, boolean bonustime)

View file

@ -3059,6 +3059,18 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
mobj->player->viewz = mobj->player->mo->z + mobj->player->viewheight;
}
if (mobj->type == MT_SKYBOX && mobj->spawnpoint)
{
mtag_t tag = Tag_FGet(&mobj->spawnpoint->tags);
if (tag >= 0 && tag <= 15)
{
if (mobj->spawnpoint->args[0])
skyboxcenterpnts[tag] = mobj;
else
skyboxviewpnts[tag] = mobj;
}
}
mobj->info = (mobjinfo_t *)next; // temporarily, set when leave this function
R_AddMobjInterpolator(mobj);
@ -3680,10 +3692,14 @@ static void P_NetUnArchiveThinkers(void)
{
next = currentthinker->next;
if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker)
if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker || currentthinker->function.acp1 == (actionf_p1)P_NullPrecipThinker)
P_RemoveSavegameMobj((mobj_t *)currentthinker); // item isn't saved, don't remove it
else
{
(next->prev = currentthinker->prev)->next = next;
R_DestroyLevelInterpolators(currentthinker);
Z_Free(currentthinker);
}
}
}
@ -3885,6 +3901,10 @@ static void P_NetUnArchiveThinkers(void)
CONS_Debug(DBG_NETPLAY, "%u thinkers loaded in list %d\n", numloaded, i);
}
// Set each skyboxmo to the first skybox (or NULL)
skyboxmo[0] = skyboxviewpnts[0];
skyboxmo[1] = skyboxcenterpnts[0];
if (restoreNum)
{
executor_t *delay = NULL;

View file

@ -3009,7 +3009,7 @@ static inline void P_LoadSubsectors(UINT8 *data)
for (i = 0; i < numsubsectors; i++, ss++, ms++)
{
ss->numlines = SHORT(ms->numsegs);
ss->firstline = SHORT(ms->firstseg);
ss->firstline = (UINT16)SHORT(ms->firstseg);
P_InitializeSubsector(ss);
}
}
@ -4910,9 +4910,9 @@ static void P_ConvertBinaryLinedefTypes(void)
case 331: // Player skin - continuous
case 332: // Player skin - each time
case 333: // Player skin - once
if (lines[i].special == 303)
if (lines[i].special == 333)
lines[i].args[0] = TMT_ONCE;
else if (lines[i].special == 302)
else if (lines[i].special == 332)
lines[i].args[0] = (lines[i].flags & ML_BOUNCY) ? TMT_EACHTIMEENTERANDEXIT : TMT_EACHTIMEENTER;
else
lines[i].args[0] = TMT_CONTINUOUS;
@ -6627,8 +6627,8 @@ static void P_ConvertBinaryThingTypes(void)
case 1713: //Hoop (Customizable)
{
UINT16 oldangle = mapthings[i].angle;
mapthings[i].angle = ((oldangle >> 8)*360)/256;
mapthings[i].pitch = ((oldangle & 255)*360)/256;
mapthings[i].angle = (mapthings[i].extrainfo == 1) ? oldangle - 90 : ((oldangle >> 8)*360)/256;
mapthings[i].pitch = (mapthings[i].extrainfo == 1) ? oldangle / 360 : ((oldangle & 255)*360)/256;
mapthings[i].args[0] = (mapthings[i].type == 1705) ? 96 : (mapthings[i].options & 0xF)*16 + 32;
mapthings[i].options &= ~0xF;
mapthings[i].type = 1713;

View file

@ -4984,7 +4984,7 @@ void P_Telekinesis(player_t *player, fixed_t thrust, fixed_t range)
static void P_DoTwinSpin(player_t *player)
{
player->pflags &= ~PF_NOJUMPDAMAGE;
player->pflags &= ~(PF_NOJUMPDAMAGE|PF_SPINNING);
player->pflags |= P_GetJumpFlags(player) | PF_THOKKED;
S_StartSound(player->mo, sfx_s3k42);
player->mo->frame = 0;
@ -5031,6 +5031,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock
if ((player->powers[pw_shield] & ~(SH_FORCEHP|SH_STACK)) == SH_FORCE)
{
player->pflags |= PF_THOKKED|PF_SHIELDABILITY;
player->pflags &= ~PF_SPINNING;
player->mo->momx = player->mo->momy = player->mo->momz = 0;
S_StartSound(player->mo, sfx_ngskid);
}
@ -5046,11 +5047,13 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock
// Armageddon pow
case SH_ARMAGEDDON:
player->pflags |= PF_THOKKED|PF_SHIELDABILITY;
player->pflags &= ~PF_SPINNING;
P_BlackOw(player);
break;
// Attraction blast
case SH_ATTRACT:
player->pflags |= PF_THOKKED|PF_SHIELDABILITY;
player->pflags &= ~PF_SPINNING;
player->homing = 2;
P_SetTarget(&player->mo->target, P_SetTarget(&player->mo->tracer, lockonshield));
if (lockonshield)
@ -5070,6 +5073,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock
{
boolean elem = ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL);
player->pflags |= PF_THOKKED|PF_SHIELDABILITY;
player->pflags &= ~PF_SPINNING;
if (elem)
{
player->mo->momx = player->mo->momy = 0;
@ -5092,7 +5096,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock
player->pflags |= PF_THOKKED|PF_SHIELDABILITY;
P_Thrust(player->mo, player->mo->angle, FixedMul(30*FRACUNIT - FixedSqrt(FixedDiv(player->speed, player->mo->scale)), player->mo->scale));
player->drawangle = player->mo->angle;
player->pflags &= ~PF_NOJUMPDAMAGE;
player->pflags &= ~(PF_NOJUMPDAMAGE|PF_SPINNING);
P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
S_StartSound(player->mo, sfx_s3k43);
default:
@ -5327,9 +5331,9 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
// disabled because it seemed to disorient people and Z-targeting exists now
/*if (!demoplayback)
{
if (player == &players[consoleplayer] && cv_cam_turnfacingability[0].value > 0 && !(G_PlayerInputDown(0, GC_TURNLEFT) || G_PlayerInputDown(0, GC_TURNRIGHT)))
if (player == &players[consoleplayer] && cv_cam_turnfacingability[0].value > 0 && !(PLAYER1INPUTDOWN(GC_TURNLEFT) || PLAYER1INPUTDOWN(GC_TURNRIGHT)))
P_SetPlayerAngle(player, player->mo->angle);;
else if (player == &players[secondarydisplayplayer] && cv_cam_turnfacingability[1].value > 0 && !(G_PlayerInputDown(1, GC_TURNLEFT) || G_PlayerInputDown(1, GC_TURNRIGHT)))
else if (player == &players[secondarydisplayplayer] && cv_cam_turnfacingability[1].value > 0 && !(PLAYER2INPUTDOWN(GC_TURNLEFT) || PLAYER2INPUTDOWN(GC_TURNRIGHT)))
P_SetPlayerAngle(player, player->mo->angle);
}*/
}
@ -5385,7 +5389,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
if (!(player->pflags & PF_THOKKED) || ((player->charflags & SF_MULTIABILITY) && (player->secondjump < (player->actionspd >> FRACBITS))))
{
player->pflags |= PF_THOKKED;
player->pflags &= ~PF_JUMPED;
player->pflags &= ~(PF_JUMPED|PF_SPINNING);
P_DoJump(player, true);
player->secondjump++;
}
@ -5411,6 +5415,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
P_Telekinesis(player,
FixedMul(player->actionspd, player->mo->scale), // +ve thrust (pushing away from player)
FixedMul(384*FRACUNIT, player->mo->scale));
player->pflags &= ~PF_SPINNING;
}
break;
case CA_FALLSWITCH:
@ -5419,6 +5424,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
player->mo->momz = -player->mo->momz;
P_SpawnThokMobj(player);
player->pflags |= PF_THOKKED;
player->pflags &= ~PF_SPINNING;
}
break;
case CA_AIRDRILL:
@ -5426,6 +5432,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
{
player->flyangle = 56 + (60-(player->actionspd>>FRACBITS))/3;
player->pflags |= PF_THOKKED;
player->pflags &= ~PF_SPINNING;
S_StartSound(player->mo, sfx_spndsh);
}
break;
@ -5433,7 +5440,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
if (!(player->pflags & PF_THOKKED) || player->charflags & SF_MULTIABILITY)
{
P_SetPlayerMobjState(player->mo, S_PLAY_BOUNCE);
player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE);
player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_SPINNING);
player->pflags |= PF_THOKKED|PF_BOUNCING;
player->mo->momx >>= 1;
player->mo->momy >>= 1;
@ -7335,7 +7342,7 @@ static void P_NiGHTSMovement(player_t *player)
else if (cmd->forwardmove < 0)
newangle = 270;
}
else // AngleFixed(R_PointToAngle2()) results in slight inaccuracy! Don't use it unless movement is on both axes.
else // AngleFixed(R_PointToAngle2()) results in slight inaccuracy! Don't use it unless movement is on both axises.
newangle = (INT16)FixedInt(AngleFixed(R_PointToAngle2(0,0, cmd->sidemove*FRACUNIT, cmd->forwardmove*FRACUNIT)));
newangle -= player->viewrollangle / ANG1;
@ -11031,6 +11038,21 @@ static void P_MinecartThink(player_t *player)
S_StartSound(minecart, minecart->info->activesound);
}
}
// Mark interpolation; the old positions need to be relative to the displacement from the minecart _after_ it's moved.
// This isn't quite correct (it captures the landing wobble) but it works well enough
if (detleft)
{
detleft->old_x = detleft->x - (minecart->old_x - minecart->old_x2);
detleft->old_y = detleft->y - (minecart->old_y - minecart->old_y2);
detleft->old_z = detleft->z - (minecart->old_z - minecart->old_z2);
}
if (detright)
{
detright->old_x = detright->x - (minecart->old_x - minecart->old_x2);
detright->old_y = detright->y - (minecart->old_y - minecart->old_y2);
detright->old_z = detright->z - (minecart->old_z - minecart->old_z2);
}
}
else
{

View file

@ -399,8 +399,8 @@ static void R_AddLine(seg_t *line)
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);
angle1 = R_PointToAngle64(line->v1->x, line->v1->y);
angle2 = R_PointToAngle64(line->v2->x, line->v2->y);
curline = line;
// Clip to view edges.
@ -620,8 +620,8 @@ static boolean R_CheckBBox(const fixed_t *bspcoord)
check = checkcoord[boxpos];
// 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;
angle1 = R_PointToAngle64(bspcoord[check[0]], bspcoord[check[1]]) - viewangle;
angle2 = R_PointToAngle64(bspcoord[check[2]], bspcoord[check[3]]) - viewangle;
if ((signed)angle1 < (signed)angle2)
{

View file

@ -587,7 +587,7 @@ typedef struct subsector_s
{
sector_t *sector;
INT16 numlines;
UINT16 firstline;
UINT32 firstline;
struct polyobj_s *polyList; // haleyjd 02/19/06: list of polyobjects
size_t validcount;
} subsector_t;

View file

@ -266,13 +266,13 @@ INT32 R_PointOnSide(fixed_t x, fixed_t y, node_t *node)
if (!node->dy)
return y <= node->y ? node->dx < 0 : node->dx > 0;
x -= node->x;
y -= node->y;
fixed_t dx = (x >> 1) - (node->x >> 1);
fixed_t dy = (y >> 1) - (node->y >> 1);
// Try to quickly decide by looking at sign bits.
if ((node->dy ^ node->dx ^ x ^ y) < 0)
return (node->dy ^ x) < 0; // (left is negative)
return FixedMul(y, node->dx>>FRACBITS) >= FixedMul(node->dy>>FRACBITS, x);
if ((node->dy ^ node->dx ^ dx ^ dy) < 0)
return (node->dy ^ dx) < 0; // (left is negative)
return FixedMul(dy, node->dx>>FRACBITS) >= FixedMul(node->dy>>FRACBITS, dx);
}
// killough 5/2/98: reformatted
@ -289,13 +289,13 @@ INT32 R_PointOnSegSide(fixed_t x, fixed_t y, seg_t *line)
if (!ldy)
return y <= ly ? ldx < 0 : ldx > 0;
x -= lx;
y -= ly;
fixed_t dx = (x >> 1) - (lx >> 1);
fixed_t dy = (y >> 1) - (ly >> 1);
// Try to quickly decide by looking at sign bits.
if ((ldy ^ ldx ^ x ^ y) < 0)
return (ldy ^ x) < 0; // (left is negative)
return FixedMul(y, ldx>>FRACBITS) >= FixedMul(ldy>>FRACBITS, x);
if ((ldy ^ ldx ^ dx ^ dy) < 0)
return (ldy ^ dx) < 0; // (left is negative)
return FixedMul(dy, ldx>>FRACBITS) >= FixedMul(ldy>>FRACBITS, dx);
}
//
@ -620,7 +620,7 @@ static struct {
0,
0,
{}, {},
{0}, {0},
false
};

View file

@ -447,7 +447,7 @@ void *Picture_FlatConvert(
for (y = 0; y < inheight; y++)
for (x = 0; x < inwidth; x++)
{
void *input;
void *input = NULL;
size_t offs = ((y * inwidth) + x);
// Read pixel

View file

@ -1785,7 +1785,11 @@ static void R_ProjectSprite(mobj_t *thing)
range++; // fencepost problem
scalestep = ((yscale2 - yscale)/range) ?: 1;
// Compatibility with MSVC - SSNTails
scalestep = ((yscale2 - yscale) / range);
if (!scalestep)
scalestep = 1;
xscale = FixedDiv(range<<FRACBITS, abs(offset2));
// The following two are alternate sorting methods which might be more applicable in some circumstances. TODO - maybe enable via MF2?
@ -1915,7 +1919,7 @@ static void R_ProjectSprite(mobj_t *thing)
if (shadoweffects)
{
mobj_t *caster = thing->target;
interpmobjstate_t casterinterp = {};
interpmobjstate_t casterinterp = { 0 }; // MSVC compatibility - SSNTails
if (R_UsingFrameInterpolation() && !paused)
{

View file

@ -401,7 +401,6 @@ void SCR_SetDefaultMode(void)
// remember the default screen size
CV_SetValue(&cv_scr_width, vid.width);
CV_SetValue(&cv_scr_height, vid.height);
CV_SetValue(&cv_scr_depth, vid.bpp*8);
}
// Change fullscreen on/off according to cv_fullscreen
@ -622,7 +621,13 @@ void SCR_ClosedCaptions(void)
y = basey-((i + 2)*10);
if (closedcaptions[i].b)
y -= (closedcaptions[i].b--)*vid.dupy;
{
y -= closedcaptions[i].b * vid.dupy;
if (renderisnewtic)
{
closedcaptions[i].b--;
}
}
if (closedcaptions[i].t < CAPTIONFADETICS)
flags |= (((CAPTIONFADETICS-closedcaptions[i].t)/2)*V_10TRANS);

View file

@ -2,7 +2,6 @@ i_net.c
i_system.c
i_main.c
i_video.c
i_gamepad.c
dosstr.c
endtxt.c
hwsym_sdl.c

View file

@ -39,46 +39,46 @@
<ProjectGuid>{61BA7D3C-F77D-4D31-B718-1177FE482CF2}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>Srb2SDL</RootNamespace>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>Srb2Win</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<UseDebugLibraries>true</UseDebugLibraries>
<WindowsSDKDesktopARMSupport>true</WindowsSDKDesktopARMSupport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<WindowsSDKDesktopARMSupport>true</WindowsSDKDesktopARMSupport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<UseDebugLibraries>true</UseDebugLibraries>
<WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>
@ -134,6 +134,9 @@
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<RunCodeAnalysis>false</RunCodeAnalysis>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<TargetName>$(ProjectName)_Debug</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@ -154,6 +157,26 @@
<AdditionalDependencies>setupapi.lib;winmm.lib;imm32.lib;version.lib;ole32.lib;advapi32.lib;shell32.lib;gdi32.lib;oleaut32.lib;uuid.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<LanguageStandard_C>Default</LanguageStandard_C>
<TreatWarningAsError>false</TreatWarningAsError>
<DisableSpecificWarnings>4244;4267;4146</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<DisableSpecificWarnings>4244;4267;4146;4003</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ProjectReference Include="..\..\libs\libpng-src\projects\visualc10\libpng.vcxproj">
<Project>{72b01aca-7a1a-4f7b-acef-2607299cf052}</Project>
@ -246,11 +269,13 @@
<ClInclude Include="..\i_system.h" />
<ClInclude Include="..\i_tcp.h" />
<ClInclude Include="..\i_threads.h" />
<ClInclude Include="..\i_time.h" />
<ClInclude Include="..\i_video.h" />
<ClInclude Include="..\keys.h" />
<ClInclude Include="..\libdivide.h" />
<ClInclude Include="..\lua_hook.h" />
<ClInclude Include="..\lua_hud.h" />
<ClInclude Include="..\lua_hudlib_drawlist.h" />
<ClInclude Include="..\lua_libs.h" />
<ClInclude Include="..\lua_script.h" />
<ClInclude Include="..\lzf.h" />
@ -264,6 +289,7 @@
<ClInclude Include="..\m_cheat.h" />
<ClInclude Include="..\m_cond.h" />
<ClInclude Include="..\m_dllist.h" />
<ClInclude Include="..\m_easing.h" />
<ClInclude Include="..\m_fixed.h" />
<ClInclude Include="..\m_menu.h" />
<ClInclude Include="..\m_misc.h" />
@ -272,6 +298,7 @@
<ClInclude Include="..\m_random.h" />
<ClInclude Include="..\m_swap.h" />
<ClInclude Include="..\p5prof.h" />
<ClInclude Include="..\p_haptic.h" />
<ClInclude Include="..\p_local.h" />
<ClInclude Include="..\p_maputl.h" />
<ClInclude Include="..\p_mobj.h" />
@ -286,6 +313,7 @@
<ClInclude Include="..\r_data.h" />
<ClInclude Include="..\r_defs.h" />
<ClInclude Include="..\r_draw.h" />
<ClInclude Include="..\r_fps.h" />
<ClInclude Include="..\r_local.h" />
<ClInclude Include="..\r_main.h" />
<ClInclude Include="..\r_patch.h" />
@ -403,11 +431,13 @@
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\i_tcp.c" />
<ClCompile Include="..\i_time.c" />
<ClCompile Include="..\lua_baselib.c" />
<ClCompile Include="..\lua_blockmaplib.c" />
<ClCompile Include="..\lua_consolelib.c" />
<ClCompile Include="..\lua_hooklib.c" />
<ClCompile Include="..\lua_hudlib.c" />
<ClCompile Include="..\lua_hudlib_drawlist.c" />
<ClCompile Include="..\lua_infolib.c" />
<ClCompile Include="..\lua_inputlib.c" />
<ClCompile Include="..\lua_maplib.c" />
@ -429,6 +459,7 @@
<ClCompile Include="..\m_bbox.c" />
<ClCompile Include="..\m_cheat.c" />
<ClCompile Include="..\m_cond.c" />
<ClCompile Include="..\m_easing.c" />
<ClCompile Include="..\m_fixed.c" />
<ClCompile Include="..\m_menu.c" />
<ClCompile Include="..\m_misc.c" />
@ -438,6 +469,7 @@
<ClCompile Include="..\p_ceilng.c" />
<ClCompile Include="..\p_enemy.c" />
<ClCompile Include="..\p_floor.c" />
<ClCompile Include="..\p_haptic.c" />
<ClCompile Include="..\p_inter.c" />
<ClCompile Include="..\p_lights.c" />
<ClCompile Include="..\p_map.c" />
@ -464,6 +496,7 @@
<ClCompile Include="..\r_draw8_npo2.c">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\r_fps.c" />
<ClCompile Include="..\r_main.c" />
<ClCompile Include="..\r_patch.c" />
<ClCompile Include="..\r_patchrotation.c" />
@ -478,7 +511,6 @@
<ClCompile Include="..\r_things.c" />
<ClCompile Include="..\screen.c" />
<ClCompile Include="..\sounds.c" />
<ClCompile Include="..\strcasestr.c" />
<ClCompile Include="..\string.c" />
<ClCompile Include="..\st_stuff.c" />
<ClCompile Include="..\s_sound.c" />
@ -507,7 +539,7 @@
<ClCompile Include="IMG_xpm.c">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="i_cdmus.c" />
<ClCompile Include="i_gamepad.c" />
<ClCompile Include="i_main.c" />
<ClCompile Include="i_net.c" />
<ClCompile Include="i_system.c" />
@ -524,4 +556,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View file

@ -144,7 +144,6 @@
<ClInclude Include="..\deh_tables.h">
<Filter>D_Doom</Filter>
</ClInclude>
<ClInclude Include="..\doomdata.h">
<Filter>D_Doom</Filter>
</ClInclude>
@ -511,6 +510,21 @@
<ClInclude Include="..\r_portal.h">
<Filter>R_Rend</Filter>
</ClInclude>
<ClInclude Include="..\lua_hudlib_drawlist.h">
<Filter>LUA</Filter>
</ClInclude>
<ClInclude Include="..\i_time.h">
<Filter>I_Interface</Filter>
</ClInclude>
<ClInclude Include="..\r_fps.h">
<Filter>R_Rend</Filter>
</ClInclude>
<ClInclude Include="..\p_haptic.h">
<Filter>P_Play</Filter>
</ClInclude>
<ClInclude Include="..\m_easing.h">
<Filter>M_Misc</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\tmap.nas">
@ -625,7 +639,6 @@
<ClCompile Include="..\deh_tables.c">
<Filter>D_Doom</Filter>
</ClCompile>
<ClCompile Include="..\d_clisrv.c">
<Filter>D_Doom</Filter>
</ClCompile>
@ -821,9 +834,6 @@
<ClCompile Include="..\string.c">
<Filter>M_Misc</Filter>
</ClCompile>
<ClCompile Include="..\strcasestr.c">
<Filter>M_Misc</Filter>
</ClCompile>
<ClCompile Include="..\comptime.c">
<Filter>O_Other</Filter>
</ClCompile>
@ -965,9 +975,6 @@
<ClCompile Include="hwsym_sdl.c">
<Filter>SDLApp</Filter>
</ClCompile>
<ClCompile Include="i_cdmus.c">
<Filter>SDLApp</Filter>
</ClCompile>
<ClCompile Include="i_main.c">
<Filter>SDLApp</Filter>
</ClCompile>
@ -1023,10 +1030,28 @@
<ClCompile Include="..\r_portal.c">
<Filter>R_Rend</Filter>
</ClCompile>
<ClCompile Include="..\lua_hudlib_drawlist.c">
<Filter>LUA</Filter>
</ClCompile>
<ClCompile Include="i_gamepad.c">
<Filter>SDLApp</Filter>
</ClCompile>
<ClCompile Include="..\i_time.c">
<Filter>I_Interface</Filter>
</ClCompile>
<ClCompile Include="..\r_fps.c">
<Filter>R_Rend</Filter>
</ClCompile>
<ClCompile Include="..\p_haptic.c">
<Filter>P_Play</Filter>
</ClCompile>
<ClCompile Include="..\m_easing.c">
<Filter>M_Misc</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Image Include="Srb2SDL.ico">
<Filter>SDLApp</Filter>
</Image>
</ItemGroup>
</Project>
</Project>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,74 +0,0 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "Srb2SDL"=.\Srb2SDL.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name libpng
End Project Dependency
Begin Project Dependency
Project_Dep_Name zlib
End Project Dependency
}}}
###############################################################################
Project: "libpng"="..\..\libs\libpng-src\projects\visualc6\libpng.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name zlib
End Project Dependency
}}}
###############################################################################
Project: "s_openal"=..\hardware\s_openal\s_openal.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "zlib"=..\..\libs\zlib\projects\visualc6\zlib.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

View file

@ -1,963 +0,0 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2022 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file i_gamepad.c
/// \brief Gamepads
#ifdef HAVE_SDL
#include "../i_gamepad.h"
#include "../i_system.h"
#include "../doomdef.h"
#include "../d_main.h"
#include "../d_netcmd.h"
#include "../g_game.h"
#include "../m_argv.h"
#include "../m_menu.h"
#include "../z_zone.h"
#include "SDL.h"
#include "SDL_joystick.h"
#include "sdlmain.h"
static void Controller_ChangeDevice(UINT8 num);
static void Controller_Close(UINT8 num);
static void Controller_StopRumble(UINT8 num);
static ControllerInfo controllers[NUM_GAMEPADS];
static boolean rumble_supported = false;
static boolean rumble_paused = false;
// This attempts to initialize the gamepad subsystems
static boolean InitGamepadSubsystems(void)
{
if (M_CheckParm("-noxinput"))
SDL_SetHintWithPriority(SDL_HINT_XINPUT_ENABLED, "0", SDL_HINT_OVERRIDE);
#if SDL_VERSION_ATLEAST(2,0,9)
if (M_CheckParm("-nohidapi"))
SDL_SetHintWithPriority(SDL_HINT_JOYSTICK_HIDAPI, "0", SDL_HINT_OVERRIDE);
#endif
if (SDL_WasInit(GAMEPAD_INIT_FLAGS) == 0)
{
if (SDL_InitSubSystem(GAMEPAD_INIT_FLAGS) == -1)
{
CONS_Printf(M_GetText("Couldn't initialize game controller subsystems: %s\n"), SDL_GetError());
return false;
}
}
return true;
}
void I_InitGamepads(void)
{
if (M_CheckParm("-nojoy"))
return;
CONS_Printf("I_InitGamepads()...\n");
if (!InitGamepadSubsystems())
return;
#if SDL_VERSION_ATLEAST(2,0,9)
rumble_supported = !M_CheckParm("-norumble");
#else
rumble_supported = false;
#endif
for (UINT8 i = 0; i < NUM_GAMEPADS; i++)
controllers[i].info = &gamepads[i];
for (UINT8 i = 0; i < NUM_GAMEPADS; i++)
Controller_ChangeDevice(i);
}
INT32 I_NumGamepads(void)
{
if (SDL_WasInit(GAMEPAD_INIT_FLAGS) == GAMEPAD_INIT_FLAGS)
return SDL_NumJoysticks();
else
return 0;
}
// From the SDL source code
#define USB_VENDOR_MICROSOFT 0x045e
#define USB_VENDOR_PDP 0x0e6f
#define USB_VENDOR_POWERA_ALT 0x20d6
#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_1 0x02e3
#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2 0x0b00
#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLUETOOTH 0x0b05
#define USB_PRODUCT_XBOX_SERIES_X 0x0b12
#define USB_PRODUCT_XBOX_SERIES_X_BLE 0x0b13
#define USB_PRODUCT_XBOX_SERIES_X_VICTRIX_GAMBIT 0x02d6
#define USB_PRODUCT_XBOX_SERIES_X_PDP_BLUE 0x02d9
#define USB_PRODUCT_XBOX_SERIES_X_PDP_AFTERGLOW 0x02da
#define USB_PRODUCT_XBOX_SERIES_X_POWERA_FUSION_PRO2 0x4001
#define USB_PRODUCT_XBOX_SERIES_X_POWERA_SPECTRA 0x4002
#if SDL_VERSION_ATLEAST(2,0,6)
static boolean IsJoystickXboxOneElite(Uint16 vendor_id, Uint16 product_id)
{
if (vendor_id == USB_VENDOR_MICROSOFT) {
if (product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_1 ||
product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2 ||
product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLUETOOTH) {
return true;
}
}
return false;
}
static boolean IsJoystickXboxSeriesXS(Uint16 vendor_id, Uint16 product_id)
{
if (vendor_id == USB_VENDOR_MICROSOFT) {
if (product_id == USB_PRODUCT_XBOX_SERIES_X ||
product_id == USB_PRODUCT_XBOX_SERIES_X_BLE) {
return true;
}
}
else if (vendor_id == USB_VENDOR_PDP) {
if (product_id == USB_PRODUCT_XBOX_SERIES_X_VICTRIX_GAMBIT ||
product_id == USB_PRODUCT_XBOX_SERIES_X_PDP_BLUE ||
product_id == USB_PRODUCT_XBOX_SERIES_X_PDP_AFTERGLOW) {
return true;
}
}
else if (vendor_id == USB_VENDOR_POWERA_ALT) {
if ((product_id >= 0x2001 && product_id <= 0x201a) ||
product_id == USB_PRODUCT_XBOX_SERIES_X_POWERA_FUSION_PRO2 ||
product_id == USB_PRODUCT_XBOX_SERIES_X_POWERA_SPECTRA) {
return true;
}
}
return false;
}
#endif
// Opens a controller device
static boolean Controller_OpenDevice(UINT8 which, INT32 devindex)
{
if (SDL_WasInit(GAMEPAD_INIT_FLAGS) == 0)
{
CONS_Debug(DBG_GAMELOGIC, M_GetText("Game controller subsystems not started\n"));
return false;
}
if (devindex <= 0)
return false;
if (SDL_NumJoysticks() == 0)
{
CONS_Debug(DBG_GAMELOGIC, M_GetText("Found no controllers on this system\n"));
return false;
}
devindex--;
if (!SDL_IsGameController(devindex))
{
CONS_Debug(DBG_GAMELOGIC, M_GetText("Device index %d isn't a game controller\n"), devindex);
return false;
}
ControllerInfo *controller = &controllers[which];
SDL_GameController *newdev = SDL_GameControllerOpen(devindex);
// Handle the edge case where the device <-> controller 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 (controller->dev)
{
if (controller->dev == newdev // same device, nothing to do
|| (newdev == NULL && SDL_GameControllerGetAttached(controller->dev))) // we failed, but already have a working device
return true;
// Else, we're changing devices, so close the controller
CONS_Debug(DBG_GAMELOGIC, M_GetText("Controller %d device is changing; closing controller...\n"), which);
Controller_Close(which);
}
if (newdev == NULL)
{
CONS_Debug(DBG_GAMELOGIC, M_GetText("Controller %d: Couldn't open device - %s\n"), which, SDL_GetError());
controller->started = false;
}
else
{
controller->dev = newdev;
controller->joydev = SDL_GameControllerGetJoystick(controller->dev);
controller->started = true;
CONS_Debug(DBG_GAMELOGIC, M_GetText("Controller %d: %s\n"), which, SDL_GameControllerName(controller->dev));
#if SDL_VERSION_ATLEAST(2,0,12)
#define GAMEPAD_TYPE_CASE(ctrl) \
case SDL_CONTROLLER_TYPE_##ctrl: \
controller->info->type = GAMEPAD_TYPE_##ctrl; \
break
switch (SDL_GameControllerGetType(newdev))
{
GAMEPAD_TYPE_CASE(UNKNOWN);
GAMEPAD_TYPE_CASE(XBOX360);
GAMEPAD_TYPE_CASE(XBOXONE);
GAMEPAD_TYPE_CASE(PS3);
GAMEPAD_TYPE_CASE(PS4);
#if SDL_VERSION_ATLEAST(2,0,14)
GAMEPAD_TYPE_CASE(PS5);
#endif
GAMEPAD_TYPE_CASE(NINTENDO_SWITCH_PRO);
#if SDL_VERSION_ATLEAST(2,0,16)
GAMEPAD_TYPE_CASE(GOOGLE_STADIA);
GAMEPAD_TYPE_CASE(AMAZON_LUNA);
#endif
GAMEPAD_TYPE_CASE(VIRTUAL);
default: break;
}
#undef GAMEPAD_BUTTON_CASE
#else
// Under older versions of SDL, we aren't provided controller type information.
controller->info->type = GAMEPAD_TYPE_UNKNOWN;
#endif // SDL_VERSION_ATLEAST(2,0,12)
#if SDL_VERSION_ATLEAST(2,0,6)
// Check the device vendor and product to find out what controller this actually is
Uint16 vendor = SDL_JoystickGetDeviceVendor(devindex);
Uint16 product = SDL_JoystickGetDeviceProduct(devindex);
if (IsJoystickXboxSeriesXS(vendor, product))
controller->info->type = GAMEPAD_TYPE_XBOX_SERIES_XS;
else if (IsJoystickXboxOneElite(vendor, product))
controller->info->type = GAMEPAD_TYPE_XBOX_ELITE;
#endif
CONS_Debug(DBG_GAMELOGIC, M_GetText(" Type: %s\n"), G_GamepadTypeToString(controller->info->type));
#if SDL_VERSION_ATLEAST(2,0,12)
// Change the ring LEDs on Xbox 360 controllers
// FIXME: Doesn't seem to work?
SDL_GameControllerSetPlayerIndex(controller->dev, which);
#endif
#if SDL_VERSION_ATLEAST(2,0,18)
// Check if rumble is supported
if (SDL_GameControllerHasRumble(controller->dev) == SDL_TRUE)
{
controller->info->rumble.supported = true;
CONS_Debug(DBG_GAMELOGIC, M_GetText(" Rumble supported: Yes\n"));
}
else
{
controller->info->rumble.supported = false;
CONS_Debug(DBG_GAMELOGIC, M_GetText(" Rumble supported: No\n"));
}
#else
controller->info->rumble.supported = true;
CONS_Debug(DBG_GAMELOGIC, M_GetText(" Rumble supported: Maybe\n"));
#endif // SDL_VERSION_ATLEAST(2,0,18)
if (!controller->info->connected)
{
controller->info->connected = true;
G_OnGamepadConnect(which);
}
}
return controller->started;
}
// Initializes a controller
static INT32 Controller_Init(SDL_GameController **newcontroller, UINT8 which, INT32 *index)
{
ControllerInfo *info = &controllers[which];
SDL_GameController *controller = NULL;
INT32 device = (*index);
if (device && SDL_IsGameController(device - 1))
controller = SDL_GameControllerOpen(device - 1);
if (newcontroller)
(*newcontroller) = controller;
if (controller && info->dev == controller) // don't override an active device
(*index) = I_GetControllerIndex(info->dev) + 1;
else if (controller && Controller_OpenDevice(which, device))
{
// SDL's device indexes are unstable, so cv_usegamepad may not match
// the actual device index. So let's cheat a bit and find the device's current index.
info->lastindex = I_GetControllerIndex(info->dev) + 1;
return 1;
}
else
{
(*index) = 0;
return 0;
}
return -1;
}
// Changes a controller's device
static void Controller_ChangeDevice(UINT8 num)
{
SDL_GameController *newjoy = NULL;
if (!Controller_Init(&newjoy, num, &cv_usegamepad[num].value) && controllers[num].lastindex)
Controller_Close(num);
I_CloseInactiveController(newjoy);
}
static boolean Controller_IsAnyUsingDevice(SDL_GameController *dev)
{
for (UINT8 i = 0; i < NUM_GAMEPADS; i++)
{
if (controllers[i].dev == dev)
return true;
}
return false;
}
static boolean Controller_IsAnyOtherUsingDevice(SDL_GameController *dev, UINT8 thisjoy)
{
for (UINT8 i = 0; i < NUM_GAMEPADS; i++)
{
if (i == thisjoy)
continue;
else if (controllers[i].dev == dev)
return true;
}
return false;
}
void I_ControllerDeviceAdded(INT32 which)
{
if (!SDL_IsGameController(which))
return;
SDL_GameController *newjoy = SDL_GameControllerOpen(which);
CONS_Debug(DBG_GAMELOGIC, "Gamepad device index %d added\n", which + 1);
// Because SDL's device index is unstable, we're going to cheat here a bit:
// For the first controller setting that is NOT active:
// 1. Set cv_usegamepadX.value to the new device index (this does not change what is written to config.cfg)
// 2. Set OTHERS' cv_usegamepadX.value to THEIR new device index, because it likely changed
// * If device doesn't exist, switch cv_usegamepad back to default value (.string)
// * BUT: If that default index is being occupied, use ANOTHER cv_usegamepad's default value!
for (UINT8 this = 0; this < NUM_GAMEPADS && newjoy; this++)
{
if ((!controllers[this].dev || !SDL_GameControllerGetAttached(controllers[this].dev))
&& !Controller_IsAnyOtherUsingDevice(newjoy, this)) // don't override a currently active device
{
cv_usegamepad[this].value = which + 1;
// Go through every other device
for (UINT8 other = 0; other < NUM_GAMEPADS; other++)
{
if (other == this)
{
// Don't change this controller's index
continue;
}
else if (controllers[other].dev)
{
// Update this controller's index if the device is open
cv_usegamepad[other].value = I_GetControllerIndex(controllers[other].dev) + 1;
}
else if (atoi(cv_usegamepad[other].string) != controllers[this].lastindex
&& atoi(cv_usegamepad[other].string) != cv_usegamepad[this].value)
{
// If the user-set index for the other controller doesn't
// match this controller's current or former internal index,
// then use the other controller's internal index
cv_usegamepad[other].value = atoi(cv_usegamepad[other].string);
}
else if (atoi(cv_usegamepad[this].string) != controllers[this].lastindex
&& atoi(cv_usegamepad[this].string) != cv_usegamepad[this].value)
{
// If the user-set index for this controller doesn't match
// its current or former internal index, then use this
// controller's internal index
cv_usegamepad[other].value = atoi(cv_usegamepad[this].string);
}
else
{
// Try again
cv_usegamepad[other].value = 0;
continue;
}
break;
}
break;
}
}
// Was cv_usegamepad disabled in settings?
for (UINT8 i = 0; i < NUM_GAMEPADS; i++)
{
if (!strcmp(cv_usegamepad[i].string, "0") || !cv_usegamepad[i].value)
cv_usegamepad[i].value = 0;
else if (atoi(cv_usegamepad[i].string) <= I_NumGamepads() // don't mess if we intentionally set higher than NumJoys
&& cv_usegamepad[i].value) // update the cvar ONLY if a device exists
CV_SetValue(&cv_usegamepad[i], cv_usegamepad[i].value);
}
// Update all gamepads' init states
// This is a little wasteful since cv_usegamepad 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.
for (UINT8 i = 0; i < NUM_GAMEPADS; i++)
{
Controller_ChangeDevice(i);
CONS_Debug(DBG_GAMELOGIC, "Controller %d device index: %d\n", i, controllers[i].lastindex);
}
if (M_OnGamepadMenu())
M_UpdateGamepadMenu();
I_CloseInactiveController(newjoy);
}
void I_ControllerDeviceRemoved(void)
{
for (UINT8 this = 0; this < NUM_GAMEPADS; this++)
{
if (controllers[this].dev && !SDL_GameControllerGetAttached(controllers[this].dev))
{
CONS_Debug(DBG_GAMELOGIC, "Controller %d removed, device index: %d\n", this, controllers[this].lastindex);
G_OnGamepadDisconnect(this);
Controller_Close(this);
}
// Update the device indexes, because they likely changed
// * If device doesn't exist, switch cv_usegamepad back to default value (.string)
// * BUT: If that default index is being occupied, use ANOTHER cv_usegamepad's default value!
if (controllers[this].dev)
cv_usegamepad[this].value = controllers[this].lastindex = I_GetControllerIndex(controllers[this].dev) + 1;
else
{
for (UINT8 other = 0; other < NUM_GAMEPADS; other++)
{
if (other == this)
continue;
if (atoi(cv_usegamepad[this].string) != controllers[other].lastindex)
{
// Update this internal index if this user-set index
// doesn't match the other's former internal index
cv_usegamepad[this].value = atoi(cv_usegamepad[this].string);
}
else if (atoi(cv_usegamepad[other].string) != controllers[other].lastindex)
{
// Otherwise, set this internal index to the other's
// user-set index, if the other user-set index is not the
// same as the other's former internal index
cv_usegamepad[this].value = atoi(cv_usegamepad[other].string);
}
else
{
// Try again
cv_usegamepad[this].value = 0;
continue;
}
break;
}
}
// Was cv_usegamepad disabled in settings?
if (!strcmp(cv_usegamepad[this].string, "0"))
cv_usegamepad[this].value = 0;
else if (atoi(cv_usegamepad[this].string) <= I_NumGamepads() // don't mess if we intentionally set higher than NumJoys
&& cv_usegamepad[this].value) // update the cvar ONLY if a device exists
CV_SetValue(&cv_usegamepad[this], cv_usegamepad[this].value);
CONS_Debug(DBG_GAMELOGIC, "Controller %d device index: %d\n", this, controllers[this].lastindex);
}
if (M_OnGamepadMenu())
M_UpdateGamepadMenu();
}
// Close the controller device if there isn't any controller using it
void I_CloseInactiveController(SDL_GameController *dev)
{
if (!Controller_IsAnyUsingDevice(dev))
SDL_GameControllerClose(dev);
}
// Cheat to get the device index for a game controller handle
INT32 I_GetControllerIndex(SDL_GameController *dev)
{
INT32 i, count = SDL_NumJoysticks();
for (i = 0; dev && i < count; i++)
{
SDL_GameController *test = SDL_GameControllerOpen(i);
if (test && test == dev)
return i;
else
I_CloseInactiveController(test);
}
return -1;
}
// Changes a gamepad's device
void I_ChangeGamepad(UINT8 which)
{
if (which >= NUM_GAMEPADS)
return;
if (controllers[which].started)
Controller_StopRumble(which);
Controller_ChangeDevice(which);
}
// Returns the name of a controller from its index
const char *I_GetGamepadName(INT32 joyindex)
{
static char joyname[256];
joyname[0] = '\0';
if (SDL_WasInit(GAMEPAD_INIT_FLAGS) == GAMEPAD_INIT_FLAGS)
{
const char *tempname = SDL_GameControllerNameForIndex(joyindex - 1);
if (tempname)
strlcpy(joyname, tempname, sizeof joyname);
}
return joyname;
}
// Toggles a gamepad's digital axis setting
void I_SetGamepadDigital(UINT8 which, boolean enable)
{
if (which >= NUM_GAMEPADS)
return;
gamepads[which].digital = enable;
}
static gamepad_t *Controller_GetFromID(SDL_JoystickID which, UINT8 *found)
{
// Determine the joystick IDs for each current open controller
for (UINT8 i = 0; i < NUM_GAMEPADS; i++)
{
if (which == SDL_JoystickInstanceID(controllers[i].joydev))
{
(*found) = i;
return &gamepads[i];
}
}
(*found) = UINT8_MAX;
return NULL;
}
void I_HandleControllerButtonEvent(SDL_ControllerButtonEvent evt, Uint32 type)
{
event_t event;
gamepad_t *gamepad = Controller_GetFromID(evt.which, &event.which);
if (gamepad == NULL)
return;
if (type == SDL_CONTROLLERBUTTONUP)
event.type = ev_gamepad_up;
else if (type == SDL_CONTROLLERBUTTONDOWN)
event.type = ev_gamepad_down;
else
return;
#define GAMEPAD_BUTTON_CASE(btn) \
case SDL_CONTROLLER_BUTTON_##btn: \
event.key = GAMEPAD_BUTTON_##btn; \
break
switch (evt.button)
{
GAMEPAD_BUTTON_CASE(A);
GAMEPAD_BUTTON_CASE(B);
GAMEPAD_BUTTON_CASE(X);
GAMEPAD_BUTTON_CASE(Y);
GAMEPAD_BUTTON_CASE(BACK);
GAMEPAD_BUTTON_CASE(GUIDE);
GAMEPAD_BUTTON_CASE(START);
GAMEPAD_BUTTON_CASE(LEFTSTICK);
GAMEPAD_BUTTON_CASE(RIGHTSTICK);
GAMEPAD_BUTTON_CASE(LEFTSHOULDER);
GAMEPAD_BUTTON_CASE(RIGHTSHOULDER);
GAMEPAD_BUTTON_CASE(DPAD_UP);
GAMEPAD_BUTTON_CASE(DPAD_DOWN);
GAMEPAD_BUTTON_CASE(DPAD_LEFT);
GAMEPAD_BUTTON_CASE(DPAD_RIGHT);
#if SDL_VERSION_ATLEAST(2,0,14)
GAMEPAD_BUTTON_CASE(MISC1);
GAMEPAD_BUTTON_CASE(PADDLE1);
GAMEPAD_BUTTON_CASE(PADDLE2);
GAMEPAD_BUTTON_CASE(PADDLE3);
GAMEPAD_BUTTON_CASE(PADDLE4);
GAMEPAD_BUTTON_CASE(TOUCHPAD);
#endif
default: return;
}
#undef GAMEPAD_BUTTON_CASE
D_PostEvent(&event);
}
void I_HandleControllerAxisEvent(SDL_ControllerAxisEvent evt)
{
event_t event;
gamepad_t *gamepad = Controller_GetFromID(evt.which, &event.which);
if (gamepad == NULL)
return;
#define GAMEPAD_AXIS_CASE(btn) \
case SDL_CONTROLLER_AXIS_##btn: \
event.key = GAMEPAD_AXIS_##btn; \
break
switch (evt.axis)
{
GAMEPAD_AXIS_CASE(LEFTX);
GAMEPAD_AXIS_CASE(LEFTY);
GAMEPAD_AXIS_CASE(RIGHTX);
GAMEPAD_AXIS_CASE(RIGHTY);
GAMEPAD_AXIS_CASE(TRIGGERLEFT);
GAMEPAD_AXIS_CASE(TRIGGERRIGHT);
default: return;
}
#undef GAMEPAD_AXIS_CASE
event.type = ev_gamepad_axis;
event.x = evt.value;
D_PostEvent(&event);
}
static void Controller_StopRumble(UINT8 num)
{
ControllerInfo *controller = &controllers[num];
controller->rumble.large_magnitude = 0;
controller->rumble.small_magnitude = 0;
controller->rumble.time_left = 0;
controller->rumble.expiration = 0;
gamepad_t *gamepad = controller->info;
gamepad->rumble.active = false;
gamepad->rumble.paused = false;
gamepad->rumble.data.large_magnitude = 0;
gamepad->rumble.data.small_magnitude = 0;
gamepad->rumble.data.duration = 0;
#if SDL_VERSION_ATLEAST(2,0,9)
if (gamepad->rumble.supported)
SDL_GameControllerRumble(controller->dev, 0, 0, 0);
#endif
}
static void Controller_Close(UINT8 num)
{
ControllerInfo *controller = &controllers[num];
// Close the game controller device
if (controller->dev)
{
Controller_StopRumble(num);
SDL_GameControllerClose(controller->dev);
}
controller->dev = NULL;
controller->joydev = NULL;
controller->lastindex = -1;
controller->started = false;
// Reset gamepad info
gamepad_t *gamepad = controller->info;
if (gamepad)
{
gamepad->type = GAMEPAD_TYPE_UNKNOWN;
gamepad->connected = false;
gamepad->digital = false;
gamepad->rumble.supported = false;
for (UINT8 i = 0; i < NUM_GAMEPAD_BUTTONS; i++)
gamepad->buttons[i] = 0;
for (UINT8 i = 0; i < NUM_GAMEPAD_AXES; i++)
gamepad->axes[i] = 0;
}
}
void I_ShutdownGamepads(void)
{
for (UINT8 i = 0; i < NUM_GAMEPADS; i++)
Controller_Close(i);
}
boolean I_RumbleSupported(void)
{
return rumble_supported;
}
static boolean Controller_Rumble(ControllerInfo *c)
{
#if SDL_VERSION_ATLEAST(2,0,9)
if (SDL_GameControllerRumble(c->dev, c->rumble.large_magnitude, c->rumble.small_magnitude, 0) == -1)
return false;
return true;
#else
(void)c;
return false;
#endif
}
void I_ToggleControllerRumble(boolean unpause)
{
#if SDL_VERSION_ATLEAST(2,0,9)
if (!I_RumbleSupported() || rumble_paused == !unpause)
return;
rumble_paused = !unpause;
for (UINT8 i = 0; i < NUM_GAMEPADS; i++)
{
ControllerInfo *controller = &controllers[i];
if (!controller->started || !controller->info->rumble.supported)
continue;
if (rumble_paused)
SDL_GameControllerRumble(controller->dev, 0, 0, 0);
else if (!controller->info->rumble.paused)
{
if (!Controller_Rumble(controller))
controller->rumble.expiration = controller->rumble.time_left = 0;
}
}
#else
(void)unpause;
return;
#endif
}
void I_UpdateControllers(void)
{
if (SDL_WasInit(GAMEPAD_INIT_FLAGS) != GAMEPAD_INIT_FLAGS)
return;
for (UINT8 i = 0; i < NUM_GAMEPADS; i++)
{
ControllerInfo *controller = &controllers[i];
if (!controller->started || !controller->info->rumble.supported || controller->info->rumble.paused)
continue;
if (controller->rumble.expiration &&
SDL_TICKS_PASSED(SDL_GetTicks(), controller->rumble.expiration))
{
// Enough time has passed, so stop the effect
Controller_StopRumble(i);
}
}
SDL_JoystickUpdate();
}
// Converts duration in tics to milliseconds
#define TICS_TO_MS(tics) ((INT32)(tics * (1000.0f/TICRATE)))
boolean I_RumbleGamepad(UINT8 which, const haptic_t *effect)
{
if (!I_RumbleSupported() || which >= NUM_GAMEPADS)
return false;
ControllerInfo *controller = &controllers[which];
if (!controller->started || !controller->info->rumble.supported)
return false;
UINT16 duration = min(TICS_TO_MS(effect->duration), UINT16_MAX);
UINT16 large_magnitude = max(0, min(effect->large_magnitude, UINT16_MAX));
UINT16 small_magnitude = max(0, min(effect->small_magnitude, UINT16_MAX));
CONS_Debug(DBG_GAMELOGIC, "Starting rumble effect for controller %d:\n", which);
CONS_Debug(DBG_GAMELOGIC, " Large motor magnitude: %f\n", large_magnitude / 65535.0f);
CONS_Debug(DBG_GAMELOGIC, " Small motor magnitude: %f\n", small_magnitude / 65535.0f);
if (!duration)
CONS_Debug(DBG_GAMELOGIC, " Duration: forever\n");
else
CONS_Debug(DBG_GAMELOGIC, " Duration: %dms\n", duration);
controller->rumble.large_magnitude = large_magnitude;
controller->rumble.small_magnitude = small_magnitude;
if (!rumble_paused && !Controller_Rumble(controller))
{
Controller_StopRumble(which);
return false;
}
controller->rumble.time_left = 0;
if (duration)
controller->rumble.expiration = SDL_GetTicks() + duration;
else
controller->rumble.expiration = 0;
// Update gamepad rumble info
gamepad_t *gamepad = controller->info;
gamepad->rumble.active = true;
gamepad->rumble.paused = false;
gamepad->rumble.data.large_magnitude = effect->large_magnitude;
gamepad->rumble.data.small_magnitude = effect->small_magnitude;
gamepad->rumble.data.duration = effect->duration;
return true;
}
#undef TICS_TO_MS
#define SET_MOTOR_FREQ(type) \
if (!I_RumbleSupported() || which >= NUM_GAMEPADS) \
return false; \
\
ControllerInfo *controller = &controllers[which]; \
if (!controller->started || !controller->info->rumble.supported) \
return false; \
\
gamepad_t *gamepad = controller->info; \
if (gamepad->rumble.data.type##_magnitude == freq) \
return true; \
\
UINT16 frequency = max(0, min(freq, UINT16_MAX)); \
\
controller->rumble.type##_magnitude = frequency; \
\
if (!rumble_paused && !gamepad->rumble.paused && !Controller_Rumble(controller)) \
{ \
Controller_StopRumble(which); \
return false; \
} \
\
gamepad->rumble.data.type##_magnitude = freq; \
gamepad->rumble.active = true; \
return true
boolean I_SetGamepadLargeMotorFreq(UINT8 which, fixed_t freq)
{
SET_MOTOR_FREQ(large);
}
boolean I_SetGamepadSmallMotorFreq(UINT8 which, fixed_t freq)
{
SET_MOTOR_FREQ(small);
}
void I_SetGamepadRumblePaused(UINT8 which, boolean pause)
{
#if SDL_VERSION_ATLEAST(2,0,9)
if (!I_RumbleSupported() || which >= NUM_GAMEPADS)
return;
ControllerInfo *controller = &controllers[which];
if (!controller->started || !controller->info->rumble.supported)
return;
if (pause == controller->info->rumble.paused)
return;
else if (pause)
{
if (!rumble_paused)
SDL_GameControllerRumble(controller->dev, 0, 0, 0);
if (controller->rumble.expiration)
{
controller->rumble.time_left = controller->rumble.expiration - SDL_GetTicks();
controller->rumble.expiration = 0;
}
}
else
{
if (!rumble_paused)
SDL_GameControllerRumble(controller->dev, controller->rumble.large_magnitude, controller->rumble.small_magnitude, 0);
if (controller->rumble.time_left)
controller->rumble.expiration = SDL_GetTicks() + controller->rumble.time_left;
}
controller->info->rumble.paused = pause;
#else
(void)which;
(void)pause;
return;
#endif
}
boolean I_GetGamepadRumbleSupported(UINT8 which)
{
if (!I_RumbleSupported() || which >= NUM_GAMEPADS)
return false;
ControllerInfo *controller = &controllers[which];
if (!controller->started)
return false;
return controller->info->rumble.supported;
}
boolean I_GetGamepadRumblePaused(UINT8 which)
{
if (!I_RumbleSupported() || which >= NUM_GAMEPADS)
return false;
ControllerInfo *controller = &controllers[which];
if (!controller->started || !controller->info->rumble.supported)
return false;
return controller->info->rumble.paused;
}
void I_StopGamepadRumble(UINT8 which)
{
if (!I_RumbleSupported() || which >= NUM_GAMEPADS)
return;
ControllerInfo *controller = &controllers[which];
if (!controller->started || !controller->info->rumble.supported)
return;
Controller_StopRumble(which);
}
#endif

View file

@ -185,7 +185,6 @@ static char returnWadPath[256];
#include "../i_video.h"
#include "../i_sound.h"
#include "../i_system.h"
#include "../i_gamepad.h"
#include "../i_threads.h"
#include "../screen.h" //vid.WndParent
#include "../d_net.h"
@ -194,6 +193,8 @@ static char returnWadPath[256];
#include "endtxt.h"
#include "sdlmain.h"
#include "../i_joy.h"
#include "../m_argv.h"
#include "../r_main.h" // Frame interpolation/uncapped
@ -211,6 +212,41 @@ static char returnWadPath[256];
#include "../byteptr.h"
#endif
/** \brief The JoyReset function
\param JoySet Joystick info to reset
\return void
*/
static void JoyReset(SDLJoyInfo_t *JoySet)
{
if (JoySet->dev)
{
SDL_JoystickClose(JoySet->dev);
}
JoySet->dev = NULL;
JoySet->oldjoy = -1;
JoySet->axises = JoySet->buttons = JoySet->hats = JoySet->balls = 0;
//JoySet->scale
}
/** \brief First joystick up and running
*/
static INT32 joystick_started = 0;
/** \brief SDL info about joystick 1
*/
SDLJoyInfo_t JoyInfo;
/** \brief Second joystick up and running
*/
static INT32 joystick2_started = 0;
/** \brief SDL inof about joystick 2
*/
SDLJoyInfo_t JoyInfo2;
#ifdef HAVE_TERMIOS
static INT32 fdmouse2 = -1;
static INT32 mouse2_started = 0;
@ -903,17 +939,721 @@ INT32 I_GetKey (void)
return rc;
}
//
// I_JoyScale
//
void I_JoyScale(void)
{
Joystick.bGamepadStyle = cv_joyscale.value==0;
JoyInfo.scale = Joystick.bGamepadStyle?1:cv_joyscale.value;
}
void I_JoyScale2(void)
{
Joystick2.bGamepadStyle = cv_joyscale2.value==0;
JoyInfo2.scale = Joystick2.bGamepadStyle?1:cv_joyscale2.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)
SDL_JoystickClose(test);
}
return -1;
}
/** \brief Joystick 1 buttons states
*/
static UINT64 lastjoybuttons = 0;
/** \brief Joystick 1 hats state
*/
static UINT64 lastjoyhats = 0;
/** \brief Shuts down joystick 1
\return void
*/
void I_ShutdownJoystick(void)
{
INT32 i;
event_t event;
event.type=ev_keyup;
event.x = 0;
event.y = 0;
lastjoybuttons = lastjoyhats = 0;
// emulate the up of all joystick buttons
for (i=0;i<JOYBUTTONS;i++)
{
event.key=KEY_JOY1+i;
D_PostEvent(&event);
}
// emulate the up of all joystick hats
for (i=0;i<JOYHATS*4;i++)
{
event.key=KEY_HAT1+i;
D_PostEvent(&event);
}
// reset joystick position
event.type = ev_joystick;
for (i=0;i<JOYAXISSET; i++)
{
event.key = i;
D_PostEvent(&event);
}
joystick_started = 0;
JoyReset(&JoyInfo);
// don't shut down the subsystem here, because hotplugging
}
void I_GetJoystickEvents(void)
{
static event_t event = {0,0,0,0,false};
INT32 i = 0;
UINT64 joyhats = 0;
#if 0
UINT64 joybuttons = 0;
Sint16 axisx, axisy;
#endif
if (!joystick_started) return;
if (!JoyInfo.dev) //I_ShutdownJoystick();
return;
#if 0
//faB: look for as much buttons as g_input code supports,
// we don't use the others
for (i = JoyInfo.buttons - 1; i >= 0; i--)
{
joybuttons <<= 1;
if (SDL_JoystickGetButton(JoyInfo.dev,i))
joybuttons |= 1;
}
if (joybuttons != lastjoybuttons)
{
INT64 j = 1; // keep only bits that changed since last time
INT64 newbuttons = joybuttons ^ lastjoybuttons;
lastjoybuttons = joybuttons;
for (i = 0; i < JOYBUTTONS; i++, j <<= 1)
{
if (newbuttons & j) // button changed state?
{
if (joybuttons & j)
event.type = ev_keydown;
else
event.type = ev_keyup;
event.key = KEY_JOY1 + i;
D_PostEvent(&event);
}
}
}
#endif
for (i = JoyInfo.hats - 1; i >= 0; i--)
{
Uint8 hat = SDL_JoystickGetHat(JoyInfo.dev, i);
if (hat & SDL_HAT_UP ) joyhats|=(UINT64)0x1<<(0 + 4*i);
if (hat & SDL_HAT_DOWN ) joyhats|=(UINT64)0x1<<(1 + 4*i);
if (hat & SDL_HAT_LEFT ) joyhats|=(UINT64)0x1<<(2 + 4*i);
if (hat & SDL_HAT_RIGHT) joyhats|=(UINT64)0x1<<(3 + 4*i);
}
if (joyhats != lastjoyhats)
{
INT64 j = 1; // keep only bits that changed since last time
INT64 newhats = joyhats ^ lastjoyhats;
lastjoyhats = joyhats;
for (i = 0; i < JOYHATS*4; i++, j <<= 1)
{
if (newhats & j) // hat changed state?
{
if (joyhats & j)
event.type = ev_keydown;
else
event.type = ev_keyup;
event.key = KEY_HAT1 + i;
D_PostEvent(&event);
}
}
}
#if 0
// send joystick axis positions
event.type = ev_joystick;
for (i = JOYAXISSET - 1; i >= 0; i--)
{
event.key = i;
if (i*2 + 1 <= JoyInfo.axises)
axisx = SDL_JoystickGetAxis(JoyInfo.dev, i*2 + 0);
else axisx = 0;
if (i*2 + 2 <= JoyInfo.axises)
axisy = SDL_JoystickGetAxis(JoyInfo.dev, i*2 + 1);
else axisy = 0;
// -32768 to 32767
axisx = axisx/32;
axisy = axisy/32;
if (Joystick.bGamepadStyle)
{
// gamepad control type, on or off, live or die
if (axisx < -(JOYAXISRANGE/2))
event.x = -1;
else if (axisx > (JOYAXISRANGE/2))
event.x = 1;
else event.x = 0;
if (axisy < -(JOYAXISRANGE/2))
event.y = -1;
else if (axisy > (JOYAXISRANGE/2))
event.y = 1;
else event.y = 0;
}
else
{
axisx = JoyInfo.scale?((axisx/JoyInfo.scale)*JoyInfo.scale):axisx;
axisy = JoyInfo.scale?((axisy/JoyInfo.scale)*JoyInfo.scale):axisy;
#ifdef SDL_JDEADZONE
if (-SDL_JDEADZONE <= axisx && axisx <= SDL_JDEADZONE) axisx = 0;
if (-SDL_JDEADZONE <= axisy && axisy <= SDL_JDEADZONE) axisy = 0;
#endif
// analog control style , just send the raw data
event.x = axisx; // x axis
event.y = axisy; // y axis
}
D_PostEvent(&event);
}
#endif
}
/** \brief Open joystick handle
\param fname name of joystick
\return axises
*/
static int joy_open(int joyindex)
{
SDL_Joystick *newdev = NULL;
int num_joy = 0;
if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
{
CONS_Printf(M_GetText("Joystick subsystem not started\n"));
return -1;
}
if (joyindex <= 0)
return -1;
num_joy = SDL_NumJoysticks();
if (num_joy == 0)
{
CONS_Printf("%s", M_GetText("Found no joysticks on this system\n"));
return -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_Debug(DBG_GAMELOGIC, M_GetText("Joystick1: Couldn't open device - %s\n"), SDL_GetError());
return -1;
}
else
{
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)
{
I_OutputMsg("Not enought axes?\n");
return 0;
}*/
JoyInfo.buttons = SDL_JoystickNumButtons(JoyInfo.dev);
if (JoyInfo.buttons > JOYBUTTONS)
JoyInfo.buttons = JOYBUTTONS;
JoyInfo.hats = SDL_JoystickNumHats(JoyInfo.dev);
if (JoyInfo.hats > JOYHATS)
JoyInfo.hats = JOYHATS;
JoyInfo.balls = SDL_JoystickNumBalls(JoyInfo.dev);
//Joystick.bGamepadStyle = !stricmp(SDL_JoystickName(JoyInfo.dev), "pad");
return JoyInfo.axises;
}
}
//Joystick2
/** \brief Joystick 2 buttons states
*/
static UINT64 lastjoy2buttons = 0;
/** \brief Joystick 2 hats state
*/
static UINT64 lastjoy2hats = 0;
/** \brief Shuts down joystick 2
\return void
*/
void I_ShutdownJoystick2(void)
{
INT32 i;
event_t event;
event.type = ev_keyup;
event.x = 0;
event.y = 0;
lastjoy2buttons = lastjoy2hats = 0;
// emulate the up of all joystick buttons
for (i = 0; i < JOYBUTTONS; i++)
{
event.key = KEY_2JOY1 + i;
D_PostEvent(&event);
}
// emulate the up of all joystick hats
for (i = 0; i < JOYHATS*4; i++)
{
event.key = KEY_2HAT1 + i;
D_PostEvent(&event);
}
// reset joystick position
event.type = ev_joystick2;
for (i = 0; i < JOYAXISSET; i++)
{
event.key = i;
D_PostEvent(&event);
}
joystick2_started = 0;
JoyReset(&JoyInfo2);
// don't shut down the subsystem here, because hotplugging
}
void I_GetJoystick2Events(void)
{
static event_t event = {0,0,0,0,false};
INT32 i = 0;
UINT64 joyhats = 0;
#if 0
INT64 joybuttons = 0;
INT32 axisx, axisy;
#endif
if (!joystick2_started)
return;
if (!JoyInfo2.dev) //I_ShutdownJoystick2();
return;
#if 0
//faB: look for as much buttons as g_input code supports,
// we don't use the others
for (i = JoyInfo2.buttons - 1; i >= 0; i--)
{
joybuttons <<= 1;
if (SDL_JoystickGetButton(JoyInfo2.dev,i))
joybuttons |= 1;
}
if (joybuttons != lastjoy2buttons)
{
INT64 j = 1; // keep only bits that changed since last time
INT64 newbuttons = joybuttons ^ lastjoy2buttons;
lastjoy2buttons = joybuttons;
for (i = 0; i < JOYBUTTONS; i++, j <<= 1)
{
if (newbuttons & j) // button changed state?
{
if (joybuttons & j)
event.type = ev_keydown;
else
event.type = ev_keyup;
event.key = KEY_2JOY1 + i;
D_PostEvent(&event);
}
}
}
#endif
for (i = JoyInfo2.hats - 1; i >= 0; i--)
{
Uint8 hat = SDL_JoystickGetHat(JoyInfo2.dev, i);
if (hat & SDL_HAT_UP ) joyhats|=(UINT64)0x1<<(0 + 4*i);
if (hat & SDL_HAT_DOWN ) joyhats|=(UINT64)0x1<<(1 + 4*i);
if (hat & SDL_HAT_LEFT ) joyhats|=(UINT64)0x1<<(2 + 4*i);
if (hat & SDL_HAT_RIGHT) joyhats|=(UINT64)0x1<<(3 + 4*i);
}
if (joyhats != lastjoy2hats)
{
INT64 j = 1; // keep only bits that changed since last time
INT64 newhats = joyhats ^ lastjoy2hats;
lastjoy2hats = joyhats;
for (i = 0; i < JOYHATS*4; i++, j <<= 1)
{
if (newhats & j) // hat changed state?
{
if (joyhats & j)
event.type = ev_keydown;
else
event.type = ev_keyup;
event.key = KEY_2HAT1 + i;
D_PostEvent(&event);
}
}
}
#if 0
// send joystick axis positions
event.type = ev_joystick2;
for (i = JOYAXISSET - 1; i >= 0; i--)
{
event.key = i;
if (i*2 + 1 <= JoyInfo2.axises)
axisx = SDL_JoystickGetAxis(JoyInfo2.dev, i*2 + 0);
else axisx = 0;
if (i*2 + 2 <= JoyInfo2.axises)
axisy = SDL_JoystickGetAxis(JoyInfo2.dev, i*2 + 1);
else axisy = 0;
// -32768 to 32767
axisx = axisx/32;
axisy = axisy/32;
if (Joystick2.bGamepadStyle)
{
// gamepad control type, on or off, live or die
if (axisx < -(JOYAXISRANGE/2))
event.x = -1;
else if (axisx > (JOYAXISRANGE/2))
event.x = 1;
else
event.x = 0;
if (axisy < -(JOYAXISRANGE/2))
event.y = -1;
else if (axisy > (JOYAXISRANGE/2))
event.y = 1;
else
event.y = 0;
}
else
{
axisx = JoyInfo2.scale?((axisx/JoyInfo2.scale)*JoyInfo2.scale):axisx;
axisy = JoyInfo2.scale?((axisy/JoyInfo2.scale)*JoyInfo2.scale):axisy;
#ifdef SDL_JDEADZONE
if (-SDL_JDEADZONE <= axisx && axisx <= SDL_JDEADZONE) axisx = 0;
if (-SDL_JDEADZONE <= axisy && axisy <= SDL_JDEADZONE) axisy = 0;
#endif
// analog control style , just send the raw data
event.x = axisx; // x axis
event.y = axisy; // y axis
}
D_PostEvent(&event);
}
#endif
}
/** \brief Open joystick handle
\param fname name of joystick
\return axises
*/
static int joy_open2(int joyindex)
{
SDL_Joystick *newdev = NULL;
int num_joy = 0;
if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
{
CONS_Printf(M_GetText("Joystick subsystem not started\n"));
return -1;
}
if (joyindex <= 0)
return -1;
num_joy = SDL_NumJoysticks();
if (num_joy == 0)
{
CONS_Printf("%s", M_GetText("Found no joysticks on this system\n"));
return -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 (JoyInfo2.dev)
{
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_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)
{
I_OutputMsg("Not enought axes?\n");
return 0;
}*/
JoyInfo2.buttons = SDL_JoystickNumButtons(JoyInfo2.dev);
if (JoyInfo2.buttons > JOYBUTTONS)
JoyInfo2.buttons = JOYBUTTONS;
JoyInfo2.hats = SDL_JoystickNumHats(JoyInfo2.dev);
if (JoyInfo2.hats > JOYHATS)
JoyInfo2.hats = JOYHATS;
JoyInfo2.balls = SDL_JoystickNumBalls(JoyInfo2.dev);
//Joystick.bGamepadStyle = !stricmp(SDL_JoystickName(JoyInfo2.dev), "pad");
return JoyInfo2.axises;
}
}
//
// I_InitJoystick
//
void I_InitJoystick(void)
{
SDL_Joystick *newjoy = NULL;
//I_ShutdownJoystick();
if (M_CheckParm("-nojoy"))
return;
if (M_CheckParm("-noxinput"))
SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE);
if (M_CheckParm("-nohidapi"))
SDL_SetHintWithPriority("SDL_JOYSTICK_HIDAPI", "0", SDL_HINT_OVERRIDE);
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) // 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;
joystick_started = 0;
}
if (JoyInfo.dev != newjoy && JoyInfo2.dev != newjoy)
SDL_JoystickClose(newjoy);
}
void I_InitJoystick2(void)
{
SDL_Joystick *newjoy = NULL;
//I_ShutdownJoystick2();
if (M_CheckParm("-nojoy"))
return;
if (M_CheckParm("-noxinput"))
SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE);
if (M_CheckParm("-nohidapi"))
SDL_SetHintWithPriority("SDL_JOYSTICK_HIDAPI", "0", SDL_HINT_OVERRIDE);
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) // 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;
joystick2_started = 0;
}
if (JoyInfo.dev != newjoy && JoyInfo2.dev != newjoy)
SDL_JoystickClose(newjoy);
}
static void I_ShutdownInput(void)
{
I_ShutdownGamepads();
// 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();
if (SDL_WasInit(GAMEPAD_INIT_FLAGS) == GAMEPAD_INIT_FLAGS)
if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
{
CONS_Printf("Shutting down game controller subsystems\n");
SDL_QuitSubSystem(GAMEPAD_INIT_FLAGS);
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) == SDL_INIT_JOYSTICK)
numjoy = SDL_NumJoysticks();
return numjoy;
}
static char joyname[255]; // 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) == SDL_INIT_JOYSTICK)
{
tempname = SDL_JoystickNameForIndex(joyindex);
if (tempname)
strncpy(joyname, tempname, 255);
}
return joyname;
}
#ifndef NOMUMBLE
#ifdef HAVE_MUMBLE
// Best Mumble positional audio settings:
@ -1373,6 +2113,23 @@ void I_StartupMouse2(void)
#endif
}
//
// I_Tactile
//
void I_Tactile(FFType pFFType, const JoyFF_t *FFEffect)
{
// UNUSED.
(void)pFFType;
(void)FFEffect;
}
void I_Tactile2(FFType pFFType, const JoyFF_t *FFEffect)
{
// UNUSED.
(void)pFFType;
(void)FFEffect;
}
/** \brief empty ticcmd for player 1
*/
static ticcmd_t emptycmd;

View file

@ -66,7 +66,7 @@
#include "../m_menu.h"
#include "../d_main.h"
#include "../s_sound.h"
#include "../i_gamepad.h"
#include "../i_joy.h"
#include "../st_stuff.h"
#include "../hu_stuff.h"
#include "../g_game.h"
@ -449,10 +449,51 @@ static void SurfaceInfo(const SDL_Surface *infoSurface, const char *SurfaceText)
static void VID_Command_Info_f (void)
{
#if 0
SDL2STUB();
#else
#if 0
const SDL_VideoInfo *videoInfo;
videoInfo = SDL_GetVideoInfo(); //Alam: Double-Check
if (videoInfo)
{
CONS_Printf("%s", M_GetText("Video Interface Capabilities:\n"));
if (videoInfo->hw_available)
CONS_Printf("%s", M_GetText(" Hardware surfaces\n"));
if (videoInfo->wm_available)
CONS_Printf("%s", M_GetText(" Window manager\n"));
//UnusedBits1 :6
//UnusedBits2 :1
if (videoInfo->blit_hw)
CONS_Printf("%s", M_GetText(" Accelerated blits HW-2-HW\n"));
if (videoInfo->blit_hw_CC)
CONS_Printf("%s", M_GetText(" Accelerated blits HW-2-HW with Colorkey\n"));
if (videoInfo->wm_available)
CONS_Printf("%s", M_GetText(" Accelerated blits HW-2-HW with Alpha\n"));
if (videoInfo->blit_sw)
{
CONS_Printf("%s", M_GetText(" Accelerated blits SW-2-HW\n"));
if (!M_CheckParm("-noblit")) videoblitok = SDL_TRUE;
}
if (videoInfo->blit_sw_CC)
CONS_Printf("%s", M_GetText(" Accelerated blits SW-2-HW with Colorkey\n"));
if (videoInfo->blit_sw_A)
CONS_Printf("%s", M_GetText(" Accelerated blits SW-2-HW with Alpha\n"));
if (videoInfo->blit_fill)
CONS_Printf("%s", M_GetText(" Accelerated Color filling\n"));
//UnusedBits3 :16
if (videoInfo->video_mem)
CONS_Printf(M_GetText(" There is %i KB of video memory\n"), videoInfo->video_mem);
else
CONS_Printf("%s", M_GetText(" There no video memory for SDL\n"));
//*vfmt
}
#else
if (!M_CheckParm("-noblit")) videoblitok = SDL_TRUE;
#endif
SurfaceInfo(bufSurface, M_GetText("Current Engine Mode"));
SurfaceInfo(vidSurface, M_GetText("Current Video Mode"));
#endif
}
static void VID_Command_ModeList_f(void)
@ -487,6 +528,61 @@ static void VID_Command_Mode_f (void)
setmodeneeded = modenum+1; // request vid mode change
}
static inline void SDLJoyRemap(event_t *event)
{
(void)event;
}
static INT32 SDLJoyAxis(const Sint16 axis, evtype_t which)
{
// -32768 to 32767
INT32 raxis = axis/32;
if (which == ev_joystick)
{
if (Joystick.bGamepadStyle)
{
// gamepad control type, on or off, live or die
if (raxis < -(JOYAXISRANGE/2))
raxis = -1;
else if (raxis > (JOYAXISRANGE/2))
raxis = 1;
else
raxis = 0;
}
else
{
raxis = JoyInfo.scale!=1?((raxis/JoyInfo.scale)*JoyInfo.scale):raxis;
#ifdef SDL_JDEADZONE
if (-SDL_JDEADZONE <= raxis && raxis <= SDL_JDEADZONE)
raxis = 0;
#endif
}
}
else if (which == ev_joystick2)
{
if (Joystick2.bGamepadStyle)
{
// gamepad control type, on or off, live or die
if (raxis < -(JOYAXISRANGE/2))
raxis = -1;
else if (raxis > (JOYAXISRANGE/2))
raxis = 1;
else raxis = 0;
}
else
{
raxis = JoyInfo2.scale!=1?((raxis/JoyInfo2.scale)*JoyInfo2.scale):raxis;
#ifdef SDL_JDEADZONE
if (-SDL_JDEADZONE <= raxis && raxis <= SDL_JDEADZONE)
raxis = 0;
#endif
}
}
return raxis;
}
static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
{
static SDL_bool firsttimeonmouse = SDL_TRUE;
@ -518,13 +614,13 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
// Tell game we got focus back, resume music if necessary
window_notinfocus = false;
if (!paused)
S_ResumeAudio();
S_ResumeAudio(); //resume it
I_ToggleControllerRumble(true);
P_UnpauseRumble(NULL);
if (!firsttimeonmouse && cv_usemouse.value)
I_StartupMouse();
if (!firsttimeonmouse)
{
if (cv_usemouse.value) I_StartupMouse();
}
//else firsttimeonmouse = SDL_FALSE;
if (USE_MOUSEINPUT && !IgnoreMouse())
SDLdoGrabMouse();
@ -533,45 +629,43 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
{
// Tell game we lost focus, pause music
window_notinfocus = true;
if (!cv_playmusicifunfocused.value)
if (! cv_playmusicifunfocused.value)
S_PauseAudio();
if (!cv_playsoundsifunfocused.value)
if (! cv_playsoundsifunfocused.value)
S_StopSounds();
if (!disable_mouse)
{
SDLforceUngrabMouse();
}
memset(gamekeydown, 0, NUMKEYS); // TODO this is a scary memset
I_ToggleControllerRumble(false);
if (P_AutoPause())
P_PauseRumble(NULL);
if (MOUSE_MENU)
{
SDLdoUngrabMouse();
}
}
}
static void Impl_HandleKeyboardEvent(SDL_KeyboardEvent evt, Uint32 type)
{
event_t event;
if (type == SDL_KEYUP)
{
event.type = ev_keyup;
}
else if (type == SDL_KEYDOWN)
{
event.type = ev_keydown;
}
else
{
return;
}
event.key = Impl_SDL_Scancode_To_Keycode(evt.keysym.scancode);
if (!event.key)
return;
event.repeated = (evt.repeat != 0);
event.which = 0;
D_PostEvent(&event);
if (event.key) D_PostEvent(&event);
}
static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt)
@ -636,35 +730,32 @@ static void Impl_HandleMouseButtonEvent(SDL_MouseButtonEvent evt, Uint32 type)
if (SDL_GetMouseFocus() != window || IgnoreMouse())
return;
/// \todo inputEvent.button.which
if (USE_MOUSEINPUT)
{
if (type == SDL_MOUSEBUTTONUP)
event.type = ev_keyup;
else if (type == SDL_MOUSEBUTTONDOWN)
event.type = ev_keydown;
else
return;
switch (evt.button)
{
case SDL_BUTTON_LEFT:
event.key = KEY_MOUSE1+0;
break;
case SDL_BUTTON_RIGHT:
event.key = KEY_MOUSE1+1;
break;
case SDL_BUTTON_MIDDLE:
event.key = KEY_MOUSE1+2;
break;
case SDL_BUTTON_X1:
event.key = KEY_MOUSE1+3;
break;
case SDL_BUTTON_X2:
event.key = KEY_MOUSE1+4;
break;
event.type = ev_keyup;
}
else if (type == SDL_MOUSEBUTTONDOWN)
{
event.type = ev_keydown;
}
else return;
if (evt.button == SDL_BUTTON_MIDDLE)
event.key = KEY_MOUSE1+2;
else if (evt.button == SDL_BUTTON_RIGHT)
event.key = KEY_MOUSE1+1;
else if (evt.button == SDL_BUTTON_LEFT)
event.key = KEY_MOUSE1;
else if (evt.button == SDL_BUTTON_X1)
event.key = KEY_MOUSE1+3;
else if (evt.button == SDL_BUTTON_X2)
event.key = KEY_MOUSE1+4;
if (event.type == ev_keyup || event.type == ev_keydown)
{
D_PostEvent(&event);
}
D_PostEvent(&event);
}
}
@ -695,6 +786,111 @@ static void Impl_HandleMouseWheelEvent(SDL_MouseWheelEvent evt)
}
}
static void Impl_HandleJoystickAxisEvent(SDL_JoyAxisEvent evt)
{
event_t event;
SDL_JoystickID joyid[2];
// Determine the Joystick IDs for each current open joystick
joyid[0] = SDL_JoystickInstanceID(JoyInfo.dev);
joyid[1] = SDL_JoystickInstanceID(JoyInfo2.dev);
evt.axis++;
event.key = event.x = event.y = INT32_MAX;
if (evt.which == joyid[0])
{
event.type = ev_joystick;
}
else if (evt.which == joyid[1])
{
event.type = ev_joystick2;
}
else return;
//axis
if (evt.axis > JOYAXISSET*2)
return;
//vaule
if (evt.axis%2)
{
event.key = evt.axis / 2;
event.x = SDLJoyAxis(evt.value, event.type);
}
else
{
evt.axis--;
event.key = evt.axis / 2;
event.y = SDLJoyAxis(evt.value, event.type);
}
D_PostEvent(&event);
}
#if 0
static void Impl_HandleJoystickHatEvent(SDL_JoyHatEvent evt)
{
event_t event;
SDL_JoystickID joyid[2];
// Determine the Joystick IDs for each current open joystick
joyid[0] = SDL_JoystickInstanceID(JoyInfo.dev);
joyid[1] = SDL_JoystickInstanceID(JoyInfo2.dev);
if (evt.hat >= JOYHATS)
return; // ignore hats with too high an index
if (evt.which == joyid[0])
{
event.key = KEY_HAT1 + (evt.hat*4);
}
else if (evt.which == joyid[1])
{
event.key = KEY_2HAT1 + (evt.hat*4);
}
else return;
// NOTE: UNFINISHED
}
#endif
static void Impl_HandleJoystickButtonEvent(SDL_JoyButtonEvent evt, Uint32 type)
{
event_t event;
SDL_JoystickID joyid[2];
// Determine the Joystick IDs for each current open joystick
joyid[0] = SDL_JoystickInstanceID(JoyInfo.dev);
joyid[1] = SDL_JoystickInstanceID(JoyInfo2.dev);
if (evt.which == joyid[0])
{
event.key = KEY_JOY1;
}
else if (evt.which == joyid[1])
{
event.key = KEY_2JOY1;
}
else return;
if (type == SDL_JOYBUTTONUP)
{
event.type = ev_keyup;
}
else if (type == SDL_JOYBUTTONDOWN)
{
event.type = ev_keydown;
}
else return;
if (evt.button < JOYBUTTONS)
{
event.key += evt.button;
}
else return;
SDLJoyRemap(&event);
if (event.type != ev_console) D_PostEvent(&event);
}
void I_GetEvent(void)
{
SDL_Event evt;
@ -732,18 +928,147 @@ void I_GetEvent(void)
case SDL_MOUSEWHEEL:
Impl_HandleMouseWheelEvent(evt.wheel);
break;
case SDL_CONTROLLERAXISMOTION:
I_HandleControllerAxisEvent(evt.caxis);
case SDL_JOYAXISMOTION:
Impl_HandleJoystickAxisEvent(evt.jaxis);
break;
case SDL_CONTROLLERBUTTONUP:
case SDL_CONTROLLERBUTTONDOWN:
I_HandleControllerButtonEvent(evt.cbutton, evt.type);
#if 0
case SDL_JOYHATMOTION:
Impl_HandleJoystickHatEvent(evt.jhat)
break;
case SDL_CONTROLLERDEVICEADDED:
I_ControllerDeviceAdded(evt.cdevice.which);
#endif
case SDL_JOYBUTTONUP:
case SDL_JOYBUTTONDOWN:
Impl_HandleJoystickButtonEvent(evt.jbutton, evt.type);
break;
case SDL_CONTROLLERDEVICEREMOVED:
I_ControllerDeviceRemoved();
case SDL_JOYDEVICEADDED:
{
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!
if (newjoy && (!JoyInfo.dev || !SDL_JoystickGetAttached(JoyInfo.dev))
&& JoyInfo2.dev != newjoy) // don't override a currently active device
{
cv_usejoystick.value = evt.jdevice.which + 1;
if (JoyInfo2.dev)
cv_usejoystick2.value = I_GetJoystickDeviceIndex(JoyInfo2.dev) + 1;
else if (atoi(cv_usejoystick2.string) != JoyInfo.oldjoy
&& atoi(cv_usejoystick2.string) != cv_usejoystick.value)
cv_usejoystick2.value = atoi(cv_usejoystick2.string);
else if (atoi(cv_usejoystick.string) != JoyInfo.oldjoy
&& atoi(cv_usejoystick.string) != cv_usejoystick.value)
cv_usejoystick2.value = atoi(cv_usejoystick.string);
else // we tried...
cv_usejoystick2.value = 0;
}
else if (newjoy && (!JoyInfo2.dev || !SDL_JoystickGetAttached(JoyInfo2.dev))
&& JoyInfo.dev != newjoy) // don't override a currently active device
{
cv_usejoystick2.value = evt.jdevice.which + 1;
if (JoyInfo.dev)
cv_usejoystick.value = I_GetJoystickDeviceIndex(JoyInfo.dev) + 1;
else if (atoi(cv_usejoystick.string) != JoyInfo2.oldjoy
&& atoi(cv_usejoystick.string) != cv_usejoystick2.value)
cv_usejoystick.value = atoi(cv_usejoystick.string);
else if (atoi(cv_usejoystick2.string) != JoyInfo2.oldjoy
&& atoi(cv_usejoystick2.string) != cv_usejoystick2.value)
cv_usejoystick.value = atoi(cv_usejoystick2.string);
else // we tried...
cv_usejoystick.value = 0;
}
// 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);
// 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();
CONS_Debug(DBG_GAMELOGIC, "Joystick1 device index: %d\n", JoyInfo.oldjoy);
CONS_Debug(DBG_GAMELOGIC, "Joystick2 device index: %d\n", JoyInfo2.oldjoy);
// update the menu
if (currentMenu == &OP_JoystickSetDef)
M_SetupJoystickMenu(0);
if (JoyInfo.dev != newjoy && JoyInfo2.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();
}
// 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)
cv_usejoystick.value = atoi(cv_usejoystick.string);
else if (atoi(cv_usejoystick2.string) != JoyInfo2.oldjoy)
cv_usejoystick.value = atoi(cv_usejoystick2.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_usejoystick2.string) != JoyInfo.oldjoy)
cv_usejoystick2.value = atoi(cv_usejoystick2.string);
else if (atoi(cv_usejoystick.string) != JoyInfo.oldjoy)
cv_usejoystick2.value = atoi(cv_usejoystick.string);
else // we tried...
cv_usejoystick2.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);
CONS_Debug(DBG_GAMELOGIC, "Joystick1 device index: %d\n", JoyInfo.oldjoy);
CONS_Debug(DBG_GAMELOGIC, "Joystick2 device index: %d\n", JoyInfo2.oldjoy);
// update the menu
if (currentMenu == &OP_JoystickSetDef)
M_SetupJoystickMenu(0);
break;
case SDL_QUIT:
LUA_HookBool(true, HOOK(GameQuit));
@ -761,7 +1086,6 @@ void I_GetEvent(void)
//SDL_memset(&event, 0, sizeof(event_t));
event.type = ev_mouse;
event.key = 0;
event.which = 0;
event.x = (INT32)lround(mousemovex * ((float)wwidth / (float)realwidth));
event.y = (INT32)lround(mousemovey * ((float)wheight / (float)realheight));
D_PostEvent(&event);
@ -800,9 +1124,15 @@ void I_OsPolling(void)
if (consolevent)
I_GetConsoleEvents();
if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
{
SDL_JoystickUpdate();
I_GetJoystickEvents();
I_GetJoystick2Events();
}
I_UpdateControllers();
I_GetMouseEvents();
I_GetEvent();
mod = SDL_GetModState();

View file

@ -23,41 +23,59 @@ extern SDL_bool consolevent;
extern SDL_bool framebuffer;
#include "../m_fixed.h"
#include "../i_gamepad.h"
// SDL info about all controllers
typedef struct
// SDL2 stub macro
#ifdef _MSC_VER
#define SDL2STUB() CONS_Printf("SDL2: stubbed: %s:%d\n", __FUNCTION__, __LINE__)
#else
#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
*/
typedef struct SDLJoyInfo_s
{
boolean started; // started
int lastindex; // last gamepad ID
/// Joystick handle
SDL_Joystick *dev;
/// number of old joystick
int oldjoy;
/// number of axies
int axises;
/// scale of axises
INT32 scale;
/// number of buttons
int buttons;
/// number of hats
int hats;
/// number of balls
int balls;
SDL_GameController *dev;
SDL_Joystick *joydev;
} SDLJoyInfo_t;
gamepad_t *info; // pointer to gamepad info
/** \brief SDL info about joystick 1
*/
extern SDLJoyInfo_t JoyInfo;
struct {
Uint16 large_magnitude;
Uint16 small_magnitude;
Uint32 expiration, time_left;
} rumble;
} ControllerInfo;
/** \brief joystick axis deadzone
*/
#define SDL_JDEADZONE 153
#undef SDL_JDEADZONE
#define GAMEPAD_INIT_FLAGS (SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER)
/** \brief SDL inof about joystick 2
*/
extern SDLJoyInfo_t JoyInfo2;
void I_UpdateControllers(void);
// So we can call this from i_video event loop
void I_ShutdownJoystick(void);
void I_ShutdownJoystick2(void);
void I_ControllerDeviceAdded(INT32 which);
void I_ControllerDeviceRemoved(void);
void I_HandleControllerButtonEvent(SDL_ControllerButtonEvent evt, Uint32 type);
void I_HandleControllerAxisEvent(SDL_ControllerAxisEvent evt);
INT32 I_GetControllerIndex(SDL_GameController *dev);
void I_CloseInactiveController(SDL_GameController *dev);
void I_CloseInactiveHapticDevice(SDL_Haptic *dev);
void I_ToggleControllerRumble(boolean unpause);
// Cheat to get the device index for a joystick handle
INT32 I_GetJoystickDeviceIndex(SDL_Joystick *dev);
void I_GetConsoleEvents(void);

View file

@ -164,7 +164,7 @@ hudinfo_t hudinfo[NUMHUDITEMS] =
{ 288, 176, V_SNAPTORIGHT|V_SNAPTOBOTTOM}, // HUD_POWERUPS
};
static huddrawlist_h luahuddrawlist_game;
static huddrawlist_h luahuddrawlist_game[2];
static huddrawlist_h luahuddrawlist_titlecard;
//
@ -427,7 +427,8 @@ void ST_Init(void)
ST_LoadGraphics();
luahuddrawlist_game = LUA_HUD_CreateDrawList();
luahuddrawlist_game[0] = LUA_HUD_CreateDrawList();
luahuddrawlist_game[1] = LUA_HUD_CreateDrawList();
luahuddrawlist_titlecard = LUA_HUD_CreateDrawList();
}
@ -2757,10 +2758,13 @@ static void ST_overlayDrawer(void)
if (!(netgame || multiplayer) || !hu_showscores)
{
INT32 hooklistindex = splitscreen && stplyr == &players[secondarydisplayplayer] ? 1 : 0;
if (renderisnewtic)
{
LUA_HUDHOOK(game, luahuddrawlist_game);
LUA_HUD_ClearDrawList(luahuddrawlist_game[hooklistindex]);
LUA_HUDHOOK(game, luahuddrawlist_game[hooklistindex]);
}
LUA_HUD_DrawList(luahuddrawlist_game[hooklistindex]);
}
// draw level title Tails
@ -2839,10 +2843,6 @@ void ST_Drawer(void)
if (st_overlay)
{
if (renderisnewtic)
{
LUA_HUD_ClearDrawList(luahuddrawlist_game);
}
// No deadview!
stplyr = &players[displayplayer];
ST_overlayDrawer();
@ -2852,7 +2852,5 @@ void ST_Drawer(void)
stplyr = &players[secondarydisplayplayer];
ST_overlayDrawer();
}
LUA_HUD_DrawList(luahuddrawlist_game);
}
}

View file

@ -22,6 +22,16 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef _MSC_VER
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#ifndef strncasecmp
#define strncasecmp _strnicmp
#endif
#endif
static inline int
trycmp (char **pp, char *cp,