mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-17 10:11:02 +00:00
Merge branch 'master' into lua-spritedefs
This commit is contained in:
commit
3d2fd5d5a4
38 changed files with 991 additions and 829 deletions
|
@ -1,6 +1,6 @@
|
||||||
cmake_minimum_required(VERSION 3.0)
|
cmake_minimum_required(VERSION 3.0)
|
||||||
project(SRB2
|
project(SRB2
|
||||||
VERSION 2.1.18
|
VERSION 2.1.19
|
||||||
LANGUAGES C)
|
LANGUAGES C)
|
||||||
|
|
||||||
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})
|
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})
|
||||||
|
|
37
appveyor.yml
37
appveyor.yml
|
@ -1,4 +1,4 @@
|
||||||
version: 2.1.18.{branch}-{build}
|
version: 2.1.19.{branch}-{build}
|
||||||
os: MinGW
|
os: MinGW
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
@ -47,7 +47,7 @@ before_build:
|
||||||
- upx -V
|
- upx -V
|
||||||
- ccache -V
|
- ccache -V
|
||||||
- ccache -s
|
- ccache -s
|
||||||
- set SRB2_MFLAGS=-C src MINGW=1 WARNINGMODE=1 GCC63=1 CCACHE=1
|
- set SRB2_MFLAGS=-C src MINGW=1 WARNINGMODE=1 GCC63=1 CCACHE=1 NOOBJDUMP=1
|
||||||
|
|
||||||
build_script:
|
build_script:
|
||||||
- cmd: mingw32-make.exe %SRB2_MFLAGS% %CONFIGURATION%=1 clean
|
- cmd: mingw32-make.exe %SRB2_MFLAGS% %CONFIGURATION%=1 clean
|
||||||
|
@ -58,26 +58,29 @@ after_build:
|
||||||
- cmd: git rev-parse --short %APPVEYOR_REPO_COMMIT%>%TMP%/gitshort.txt
|
- cmd: git rev-parse --short %APPVEYOR_REPO_COMMIT%>%TMP%/gitshort.txt
|
||||||
- cmd: set /P GITSHORT=<%TMP%/gitshort.txt
|
- cmd: set /P GITSHORT=<%TMP%/gitshort.txt
|
||||||
- set BUILD_ARCHIVE=%APPVEYOR_REPO_BRANCH%-%GITSHORT%-%CONFIGURATION%.7z
|
- set BUILD_ARCHIVE=%APPVEYOR_REPO_BRANCH%-%GITSHORT%-%CONFIGURATION%.7z
|
||||||
|
- set BUILDSARCHIVE=%APPVEYOR_REPO_BRANCH%-%CONFIGURATION%.7z
|
||||||
- cmd: 7z a %BUILD_ARCHIVE% bin\Mingw\Release -xr!.gitignore
|
- cmd: 7z a %BUILD_ARCHIVE% bin\Mingw\Release -xr!.gitignore
|
||||||
- appveyor PushArtifact %BUILD_ARCHIVE%
|
- appveyor PushArtifact %BUILD_ARCHIVE%
|
||||||
|
- cmd: copy %BUILD_ARCHIVE% %BUILDSARCHIVE%
|
||||||
|
- appveyor PushArtifact %BUILDSARCHIVE%
|
||||||
|
|
||||||
test: off
|
test: off
|
||||||
|
|
||||||
deploy:
|
#deploy:
|
||||||
- provider: FTP
|
# - provider: FTP
|
||||||
protocol: ftps
|
# protocol: ftps
|
||||||
host:
|
# host:
|
||||||
secure: NsLJEPIBvmwCOj8Tg8RoRQ==
|
# secure: NsLJEPIBvmwCOj8Tg8RoRQ==
|
||||||
username:
|
# username:
|
||||||
secure: ejxi5mvk7oLYu7QtbYojajEPigMy0mokaKhuEVuDZcA=
|
# secure: ejxi5mvk7oLYu7QtbYojajEPigMy0mokaKhuEVuDZcA=
|
||||||
password:
|
# password:
|
||||||
secure: Hbn6Uy3lT0YZ88yFJ3aW4w==
|
# secure: Hbn6Uy3lT0YZ88yFJ3aW4w==
|
||||||
folder: appveyor
|
# folder: appveyor
|
||||||
application:
|
# application:
|
||||||
active_mode: false
|
# active_mode: false
|
||||||
on:
|
# on:
|
||||||
branch: master
|
# branch: master
|
||||||
appveyor_repo_tag: true
|
# appveyor_repo_tag: true
|
||||||
|
|
||||||
|
|
||||||
on_finish:
|
on_finish:
|
||||||
|
|
|
@ -511,13 +511,11 @@ OBJS:=$(i_main_o) \
|
||||||
# For reference, this is the command I use to build a srb2.pot file from the source code.
|
# For reference, this is the command I use to build a srb2.pot file from the source code.
|
||||||
# (The listed source files are the ones containing translated strings).
|
# (The listed source files are the ones containing translated strings).
|
||||||
# FILES=""; for file in `find ./ | grep "\.c" | grep -v svn`; do [ "`grep "M_GetText(" $file`" ] && FILES="$FILES $file"; done; xgettext -d srb2 -o locale/srb2.pot -kM_GetText -F --no-wrap $FILES
|
# FILES=""; for file in `find ./ | grep "\.c" | grep -v svn`; do [ "`grep "M_GetText(" $file`" ] && FILES="$FILES $file"; done; xgettext -d srb2 -o locale/srb2.pot -kM_GetText -F --no-wrap $FILES
|
||||||
ifndef NOGETTEXT
|
|
||||||
ifdef GETTEXT
|
ifdef GETTEXT
|
||||||
POS:=$(BIN)/en.mo
|
POS:=$(BIN)/en.mo
|
||||||
|
|
||||||
OPTS+=-DGETTEXT
|
OPTS+=-DGETTEXT
|
||||||
endif
|
endif
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef DJGPPDOS
|
ifdef DJGPPDOS
|
||||||
all: pre-build $(BIN)/$(EXENAME)
|
all: pre-build $(BIN)/$(EXENAME)
|
||||||
|
|
|
@ -283,9 +283,6 @@ else
|
||||||
ifdef LINUX
|
ifdef LINUX
|
||||||
NASMFORMAT=elf -DLINUX
|
NASMFORMAT=elf -DLINUX
|
||||||
SDL=1
|
SDL=1
|
||||||
ifndef NOGETTEXT
|
|
||||||
GETTEXT=1
|
|
||||||
endif
|
|
||||||
ifdef LINUX64
|
ifdef LINUX64
|
||||||
OBJDIR:=$(OBJDIR)/Linux64
|
OBJDIR:=$(OBJDIR)/Linux64
|
||||||
BIN:=$(BIN)/Linux64
|
BIN:=$(BIN)/Linux64
|
||||||
|
@ -321,9 +318,6 @@ else
|
||||||
ifdef MINGW64
|
ifdef MINGW64
|
||||||
INTERFACE=win32
|
INTERFACE=win32
|
||||||
#NASMFORMAT=win64
|
#NASMFORMAT=win64
|
||||||
ifndef NOGETTEXT
|
|
||||||
#GETTEXT=1
|
|
||||||
endif
|
|
||||||
OBJDIR:=$(OBJDIR)/Mingw64
|
OBJDIR:=$(OBJDIR)/Mingw64
|
||||||
BIN:=$(BIN)/Mingw64
|
BIN:=$(BIN)/Mingw64
|
||||||
else
|
else
|
||||||
|
@ -354,9 +348,6 @@ else
|
||||||
ifdef MINGW
|
ifdef MINGW
|
||||||
INTERFACE=win32
|
INTERFACE=win32
|
||||||
NASMFORMAT=win32
|
NASMFORMAT=win32
|
||||||
ifndef NOGETTEXT
|
|
||||||
GETTEXT=1
|
|
||||||
endif
|
|
||||||
OBJDIR:=$(OBJDIR)/Mingw
|
OBJDIR:=$(OBJDIR)/Mingw
|
||||||
BIN:=$(BIN)/Mingw
|
BIN:=$(BIN)/Mingw
|
||||||
else
|
else
|
||||||
|
|
160
src/d_clisrv.c
160
src/d_clisrv.c
|
@ -1740,9 +1740,7 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent)
|
||||||
{
|
{
|
||||||
#ifndef NONET
|
#ifndef NONET
|
||||||
INT32 i;
|
INT32 i;
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef NONET
|
|
||||||
// serverlist is updated by GetPacket function
|
// serverlist is updated by GetPacket function
|
||||||
if (serverlistcount > 0)
|
if (serverlistcount > 0)
|
||||||
{
|
{
|
||||||
|
@ -1776,7 +1774,20 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent)
|
||||||
serverlist[i].info.fileneeded);
|
serverlist[i].info.fileneeded);
|
||||||
CONS_Printf(M_GetText("Checking files...\n"));
|
CONS_Printf(M_GetText("Checking files...\n"));
|
||||||
i = CL_CheckFiles();
|
i = CL_CheckFiles();
|
||||||
if (i == 2) // cannot join for some reason
|
if (i == 3) // too many files
|
||||||
|
{
|
||||||
|
D_QuitNetGame();
|
||||||
|
CL_Reset();
|
||||||
|
D_StartTitle();
|
||||||
|
M_StartMessage(M_GetText(
|
||||||
|
"You have too many WAD files loaded\n"
|
||||||
|
"to add ones the server is using.\n"
|
||||||
|
"Please restart SRB2 before connecting.\n\n"
|
||||||
|
"Press ESC\n"
|
||||||
|
), NULL, MM_NOTHING);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (i == 2) // cannot join for some reason
|
||||||
{
|
{
|
||||||
D_QuitNetGame();
|
D_QuitNetGame();
|
||||||
CL_Reset();
|
CL_Reset();
|
||||||
|
@ -2516,12 +2527,18 @@ static void Command_Nodes(void)
|
||||||
|
|
||||||
static void Command_Ban(void)
|
static void Command_Ban(void)
|
||||||
{
|
{
|
||||||
if (COM_Argc() == 1)
|
if (COM_Argc() < 2)
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("Ban <playername/playernum> <reason>: ban and kick a player\n"));
|
CONS_Printf(M_GetText("Ban <playername/playernum> <reason>: ban and kick a player\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!netgame) // Don't kick Tails in splitscreen!
|
||||||
|
{
|
||||||
|
CONS_Printf(M_GetText("This only works in a netgame.\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (server || adminplayer == consoleplayer)
|
if (server || adminplayer == consoleplayer)
|
||||||
{
|
{
|
||||||
XBOXSTATIC UINT8 buf[3 + MAX_REASONLENGTH];
|
XBOXSTATIC UINT8 buf[3 + MAX_REASONLENGTH];
|
||||||
|
@ -2531,8 +2548,9 @@ static void Command_Ban(void)
|
||||||
|
|
||||||
if (pn == -1 || pn == 0)
|
if (pn == -1 || pn == 0)
|
||||||
return;
|
return;
|
||||||
else
|
|
||||||
WRITEUINT8(p, pn);
|
WRITEUINT8(p, pn);
|
||||||
|
|
||||||
if (server && I_Ban && !I_Ban(node)) // only the server is allowed to do this right now
|
if (server && I_Ban && !I_Ban(node)) // only the server is allowed to do this right now
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Too many bans! Geez, that's a lot of people you're excluding...\n"));
|
CONS_Alert(CONS_WARNING, M_GetText("Too many bans! Geez, that's a lot of people you're excluding...\n"));
|
||||||
|
@ -2575,21 +2593,27 @@ static void Command_Ban(void)
|
||||||
|
|
||||||
static void Command_Kick(void)
|
static void Command_Kick(void)
|
||||||
{
|
{
|
||||||
XBOXSTATIC UINT8 buf[3 + MAX_REASONLENGTH];
|
if (COM_Argc() < 2)
|
||||||
UINT8 *p = buf;
|
|
||||||
|
|
||||||
if (COM_Argc() == 1)
|
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("kick <playername/playernum> <reason>: kick a player\n"));
|
CONS_Printf(M_GetText("kick <playername/playernum> <reason>: kick a player\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!netgame) // Don't kick Tails in splitscreen!
|
||||||
|
{
|
||||||
|
CONS_Printf(M_GetText("This only works in a netgame.\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (server || adminplayer == consoleplayer)
|
if (server || adminplayer == consoleplayer)
|
||||||
{
|
{
|
||||||
|
XBOXSTATIC UINT8 buf[3 + MAX_REASONLENGTH];
|
||||||
|
UINT8 *p = buf;
|
||||||
const SINT8 pn = nametonum(COM_Argv(1));
|
const SINT8 pn = nametonum(COM_Argv(1));
|
||||||
WRITESINT8(p, pn);
|
|
||||||
if (pn == -1 || pn == 0)
|
if (pn == -1 || pn == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Special case if we are trying to kick a player who is downloading the game state:
|
// Special case if we are trying to kick a player who is downloading the game state:
|
||||||
// trigger a timeout instead of kicking them, because a kick would only
|
// trigger a timeout instead of kicking them, because a kick would only
|
||||||
// take effect after they have finished downloading
|
// take effect after they have finished downloading
|
||||||
|
@ -2598,6 +2622,9 @@ static void Command_Kick(void)
|
||||||
Net_ConnectionTimeout(playernode[pn]);
|
Net_ConnectionTimeout(playernode[pn]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WRITESINT8(p, pn);
|
||||||
|
|
||||||
if (COM_Argc() == 2)
|
if (COM_Argc() == 2)
|
||||||
{
|
{
|
||||||
WRITEUINT8(p, KICK_MSG_GO_AWAY);
|
WRITEUINT8(p, KICK_MSG_GO_AWAY);
|
||||||
|
@ -3404,17 +3431,42 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
||||||
if (node != servernode)
|
if (node != servernode)
|
||||||
DEBFILE(va("Received packet from unknown host %d\n", node));
|
DEBFILE(va("Received packet from unknown host %d\n", node));
|
||||||
|
|
||||||
|
// macro for packets that should only be sent by the server
|
||||||
|
// if it is NOT from the server, bail out and close the connection!
|
||||||
|
#define SERVERONLY \
|
||||||
|
if (node != servernode) \
|
||||||
|
{ \
|
||||||
|
Net_CloseConnection(node); \
|
||||||
|
break; \
|
||||||
|
}
|
||||||
switch (netbuffer->packettype)
|
switch (netbuffer->packettype)
|
||||||
{
|
{
|
||||||
case PT_ASKINFOVIAMS:
|
case PT_ASKINFOVIAMS:
|
||||||
|
#if 0
|
||||||
if (server && serverrunning)
|
if (server && serverrunning)
|
||||||
{
|
{
|
||||||
INT32 clientnode = I_NetMakeNode(netbuffer->u.msaskinfo.clientaddr);
|
INT32 clientnode;
|
||||||
SV_SendServerInfo(clientnode, (tic_t)LONG(netbuffer->u.msaskinfo.time));
|
if (ms_RoomId < 0) // ignore if we're not actually on the MS right now
|
||||||
SV_SendPlayerInfo(clientnode); // Send extra info
|
{
|
||||||
Net_CloseConnection(clientnode);
|
Net_CloseConnection(node); // and yes, close connection
|
||||||
// Don't close connection to MS.
|
return;
|
||||||
|
}
|
||||||
|
clientnode = I_NetMakeNode(netbuffer->u.msaskinfo.clientaddr);
|
||||||
|
if (clientnode != -1)
|
||||||
|
{
|
||||||
|
SV_SendServerInfo(clientnode, (tic_t)LONG(netbuffer->u.msaskinfo.time));
|
||||||
|
SV_SendPlayerInfo(clientnode); // Send extra info
|
||||||
|
Net_CloseConnection(clientnode);
|
||||||
|
// Don't close connection to MS...
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Net_CloseConnection(node); // ...unless the IP address is not valid
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
Net_CloseConnection(node); // you're not supposed to get it, so ignore it
|
||||||
|
#else
|
||||||
|
Net_CloseConnection(node);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PT_ASKINFO:
|
case PT_ASKINFO:
|
||||||
|
@ -3422,8 +3474,8 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
||||||
{
|
{
|
||||||
SV_SendServerInfo(node, (tic_t)LONG(netbuffer->u.askinfo.time));
|
SV_SendServerInfo(node, (tic_t)LONG(netbuffer->u.askinfo.time));
|
||||||
SV_SendPlayerInfo(node); // Send extra info
|
SV_SendPlayerInfo(node); // Send extra info
|
||||||
Net_CloseConnection(node);
|
|
||||||
}
|
}
|
||||||
|
Net_CloseConnection(node);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PT_SERVERREFUSE: // Negative response of client join request
|
case PT_SERVERREFUSE: // Negative response of client join request
|
||||||
|
@ -3432,6 +3484,7 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
||||||
Net_CloseConnection(node);
|
Net_CloseConnection(node);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
SERVERONLY
|
||||||
if (cl_mode == CL_WAITJOINRESPONSE)
|
if (cl_mode == CL_WAITJOINRESPONSE)
|
||||||
{
|
{
|
||||||
// Save the reason so it can be displayed after quitting the netgame
|
// Save the reason so it can be displayed after quitting the netgame
|
||||||
|
@ -3463,6 +3516,7 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
||||||
Net_CloseConnection(node);
|
Net_CloseConnection(node);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
SERVERONLY
|
||||||
/// \note how would this happen? and is it doing the right thing if it does?
|
/// \note how would this happen? and is it doing the right thing if it does?
|
||||||
if (cl_mode != CL_WAITJOINRESPONSE)
|
if (cl_mode != CL_WAITJOINRESPONSE)
|
||||||
break;
|
break;
|
||||||
|
@ -3528,13 +3582,18 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
||||||
Net_CloseConnection(node);
|
Net_CloseConnection(node);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
SERVERONLY
|
||||||
Got_Filetxpak();
|
Got_Filetxpak();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PT_REQUESTFILE:
|
case PT_REQUESTFILE:
|
||||||
if (server)
|
if (server)
|
||||||
Got_RequestFilePak(node);
|
{
|
||||||
|
if (!cv_downloading.value || !Got_RequestFilePak(node))
|
||||||
|
Net_CloseConnection(node); // close connection if one of the requested files could not be sent, or you disabled downloading anyway
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Net_CloseConnection(node); // nope
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PT_NODETIMEOUT:
|
case PT_NODETIMEOUT:
|
||||||
|
@ -3557,6 +3616,7 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
||||||
break; // Ignore it
|
break; // Ignore it
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#undef SERVERONLY
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Handles a packet received from a node that is in game
|
/** Handles a packet received from a node that is in game
|
||||||
|
@ -3589,6 +3649,8 @@ FILESTAMP
|
||||||
{
|
{
|
||||||
// -------------------------------------------- SERVER RECEIVE ----------
|
// -------------------------------------------- SERVER RECEIVE ----------
|
||||||
case PT_RESYNCHGET:
|
case PT_RESYNCHGET:
|
||||||
|
if (client)
|
||||||
|
break;
|
||||||
SV_AcknowledgeResynchAck(netconsole, netbuffer->u.resynchgot);
|
SV_AcknowledgeResynchAck(netconsole, netbuffer->u.resynchgot);
|
||||||
break;
|
break;
|
||||||
case PT_CLIENTCMD:
|
case PT_CLIENTCMD:
|
||||||
|
@ -3655,7 +3717,8 @@ FILESTAMP
|
||||||
}
|
}
|
||||||
|
|
||||||
// Splitscreen cmd
|
// Splitscreen cmd
|
||||||
if (netbuffer->packettype == PT_CLIENT2CMD && nodetoplayer2[node] >= 0)
|
if ((netbuffer->packettype == PT_CLIENT2CMD || netbuffer->packettype == PT_CLIENT2MIS)
|
||||||
|
&& nodetoplayer2[node] >= 0)
|
||||||
G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)nodetoplayer2[node]],
|
G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)nodetoplayer2[node]],
|
||||||
&netbuffer->u.client2pak.cmd2, 1);
|
&netbuffer->u.client2pak.cmd2, 1);
|
||||||
|
|
||||||
|
@ -3714,6 +3777,27 @@ FILESTAMP
|
||||||
tic_t tic = maketic;
|
tic_t tic = maketic;
|
||||||
UINT8 *textcmd;
|
UINT8 *textcmd;
|
||||||
|
|
||||||
|
// ignore if the textcmd has a reported size of zero
|
||||||
|
// this shouldn't be sent at all
|
||||||
|
if (!netbuffer->u.textcmd[0])
|
||||||
|
{
|
||||||
|
DEBFILE(va("GetPacket: Textcmd with size 0 detected! (node %u, player %d)\n",
|
||||||
|
node, netconsole));
|
||||||
|
Net_UnAcknowledgePacket(node);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore if the textcmd size var is actually larger than it should be
|
||||||
|
// BASEPACKETSIZE + 1 (for size) + textcmd[0] should == datalength
|
||||||
|
if (netbuffer->u.textcmd[0] > (size_t)doomcom->datalength-BASEPACKETSIZE-1)
|
||||||
|
{
|
||||||
|
DEBFILE(va("GetPacket: Bad Textcmd packet size! (expected %d, actual %s, node %u, player %d)\n",
|
||||||
|
netbuffer->u.textcmd[0], sizeu1((size_t)doomcom->datalength-BASEPACKETSIZE-1),
|
||||||
|
node, netconsole));
|
||||||
|
Net_UnAcknowledgePacket(node);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// check if tic that we are making isn't too large else we cannot send it :(
|
// check if tic that we are making isn't too large else we cannot send it :(
|
||||||
// doomcom->numslots+1 "+1" since doomcom->numslots can change within this time and sent time
|
// doomcom->numslots+1 "+1" since doomcom->numslots can change within this time and sent time
|
||||||
j = software_MAXPACKETLENGTH
|
j = software_MAXPACKETLENGTH
|
||||||
|
@ -3907,7 +3991,7 @@ FILESTAMP
|
||||||
if (client)
|
if (client)
|
||||||
{
|
{
|
||||||
INT32 i;
|
INT32 i;
|
||||||
for (i = 0; i < MAXNETNODES; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
if (playeringame[i])
|
if (playeringame[i])
|
||||||
playerpingtable[i] = (tic_t)netbuffer->u.pingtable[i];
|
playerpingtable[i] = (tic_t)netbuffer->u.pingtable[i];
|
||||||
}
|
}
|
||||||
|
@ -3917,6 +4001,21 @@ FILESTAMP
|
||||||
case PT_SERVERCFG:
|
case PT_SERVERCFG:
|
||||||
break;
|
break;
|
||||||
case PT_FILEFRAGMENT:
|
case PT_FILEFRAGMENT:
|
||||||
|
// Only accept PT_FILEFRAGMENT from the server.
|
||||||
|
if (node != servernode)
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_FILEFRAGMENT", node);
|
||||||
|
|
||||||
|
if (server)
|
||||||
|
{
|
||||||
|
XBOXSTATIC UINT8 buf[2];
|
||||||
|
buf[0] = (UINT8)node;
|
||||||
|
buf[1] = KICK_MSG_CON_FAIL;
|
||||||
|
SendNetXCmd(XD_KICK, &buf, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (client)
|
if (client)
|
||||||
Got_Filetxpak();
|
Got_Filetxpak();
|
||||||
break;
|
break;
|
||||||
|
@ -4450,8 +4549,8 @@ static inline void PingUpdate(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
//send out our ping packets
|
//send out our ping packets
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXNETNODES; i++)
|
||||||
if (playeringame[i])
|
if (nodeingame[i])
|
||||||
HSendPacket(i, true, 0, sizeof(INT32) * MAXPLAYERS);
|
HSendPacket(i, true, 0, sizeof(INT32) * MAXPLAYERS);
|
||||||
|
|
||||||
pingmeasurecount = 1; //Reset count
|
pingmeasurecount = 1; //Reset count
|
||||||
|
@ -4481,20 +4580,15 @@ void NetUpdate(void)
|
||||||
|
|
||||||
gametime = nowtime;
|
gametime = nowtime;
|
||||||
|
|
||||||
if (!(gametime % 255) && netgame && server)
|
|
||||||
{
|
|
||||||
#ifdef NEWPING
|
|
||||||
PingUpdate();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef NEWPING
|
#ifdef NEWPING
|
||||||
if (server)
|
if (server)
|
||||||
{
|
{
|
||||||
|
if (netgame && !(gametime % 255))
|
||||||
|
PingUpdate();
|
||||||
// update node latency values so we can take an average later.
|
// update node latency values so we can take an average later.
|
||||||
for (i = 0; i < MAXNETNODES; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
if (playeringame[i])
|
if (playeringame[i])
|
||||||
realpingtable[i] += G_TicsToMilliseconds(GetLag(i));
|
realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i]));
|
||||||
pingmeasurecount++;
|
pingmeasurecount++;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
68
src/d_main.c
68
src/d_main.c
|
@ -107,8 +107,6 @@ UINT8 window_notinfocus = false;
|
||||||
//
|
//
|
||||||
// DEMO LOOP
|
// DEMO LOOP
|
||||||
//
|
//
|
||||||
//static INT32 demosequence;
|
|
||||||
static const char *pagename = "MAP1PIC";
|
|
||||||
static char *startupwadfiles[MAX_WADFILES];
|
static char *startupwadfiles[MAX_WADFILES];
|
||||||
|
|
||||||
boolean devparm = false; // started game with -devparm
|
boolean devparm = false; // started game with -devparm
|
||||||
|
@ -721,7 +719,6 @@ void D_StartTitle(void)
|
||||||
|
|
||||||
gameaction = ga_nothing;
|
gameaction = ga_nothing;
|
||||||
displayplayer = consoleplayer = 0;
|
displayplayer = consoleplayer = 0;
|
||||||
//demosequence = -1;
|
|
||||||
gametype = GT_COOP;
|
gametype = GT_COOP;
|
||||||
paused = false;
|
paused = false;
|
||||||
advancedemo = false;
|
advancedemo = false;
|
||||||
|
@ -886,27 +883,10 @@ static void IdentifyVersion(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ======================================================================== */
|
|
||||||
// Just print the nice red titlebar like the original SRB2 for DOS.
|
|
||||||
/* ======================================================================== */
|
|
||||||
#ifdef PC_DOS
|
#ifdef PC_DOS
|
||||||
static inline void D_Titlebar(char *title1, char *title2)
|
/* ======================================================================== */
|
||||||
{
|
// Code for printing SRB2's title bar in DOS
|
||||||
// SRB2 banner
|
/* ======================================================================== */
|
||||||
clrscr();
|
|
||||||
textattr((BLUE<<4)+WHITE);
|
|
||||||
clreol();
|
|
||||||
cputs(title1);
|
|
||||||
|
|
||||||
// standard srb2 banner
|
|
||||||
textattr((RED<<4)+WHITE);
|
|
||||||
clreol();
|
|
||||||
gotoxy((80-strlen(title2))/2, 2);
|
|
||||||
cputs(title2);
|
|
||||||
normvideo();
|
|
||||||
gotoxy(1,3);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Center the title string, then add the date and time of compilation.
|
// Center the title string, then add the date and time of compilation.
|
||||||
|
@ -935,6 +915,31 @@ static inline void D_MakeTitleString(char *s)
|
||||||
strcpy(s, temp);
|
strcpy(s, temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void D_Titlebar(void)
|
||||||
|
{
|
||||||
|
char title1[82]; // srb2 title banner
|
||||||
|
char title2[82];
|
||||||
|
|
||||||
|
strcpy(title1, "Sonic Robo Blast 2");
|
||||||
|
strcpy(title2, "Sonic Robo Blast 2");
|
||||||
|
|
||||||
|
D_MakeTitleString(title1);
|
||||||
|
|
||||||
|
// SRB2 banner
|
||||||
|
clrscr();
|
||||||
|
textattr((BLUE<<4)+WHITE);
|
||||||
|
clreol();
|
||||||
|
cputs(title1);
|
||||||
|
|
||||||
|
// standard srb2 banner
|
||||||
|
textattr((RED<<4)+WHITE);
|
||||||
|
clreol();
|
||||||
|
gotoxy((80-strlen(title2))/2, 2);
|
||||||
|
cputs(title2);
|
||||||
|
normvideo();
|
||||||
|
gotoxy(1,3);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// D_SRB2Main
|
// D_SRB2Main
|
||||||
|
@ -942,8 +947,6 @@ static inline void D_MakeTitleString(char *s)
|
||||||
void D_SRB2Main(void)
|
void D_SRB2Main(void)
|
||||||
{
|
{
|
||||||
INT32 p;
|
INT32 p;
|
||||||
char srb2[82]; // srb2 title banner
|
|
||||||
char title[82];
|
|
||||||
|
|
||||||
INT32 pstartmap = 1;
|
INT32 pstartmap = 1;
|
||||||
boolean autostart = false;
|
boolean autostart = false;
|
||||||
|
@ -986,20 +989,8 @@ void D_SRB2Main(void)
|
||||||
dedicated = M_CheckParm("-dedicated") != 0;
|
dedicated = M_CheckParm("-dedicated") != 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
strcpy(title, "Sonic Robo Blast 2");
|
|
||||||
strcpy(srb2, "Sonic Robo Blast 2");
|
|
||||||
D_MakeTitleString(srb2);
|
|
||||||
|
|
||||||
#ifdef PC_DOS
|
#ifdef PC_DOS
|
||||||
D_Titlebar(srb2, title);
|
D_Titlebar();
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined (__OS2__) && !defined (HAVE_SDL)
|
|
||||||
// set PM window title
|
|
||||||
snprintf(pmData->title, sizeof (pmData->title),
|
|
||||||
"Sonic Robo Blast 2" VERSIONSTRING ": %s",
|
|
||||||
title);
|
|
||||||
pmData->title[sizeof (pmData->title) - 1] = '\0';
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (devparm)
|
if (devparm)
|
||||||
|
@ -1399,7 +1390,6 @@ void D_SRB2Main(void)
|
||||||
|
|
||||||
if (dedicated && server)
|
if (dedicated && server)
|
||||||
{
|
{
|
||||||
pagename = "TITLESKY";
|
|
||||||
levelstarttic = gametic;
|
levelstarttic = gametic;
|
||||||
G_SetGamestate(GS_LEVEL);
|
G_SetGamestate(GS_LEVEL);
|
||||||
if (!P_SetupLevel(false))
|
if (!P_SetupLevel(false))
|
||||||
|
|
|
@ -713,6 +713,13 @@ void Net_CloseConnection(INT32 node)
|
||||||
#else
|
#else
|
||||||
INT32 i;
|
INT32 i;
|
||||||
boolean forceclose = (node & FORCECLOSE) != 0;
|
boolean forceclose = (node & FORCECLOSE) != 0;
|
||||||
|
|
||||||
|
if (node == -1)
|
||||||
|
{
|
||||||
|
DEBFILE(M_GetText("Net_CloseConnection: node -1 detected!\n"));
|
||||||
|
return; // nope, just ignore it
|
||||||
|
}
|
||||||
|
|
||||||
node &= ~FORCECLOSE;
|
node &= ~FORCECLOSE;
|
||||||
|
|
||||||
if (!node)
|
if (!node)
|
||||||
|
@ -720,7 +727,7 @@ void Net_CloseConnection(INT32 node)
|
||||||
|
|
||||||
if (node < 0 || node >= MAXNETNODES) // prevent invalid nodes from crashing the game
|
if (node < 0 || node >= MAXNETNODES) // prevent invalid nodes from crashing the game
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Net_CloseConnection: invalid node %d detected!\n"), node);
|
DEBFILE(va(M_GetText("Net_CloseConnection: invalid node %d detected!\n"), node));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1609,8 +1609,13 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese
|
||||||
mapchangepending = 0;
|
mapchangepending = 0;
|
||||||
// spawn the server if needed
|
// spawn the server if needed
|
||||||
// reset players if there is a new one
|
// reset players if there is a new one
|
||||||
if (!(adminplayer == consoleplayer) && SV_SpawnServer())
|
if (!(adminplayer == consoleplayer))
|
||||||
buf[0] &= ~(1<<1);
|
{
|
||||||
|
if (SV_SpawnServer())
|
||||||
|
buf[0] &= ~(1<<1);
|
||||||
|
if (!Playing()) // you failed to start a server somehow, so cancel the map change
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Kick bot from special stages
|
// Kick bot from special stages
|
||||||
if (botskin)
|
if (botskin)
|
||||||
|
@ -3116,7 +3121,13 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
|
||||||
filestatus_t ncs = FS_NOTFOUND;
|
filestatus_t ncs = FS_NOTFOUND;
|
||||||
UINT8 md5sum[16];
|
UINT8 md5sum[16];
|
||||||
boolean kick = false;
|
boolean kick = false;
|
||||||
|
boolean toomany = false;
|
||||||
INT32 i;
|
INT32 i;
|
||||||
|
size_t packetsize = 0;
|
||||||
|
serverinfo_pak *dummycheck = NULL;
|
||||||
|
|
||||||
|
// Shut the compiler up.
|
||||||
|
(void)dummycheck;
|
||||||
|
|
||||||
READSTRINGN(*cp, filename, 240);
|
READSTRINGN(*cp, filename, 240);
|
||||||
READMEM(*cp, md5sum, 16);
|
READMEM(*cp, md5sum, 16);
|
||||||
|
@ -3142,13 +3153,25 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ncs = findfile(filename,md5sum,true);
|
// See W_LoadWadFile in w_wad.c
|
||||||
|
for (i = 0; i < numwadfiles; i++)
|
||||||
|
packetsize += nameonlylength(wadfiles[i]->filename) + 22;
|
||||||
|
|
||||||
if (ncs != FS_FOUND)
|
packetsize += nameonlylength(filename) + 22;
|
||||||
|
|
||||||
|
if ((numwadfiles >= MAX_WADFILES)
|
||||||
|
|| (packetsize > sizeof(dummycheck->fileneeded)))
|
||||||
|
toomany = true;
|
||||||
|
else
|
||||||
|
ncs = findfile(filename,md5sum,true);
|
||||||
|
|
||||||
|
if (ncs != FS_FOUND || toomany)
|
||||||
{
|
{
|
||||||
char message[256];
|
char message[256];
|
||||||
|
|
||||||
if (ncs == FS_NOTFOUND)
|
if (toomany)
|
||||||
|
sprintf(message, M_GetText("Too many files loaded to add %s\n"), filename);
|
||||||
|
else if (ncs == FS_NOTFOUND)
|
||||||
sprintf(message, M_GetText("The server doesn't have %s\n"), filename);
|
sprintf(message, M_GetText("The server doesn't have %s\n"), filename);
|
||||||
else if (ncs == FS_MD5SUMBAD)
|
else if (ncs == FS_MD5SUMBAD)
|
||||||
sprintf(message, M_GetText("Checksum mismatch on %s\n"), filename);
|
sprintf(message, M_GetText("Checksum mismatch on %s\n"), filename);
|
||||||
|
@ -3218,10 +3241,15 @@ static void Got_Addfilecmd(UINT8 **cp, INT32 playernum)
|
||||||
|
|
||||||
ncs = findfile(filename,md5sum,true);
|
ncs = findfile(filename,md5sum,true);
|
||||||
|
|
||||||
if (ncs != FS_FOUND)
|
if (ncs != FS_FOUND || !P_AddWadFile(filename, NULL))
|
||||||
{
|
{
|
||||||
Command_ExitGame_f();
|
Command_ExitGame_f();
|
||||||
if (ncs == FS_NOTFOUND)
|
if (ncs == FS_FOUND)
|
||||||
|
{
|
||||||
|
CONS_Printf(M_GetText("The server tried to add %s,\nbut you have too many files added.\nRestart the game to clear loaded files\nand play on this server."), filename);
|
||||||
|
M_StartMessage(va("The server added a file \n(%s)\nbut you have too many files added.\nRestart the game to clear loaded files.\n\nPress ESC\n",filename), NULL, MM_NOTHING);
|
||||||
|
}
|
||||||
|
else if (ncs == FS_NOTFOUND)
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("The server tried to add %s,\nbut you don't have this file.\nYou need to find it in order\nto play on this server."), filename);
|
CONS_Printf(M_GetText("The server tried to add %s,\nbut you don't have this file.\nYou need to find it in order\nto play on this server."), filename);
|
||||||
M_StartMessage(va("The server added a file \n(%s)\nthat you do not have.\n\nPress ESC\n",filename), NULL, MM_NOTHING);
|
M_StartMessage(va("The server added a file \n(%s)\nthat you do not have.\n\nPress ESC\n",filename), NULL, MM_NOTHING);
|
||||||
|
@ -3239,7 +3267,6 @@ static void Got_Addfilecmd(UINT8 **cp, INT32 playernum)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
P_AddWadFile(filename, NULL);
|
|
||||||
G_SetGameModified(true);
|
G_SetGameModified(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,8 @@
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid);
|
// Prototypes
|
||||||
|
static boolean SV_SendFile(INT32 node, const char *filename, UINT8 fileid);
|
||||||
|
|
||||||
// Sender structure
|
// Sender structure
|
||||||
typedef struct filetx_s
|
typedef struct filetx_s
|
||||||
|
@ -303,7 +304,8 @@ boolean CL_SendRequestFile(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// get request filepak and put it on the send queue
|
// get request filepak and put it on the send queue
|
||||||
void Got_RequestFilePak(INT32 node)
|
// returns false if a requested file was not found or cannot be sent
|
||||||
|
boolean Got_RequestFilePak(INT32 node)
|
||||||
{
|
{
|
||||||
char wad[MAX_WADPATH+1];
|
char wad[MAX_WADPATH+1];
|
||||||
UINT8 *p = netbuffer->u.textcmd;
|
UINT8 *p = netbuffer->u.textcmd;
|
||||||
|
@ -314,8 +316,13 @@ void Got_RequestFilePak(INT32 node)
|
||||||
if (id == 0xFF)
|
if (id == 0xFF)
|
||||||
break;
|
break;
|
||||||
READSTRINGN(p, wad, MAX_WADPATH);
|
READSTRINGN(p, wad, MAX_WADPATH);
|
||||||
SV_SendFile(node, wad, id);
|
if (!SV_SendFile(node, wad, id))
|
||||||
|
{
|
||||||
|
SV_AbortSendFiles(node);
|
||||||
|
return false; // don't read the rest of the files
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return true; // no problems with any files
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Checks if the files needed aren't already loaded or on the disk
|
/** Checks if the files needed aren't already loaded or on the disk
|
||||||
|
@ -330,6 +337,12 @@ INT32 CL_CheckFiles(void)
|
||||||
INT32 i, j;
|
INT32 i, j;
|
||||||
char wadfilename[MAX_WADPATH];
|
char wadfilename[MAX_WADPATH];
|
||||||
INT32 ret = 1;
|
INT32 ret = 1;
|
||||||
|
size_t packetsize = 0;
|
||||||
|
size_t filestoget = 0;
|
||||||
|
serverinfo_pak *dummycheck = NULL;
|
||||||
|
|
||||||
|
// Shut the compiler up.
|
||||||
|
(void)dummycheck;
|
||||||
|
|
||||||
// if (M_CheckParm("-nofiles"))
|
// if (M_CheckParm("-nofiles"))
|
||||||
// return 1;
|
// return 1;
|
||||||
|
@ -378,6 +391,10 @@ INT32 CL_CheckFiles(void)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See W_LoadWadFile in w_wad.c
|
||||||
|
for (i = 0; i < numwadfiles; i++)
|
||||||
|
packetsize += nameonlylength(wadfiles[i]->filename) + 22;
|
||||||
|
|
||||||
for (i = 1; i < fileneedednum; i++)
|
for (i = 1; i < fileneedednum; i++)
|
||||||
{
|
{
|
||||||
CONS_Debug(DBG_NETPLAY, "searching for '%s' ", fileneeded[i].filename);
|
CONS_Debug(DBG_NETPLAY, "searching for '%s' ", fileneeded[i].filename);
|
||||||
|
@ -397,6 +414,14 @@ INT32 CL_CheckFiles(void)
|
||||||
if (fileneeded[i].status != FS_NOTFOUND || !fileneeded[i].important)
|
if (fileneeded[i].status != FS_NOTFOUND || !fileneeded[i].important)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
packetsize += nameonlylength(fileneeded[i].filename) + 22;
|
||||||
|
|
||||||
|
if ((numwadfiles+filestoget >= MAX_WADFILES)
|
||||||
|
|| (packetsize > sizeof(dummycheck->fileneeded)))
|
||||||
|
return 3;
|
||||||
|
|
||||||
|
filestoget++;
|
||||||
|
|
||||||
fileneeded[i].status = findfile(fileneeded[i].filename, fileneeded[i].md5sum, true);
|
fileneeded[i].status = findfile(fileneeded[i].filename, fileneeded[i].md5sum, true);
|
||||||
CONS_Debug(DBG_NETPLAY, "found %d\n", fileneeded[i].status);
|
CONS_Debug(DBG_NETPLAY, "found %d\n", fileneeded[i].status);
|
||||||
if (fileneeded[i].status != FS_FOUND)
|
if (fileneeded[i].status != FS_FOUND)
|
||||||
|
@ -480,7 +505,7 @@ static INT32 filestosend = 0;
|
||||||
* \sa SV_SendRam
|
* \sa SV_SendRam
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
|
static boolean SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
|
||||||
{
|
{
|
||||||
filetx_t **q; // A pointer to the "next" field of the last file in the list
|
filetx_t **q; // A pointer to the "next" field of the last file in the list
|
||||||
filetx_t *p; // The new file request
|
filetx_t *p; // The new file request
|
||||||
|
@ -488,7 +513,7 @@ static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
|
||||||
char wadfilename[MAX_WADPATH];
|
char wadfilename[MAX_WADPATH];
|
||||||
|
|
||||||
if (cv_noticedownload.value)
|
if (cv_noticedownload.value)
|
||||||
CONS_Printf("Sending file \"%s\" to node %d\n", filename, node);
|
CONS_Printf("Sending file \"%s\" to node %d (%s)\n", filename, node, I_GetNodeAddress(node));
|
||||||
|
|
||||||
// Find the last file in the list and set a pointer to its "next" field
|
// Find the last file in the list and set a pointer to its "next" field
|
||||||
q = &transfer[node].txlist;
|
q = &transfer[node].txlist;
|
||||||
|
@ -537,7 +562,7 @@ static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
|
||||||
free(p->id.filename);
|
free(p->id.filename);
|
||||||
free(p);
|
free(p);
|
||||||
*q = NULL;
|
*q = NULL;
|
||||||
return;
|
return false; // cancel the rest of the requests
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle huge file requests (i.e. bigger than cv_maxsend.value KB)
|
// Handle huge file requests (i.e. bigger than cv_maxsend.value KB)
|
||||||
|
@ -549,7 +574,7 @@ static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
|
||||||
free(p->id.filename);
|
free(p->id.filename);
|
||||||
free(p);
|
free(p);
|
||||||
*q = NULL;
|
*q = NULL;
|
||||||
return;
|
return false; // cancel the rest of the requests
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBFILE(va("Sending file %s (id=%d) to %d\n", filename, fileid, node));
|
DEBFILE(va("Sending file %s (id=%d) to %d\n", filename, fileid, node));
|
||||||
|
@ -557,6 +582,7 @@ static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
|
||||||
p->fileid = fileid;
|
p->fileid = fileid;
|
||||||
p->next = NULL; // End of list
|
p->next = NULL; // End of list
|
||||||
filestosend++;
|
filestosend++;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adds a memory block to the file list for a node
|
/** Adds a memory block to the file list for a node
|
||||||
|
|
|
@ -69,7 +69,7 @@ boolean SV_SendingFile(INT32 node);
|
||||||
|
|
||||||
boolean CL_CheckDownloadable(void);
|
boolean CL_CheckDownloadable(void);
|
||||||
boolean CL_SendRequestFile(void);
|
boolean CL_SendRequestFile(void);
|
||||||
void Got_RequestFilePak(INT32 node);
|
boolean Got_RequestFilePak(INT32 node);
|
||||||
|
|
||||||
void SV_AbortSendFiles(INT32 node);
|
void SV_AbortSendFiles(INT32 node);
|
||||||
void CloseNetFile(void);
|
void CloseNetFile(void);
|
||||||
|
|
339
src/dehacked.c
339
src/dehacked.c
|
@ -382,56 +382,6 @@ static void clear_levels(void)
|
||||||
P_AllocMapHeader(gamemap-1);
|
P_AllocMapHeader(gamemap-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// Edits an animated texture slot on the array
|
|
||||||
// Tails 12-27-2003
|
|
||||||
static void readAnimTex(MYFILE *f, INT32 num)
|
|
||||||
{
|
|
||||||
char s[MAXLINELEN];
|
|
||||||
char *word;
|
|
||||||
char *word2;
|
|
||||||
INT32 i;
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (myfgets(s, sizeof s, f) != NULL)
|
|
||||||
{
|
|
||||||
if (s[0] == '\n') break;
|
|
||||||
|
|
||||||
tmp = strchr(s, '#');
|
|
||||||
if (tmp)
|
|
||||||
*tmp = '\0';
|
|
||||||
// set the value in the appropriate field
|
|
||||||
|
|
||||||
word = strtok(s, " ");
|
|
||||||
if (word)
|
|
||||||
strupr(word);
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
|
|
||||||
word2 = strtok(NULL, " = ");
|
|
||||||
if (word2)
|
|
||||||
strupr(word2);
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (word2[strlen(word2)-1] == '\n')
|
|
||||||
word2[strlen(word2)-1] = '\0';
|
|
||||||
|
|
||||||
i = atoi(word2);
|
|
||||||
|
|
||||||
if (fastcmp(word, "START"))
|
|
||||||
strncpy(harddefs[num].startname, word2, 8);
|
|
||||||
if (fastcmp(word, "END"))
|
|
||||||
strncpy(harddefs[num].endname, word2, 8);
|
|
||||||
else if (fastcmp(word, "SPEED")) harddefs[num].speed = i;
|
|
||||||
else if (fastcmp(word, "ISTEXTURE")) harddefs[num].istexture = i;
|
|
||||||
|
|
||||||
else deh_warning("readAnimTex %d: unknown word '%s'", num, word);
|
|
||||||
}
|
|
||||||
} while (s[0] != '\n' && !myfeof(f)); //finish when the line is empty
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
static boolean findFreeSlot(INT32 *num)
|
static boolean findFreeSlot(INT32 *num)
|
||||||
{
|
{
|
||||||
// Send the character select entry to a free slot.
|
// Send the character select entry to a free slot.
|
||||||
|
@ -2106,7 +2056,7 @@ static void readframe(MYFILE *f, INT32 num)
|
||||||
Z_Free(s);
|
Z_Free(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void readsound(MYFILE *f, INT32 num, const char *savesfxnames[])
|
static void readsound(MYFILE *f, INT32 num)
|
||||||
{
|
{
|
||||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||||
char *word;
|
char *word;
|
||||||
|
@ -2142,21 +2092,7 @@ static void readsound(MYFILE *f, INT32 num, const char *savesfxnames[])
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if (fastcmp(word, "OFFSET"))
|
if (fastcmp(word, "SINGULAR"))
|
||||||
{
|
|
||||||
value -= 150360;
|
|
||||||
if (value <= 64)
|
|
||||||
value /= 8;
|
|
||||||
else if (value <= 260)
|
|
||||||
value = (value+4)/8;
|
|
||||||
else
|
|
||||||
value = (value+8)/8;
|
|
||||||
if (value >= -1 && value < sfx_freeslot0 - 1)
|
|
||||||
S_sfx[num].name = savesfxnames[value+1];
|
|
||||||
else
|
|
||||||
deh_warning("Sound %d: offset out of bounds", num);
|
|
||||||
}
|
|
||||||
else */if (fastcmp(word, "SINGULAR"))
|
|
||||||
{
|
{
|
||||||
DEH_WriteUndoline(word, va("%d", S_sfx[num].singularity), UNDO_NONE);
|
DEH_WriteUndoline(word, va("%d", S_sfx[num].singularity), UNDO_NONE);
|
||||||
S_sfx[num].singularity = value;
|
S_sfx[num].singularity = value;
|
||||||
|
@ -2182,8 +2118,6 @@ static void readsound(MYFILE *f, INT32 num, const char *savesfxnames[])
|
||||||
} while (!myfeof(f));
|
} while (!myfeof(f));
|
||||||
|
|
||||||
Z_Free(s);
|
Z_Free(s);
|
||||||
|
|
||||||
(void)savesfxnames;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Checks if a game data file name for a mod is good.
|
/** Checks if a game data file name for a mod is good.
|
||||||
|
@ -2811,190 +2745,6 @@ static void readconditionset(MYFILE *f, UINT8 setnum)
|
||||||
Z_Free(s);
|
Z_Free(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void readtexture(MYFILE *f, const char *name)
|
|
||||||
{
|
|
||||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
|
||||||
char *word;
|
|
||||||
char *word2;
|
|
||||||
char *tmp;
|
|
||||||
INT32 i, j, value;
|
|
||||||
UINT16 width = 0, height = 0;
|
|
||||||
INT16 patchcount = 0;
|
|
||||||
texture_t *texture;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (myfgets(s, MAXLINELEN, f))
|
|
||||||
{
|
|
||||||
if (s[0] == '\n')
|
|
||||||
break;
|
|
||||||
|
|
||||||
tmp = strchr(s, '#');
|
|
||||||
if (tmp)
|
|
||||||
*tmp = '\0';
|
|
||||||
|
|
||||||
value = searchvalue(s);
|
|
||||||
word = strtok(s, " ");
|
|
||||||
if (word)
|
|
||||||
strupr(word);
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
|
|
||||||
word2 = strtok(NULL, " ");
|
|
||||||
if (word2)
|
|
||||||
strupr(word2);
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Width of the texture.
|
|
||||||
if (fastcmp(word, "WIDTH"))
|
|
||||||
{
|
|
||||||
DEH_WriteUndoline(word, va("%d", width), UNDO_NONE);
|
|
||||||
width = SHORT((UINT16)value);
|
|
||||||
}
|
|
||||||
// Height of the texture.
|
|
||||||
else if (fastcmp(word, "HEIGHT"))
|
|
||||||
{
|
|
||||||
DEH_WriteUndoline(word, va("%d", height), UNDO_NONE);
|
|
||||||
height = SHORT((UINT16)value);
|
|
||||||
}
|
|
||||||
// Number of patches the texture has.
|
|
||||||
else if (fastcmp(word, "NUMPATCHES"))
|
|
||||||
{
|
|
||||||
DEH_WriteUndoline(word, va("%d", patchcount), UNDO_NONE);
|
|
||||||
patchcount = SHORT((UINT16)value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
deh_warning("readtexture: unknown word '%s'", word);
|
|
||||||
}
|
|
||||||
} while (!myfeof(f));
|
|
||||||
|
|
||||||
// Error checking.
|
|
||||||
if (!width)
|
|
||||||
I_Error("Texture %s has no width!\n", name);
|
|
||||||
|
|
||||||
if (!height)
|
|
||||||
I_Error("Texture %s has no height!\n", name);
|
|
||||||
|
|
||||||
if (!patchcount)
|
|
||||||
I_Error("Texture %s has no patches!\n", name);
|
|
||||||
|
|
||||||
// Allocate memory for the texture, and fill in information.
|
|
||||||
texture = Z_Calloc(sizeof(texture_t) + (sizeof(texpatch_t) * SHORT(patchcount)), PU_STATIC, NULL);
|
|
||||||
M_Memcpy(texture->name, name, sizeof(texture->name));
|
|
||||||
texture->width = width;
|
|
||||||
texture->height = height;
|
|
||||||
texture->patchcount = patchcount;
|
|
||||||
texture->holes = false;
|
|
||||||
// Fill out the texture patches, to allow them to be detected
|
|
||||||
// accurately by readpatch.
|
|
||||||
for (i = 0; i < patchcount; i++)
|
|
||||||
{
|
|
||||||
texture->patches[i].originx = 0;
|
|
||||||
texture->patches[i].originy = 0;
|
|
||||||
texture->patches[i].wad = UINT16_MAX;
|
|
||||||
texture->patches[i].lump = UINT16_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Jump to the next empty texture entry.
|
|
||||||
i = 0;
|
|
||||||
while (textures[i])
|
|
||||||
i++;
|
|
||||||
|
|
||||||
// Fill the global texture buffer entries.
|
|
||||||
j = 1;
|
|
||||||
while (j << 1 <= texture->width)
|
|
||||||
j <<= 1;
|
|
||||||
|
|
||||||
textures[i] = texture;
|
|
||||||
texturewidthmask[i] = j - 1;
|
|
||||||
textureheight[i] = texture->height << FRACBITS;
|
|
||||||
|
|
||||||
// Clean up.
|
|
||||||
Z_Free(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void readpatch(MYFILE *f, const char *name, UINT16 wad)
|
|
||||||
{
|
|
||||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
|
||||||
char *word;
|
|
||||||
char *word2;
|
|
||||||
char *tmp;
|
|
||||||
INT32 i = 0, j = 0, value;
|
|
||||||
texpatch_t patch = {0, 0, UINT16_MAX, UINT16_MAX, 0, 255, AST_COPY};
|
|
||||||
|
|
||||||
// Jump to the texture this patch belongs to, which,
|
|
||||||
// coincidentally, is always the last one on the buffer cache.
|
|
||||||
while (textures[i+1])
|
|
||||||
i++;
|
|
||||||
|
|
||||||
// Jump to the next empty patch entry.
|
|
||||||
while (memcmp(&(textures[i]->patches[j]), &patch, sizeof(patch)))
|
|
||||||
j++;
|
|
||||||
|
|
||||||
patch.wad = wad;
|
|
||||||
// Set the texture number, but only if the lump exists.
|
|
||||||
if ((patch.lump = W_CheckNumForNamePwad(name, wad, 0)) == INT16_MAX)
|
|
||||||
I_Error("readpatch: Missing patch in texture %s", textures[i]->name);
|
|
||||||
|
|
||||||
// note: undoing this patch will be done by other means
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (myfgets(s, MAXLINELEN, f))
|
|
||||||
{
|
|
||||||
if (s[0] == '\n')
|
|
||||||
break;
|
|
||||||
|
|
||||||
tmp = strchr(s, '#');
|
|
||||||
if (tmp)
|
|
||||||
*tmp = '\0';
|
|
||||||
|
|
||||||
value = searchvalue(s);
|
|
||||||
word = strtok(s, " ");
|
|
||||||
if (word)
|
|
||||||
strupr(word);
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
|
|
||||||
word2 = strtok(NULL, " ");
|
|
||||||
if (word2)
|
|
||||||
strupr(word2);
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
|
|
||||||
// X position of the patch in the texture.
|
|
||||||
if (fastcmp(word, "X"))
|
|
||||||
{
|
|
||||||
//DEH_WriteUndoline(word, va("%d", patch->originx), UNDO_NONE);
|
|
||||||
patch.originx = (INT16)value;
|
|
||||||
}
|
|
||||||
// Y position of the patch in the texture.
|
|
||||||
else if (fastcmp(word, "Y"))
|
|
||||||
{
|
|
||||||
//DEH_WriteUndoline(word, va("%d", patch->originy), UNDO_NONE);
|
|
||||||
patch.originy = (INT16)value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
deh_warning("readpatch: unknown word '%s'", word);
|
|
||||||
}
|
|
||||||
} while (!myfeof(f));
|
|
||||||
|
|
||||||
// Error checking.
|
|
||||||
/* // Irrelevant. Origins cannot be unsigned.
|
|
||||||
if (patch.originx == UINT16_MAX)
|
|
||||||
I_Error("Patch %s on texture %s has no X position!\n", name, textures[i]->name);
|
|
||||||
|
|
||||||
if (patch.originy == UINT16_MAX)
|
|
||||||
I_Error("Patch %s on texture %s has no Y position!\n", name, textures[i]->name);
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Set the patch as that patch number.
|
|
||||||
textures[i]->patches[j] = patch;
|
|
||||||
|
|
||||||
// Clean up.
|
|
||||||
Z_Free(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void readmaincfg(MYFILE *f)
|
static void readmaincfg(MYFILE *f)
|
||||||
{
|
{
|
||||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||||
|
@ -3405,30 +3155,17 @@ static void ignorelines(MYFILE *f)
|
||||||
Z_Free(s);
|
Z_Free(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
static void DEH_LoadDehackedFile(MYFILE *f)
|
||||||
{
|
{
|
||||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||||
char *word;
|
char *word;
|
||||||
char *word2;
|
char *word2;
|
||||||
INT32 i;
|
INT32 i;
|
||||||
// do a copy of this for cross references probleme
|
|
||||||
//XBOXSTATIC actionf_t saveactions[NUMSTATES];
|
|
||||||
//XBOXSTATIC const char *savesprnames[NUMSPRITES];
|
|
||||||
XBOXSTATIC const char *savesfxnames[NUMSFX];
|
|
||||||
|
|
||||||
if (!deh_loaded)
|
if (!deh_loaded)
|
||||||
initfreeslots();
|
initfreeslots();
|
||||||
|
|
||||||
deh_num_warning = 0;
|
deh_num_warning = 0;
|
||||||
// save values for cross reference
|
|
||||||
/*
|
|
||||||
for (i = 0; i < NUMSTATES; i++)
|
|
||||||
saveactions[i] = states[i].action;
|
|
||||||
for (i = 0; i < NUMSPRITES; i++)
|
|
||||||
savesprnames[i] = sprnames[i];
|
|
||||||
*/
|
|
||||||
for (i = 0; i < NUMSFX; i++)
|
|
||||||
savesfxnames[i] = S_sfx[i].name;
|
|
||||||
|
|
||||||
gamedataadded = false;
|
gamedataadded = false;
|
||||||
|
|
||||||
|
@ -3505,19 +3242,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
if (word2[strlen(word2)-1] == '\n')
|
if (word2[strlen(word2)-1] == '\n')
|
||||||
word2[strlen(word2)-1] = '\0';
|
word2[strlen(word2)-1] = '\0';
|
||||||
i = atoi(word2);
|
i = atoi(word2);
|
||||||
if (fastcmp(word, "TEXTURE"))
|
if (fastcmp(word, "THING") || fastcmp(word, "MOBJ") || fastcmp(word, "OBJECT"))
|
||||||
{
|
|
||||||
// Read texture from spec file.
|
|
||||||
readtexture(f, word2);
|
|
||||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
|
||||||
}
|
|
||||||
else if (fastcmp(word, "PATCH"))
|
|
||||||
{
|
|
||||||
// Read patch from spec file.
|
|
||||||
readpatch(f, word2, wad);
|
|
||||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
|
||||||
}
|
|
||||||
else if (fastcmp(word, "THING") || fastcmp(word, "MOBJ") || fastcmp(word, "OBJECT"))
|
|
||||||
{
|
{
|
||||||
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
||||||
i = get_mobjtype(word2); // find a thing by name
|
i = get_mobjtype(word2); // find a thing by name
|
||||||
|
@ -3530,10 +3255,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
}
|
}
|
||||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||||
}
|
}
|
||||||
/* else if (fastcmp(word, "ANIMTEX"))
|
|
||||||
{
|
|
||||||
readAnimTex(f, i);
|
|
||||||
}*/
|
|
||||||
else if (fastcmp(word, "LIGHT"))
|
else if (fastcmp(word, "LIGHT"))
|
||||||
{
|
{
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
|
@ -3605,34 +3326,12 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
}
|
}
|
||||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||||
}
|
}
|
||||||
// <Callum> Added translations to this just in case its re-enabled
|
|
||||||
/* else if (fastcmp(word, "POINTER"))
|
|
||||||
{
|
|
||||||
word = strtok(NULL, " "); // get frame
|
|
||||||
word = strtok(NULL, ")");
|
|
||||||
if (word)
|
|
||||||
{
|
|
||||||
i = atoi(word);
|
|
||||||
if (i < NUMSTATES && i >= 0)
|
|
||||||
{
|
|
||||||
if (myfgets(s, MAXLINELEN, f))
|
|
||||||
states[i].action = saveactions[searchvalue(s)];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
deh_warning("Pointer: Frame %d doesn't exist", i);
|
|
||||||
ignorelines(f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
deh_warning("pointer (Frame %d) : missing ')'", i);
|
|
||||||
}*/
|
|
||||||
else if (fastcmp(word, "SOUND"))
|
else if (fastcmp(word, "SOUND"))
|
||||||
{
|
{
|
||||||
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
||||||
i = get_sfx(word2); // find a sound by name
|
i = get_sfx(word2); // find a sound by name
|
||||||
if (i < NUMSFX && i > 0)
|
if (i < NUMSFX && i > 0)
|
||||||
readsound(f, i, savesfxnames);
|
readsound(f, i);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
deh_warning("Sound %d out of range (1 - %d)", i, NUMSFX-1);
|
deh_warning("Sound %d out of range (1 - %d)", i, NUMSFX-1);
|
||||||
|
@ -3640,26 +3339,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
}
|
}
|
||||||
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||||
}
|
}
|
||||||
/* else if (fastcmp(word, "SPRITE"))
|
|
||||||
{
|
|
||||||
if (i < NUMSPRITES && i >= 0)
|
|
||||||
{
|
|
||||||
if (myfgets(s, MAXLINELEN, f))
|
|
||||||
{
|
|
||||||
INT32 k;
|
|
||||||
k = (searchvalue(s) - 151328)/8;
|
|
||||||
if (k >= 0 && k < NUMSPRITES)
|
|
||||||
sprnames[i] = savesprnames[k];
|
|
||||||
else
|
|
||||||
{
|
|
||||||
deh_warning("Sprite %d: offset out of bounds", i);
|
|
||||||
ignorelines(f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
deh_warning("Sprite %d doesn't exist",i);
|
|
||||||
}*/
|
|
||||||
else if (fastcmp(word, "HUDITEM"))
|
else if (fastcmp(word, "HUDITEM"))
|
||||||
{
|
{
|
||||||
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
||||||
|
@ -3746,7 +3425,10 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
// no undo support for this insanity yet
|
// no undo support for this insanity yet
|
||||||
//DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
//DEH_WriteUndoline(word, word2, UNDO_HEADER);
|
||||||
}
|
}
|
||||||
else if (fastcmp(word, "SRB2"))
|
// Last I heard this crashes the game if you try to use it
|
||||||
|
// so this is disabled for now
|
||||||
|
// -- Monster Iestyn
|
||||||
|
/* else if (fastcmp(word, "SRB2"))
|
||||||
{
|
{
|
||||||
INT32 ver = searchvalue(strtok(NULL, "\n"));
|
INT32 ver = searchvalue(strtok(NULL, "\n"));
|
||||||
if (ver != PATCHVERSION)
|
if (ver != PATCHVERSION)
|
||||||
|
@ -3757,6 +3439,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
|
||||||
// Unless you REALLY want to piss people off,
|
// Unless you REALLY want to piss people off,
|
||||||
// define a custom gamedata /before/ doing this!!
|
// define a custom gamedata /before/ doing this!!
|
||||||
// (then again, modifiedgame will prevent game data saving anyway)
|
// (then again, modifiedgame will prevent game data saving anyway)
|
||||||
|
*/
|
||||||
else if (fastcmp(word, "CLEAR"))
|
else if (fastcmp(word, "CLEAR"))
|
||||||
{
|
{
|
||||||
boolean clearall = (fastcmp(word2, "ALL"));
|
boolean clearall = (fastcmp(word2, "ALL"));
|
||||||
|
@ -3830,7 +3513,7 @@ void DEH_LoadDehackedLumpPwad(UINT16 wad, UINT16 lump)
|
||||||
W_ReadLumpPwad(wad, lump, f.data);
|
W_ReadLumpPwad(wad, lump, f.data);
|
||||||
f.curpos = f.data;
|
f.curpos = f.data;
|
||||||
f.data[f.size] = 0;
|
f.data[f.size] = 0;
|
||||||
DEH_LoadDehackedFile(&f, wad);
|
DEH_LoadDehackedFile(&f);
|
||||||
DEH_WriteUndoline(va("# uload for wad: %u, lump: %u", wad, lump), NULL, UNDO_DONE);
|
DEH_WriteUndoline(va("# uload for wad: %u, lump: %u", wad, lump), NULL, UNDO_DONE);
|
||||||
Z_Free(f.data);
|
Z_Free(f.data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,7 +214,7 @@ extern FILE *logstream;
|
||||||
// it's only for detection of the version the player is using so the MS can alert them of an update.
|
// it's only for detection of the version the player is using so the MS can alert them of an update.
|
||||||
// Only set it higher, not lower, obviously.
|
// Only set it higher, not lower, obviously.
|
||||||
// Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1".
|
// Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1".
|
||||||
#define MODVERSION 23
|
#define MODVERSION 24
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
||||||
|
@ -546,4 +546,8 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
|
||||||
/// Hudname padding.
|
/// Hudname padding.
|
||||||
#define SKINNAMEPADDING
|
#define SKINNAMEPADDING
|
||||||
|
|
||||||
|
/// Handle touching sector specials in P_PlayerAfterThink instead of P_PlayerThink.
|
||||||
|
/// \note Required for proper collision with moving sloped surfaces that have sector specials on them.
|
||||||
|
//#define SECTORSPECIALSAFTERTHINK
|
||||||
|
|
||||||
#endif // __DOOMDEF__
|
#endif // __DOOMDEF__
|
||||||
|
|
|
@ -1723,7 +1723,7 @@ static void F_AdvanceToNextScene(void)
|
||||||
|
|
||||||
void F_EndCutScene(void)
|
void F_EndCutScene(void)
|
||||||
{
|
{
|
||||||
cutsceneover = true; // do this first, just in case Y_EndGame or something wants to turn it back false later
|
cutsceneover = true; // do this first, just in case G_EndGame or something wants to turn it back false later
|
||||||
if (runningprecutscene)
|
if (runningprecutscene)
|
||||||
{
|
{
|
||||||
if (server)
|
if (server)
|
||||||
|
@ -1738,7 +1738,7 @@ void F_EndCutScene(void)
|
||||||
else if (nextmap < 1100-1)
|
else if (nextmap < 1100-1)
|
||||||
G_NextLevel();
|
G_NextLevel();
|
||||||
else
|
else
|
||||||
Y_EndGame();
|
G_EndGame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
41
src/g_game.c
41
src/g_game.c
|
@ -2309,6 +2309,9 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost)
|
||||||
if (starpost) //Don't even bother with looking for a place to spawn.
|
if (starpost) //Don't even bother with looking for a place to spawn.
|
||||||
{
|
{
|
||||||
P_MovePlayerToStarpost(playernum);
|
P_MovePlayerToStarpost(playernum);
|
||||||
|
#ifdef HAVE_BLUA
|
||||||
|
LUAh_PlayerSpawn(&players[playernum]); // Lua hook for player spawning :)
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2633,7 +2636,7 @@ void G_ExitLevel(void)
|
||||||
CONS_Printf(M_GetText("The round has ended.\n"));
|
CONS_Printf(M_GetText("The round has ended.\n"));
|
||||||
|
|
||||||
// Remove CEcho text on round end.
|
// Remove CEcho text on round end.
|
||||||
HU_DoCEcho("");
|
HU_ClearCEcho();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2927,7 +2930,7 @@ void G_AfterIntermission(void)
|
||||||
if (nextmap < 1100-1)
|
if (nextmap < 1100-1)
|
||||||
G_NextLevel();
|
G_NextLevel();
|
||||||
else
|
else
|
||||||
Y_EndGame();
|
G_EndGame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3013,6 +3016,38 @@ static void G_DoContinued(void)
|
||||||
gameaction = ga_nothing;
|
gameaction = ga_nothing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// G_EndGame (formerly Y_EndGame)
|
||||||
|
// Frankly this function fits better in g_game.c than it does in y_inter.c
|
||||||
|
//
|
||||||
|
// ...Gee, (why) end the game?
|
||||||
|
// Because G_AfterIntermission and F_EndCutscene would
|
||||||
|
// both do this exact same thing *in different ways* otherwise,
|
||||||
|
// which made it so that you could only unlock Ultimate mode
|
||||||
|
// if you had a cutscene after the final level and crap like that.
|
||||||
|
// This function simplifies it so only one place has to be updated
|
||||||
|
// when something new is added.
|
||||||
|
void G_EndGame(void)
|
||||||
|
{
|
||||||
|
// Only do evaluation and credits in coop games.
|
||||||
|
if (gametype == GT_COOP)
|
||||||
|
{
|
||||||
|
if (nextmap == 1102-1) // end game with credits
|
||||||
|
{
|
||||||
|
F_StartCredits();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (nextmap == 1101-1) // end game with evaluation
|
||||||
|
{
|
||||||
|
F_StartGameEvaluation();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1100 or competitive multiplayer, so go back to title screen.
|
||||||
|
D_StartTitle();
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// G_LoadGameSettings
|
// G_LoadGameSettings
|
||||||
//
|
//
|
||||||
|
@ -3898,7 +3933,7 @@ void G_GhostAddColor(ghostcolor_t color)
|
||||||
ghostext.color = (UINT8)color;
|
ghostext.color = (UINT8)color;
|
||||||
}
|
}
|
||||||
|
|
||||||
void G_GhostAddScale(UINT16 scale)
|
void G_GhostAddScale(fixed_t scale)
|
||||||
{
|
{
|
||||||
if (!demorecording || !(demoflags & DF_GHOST))
|
if (!demorecording || !(demoflags & DF_GHOST))
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -142,7 +142,7 @@ void G_GhostAddSpin(void);
|
||||||
void G_GhostAddRev(void);
|
void G_GhostAddRev(void);
|
||||||
void G_GhostAddColor(ghostcolor_t color);
|
void G_GhostAddColor(ghostcolor_t color);
|
||||||
void G_GhostAddFlip(void);
|
void G_GhostAddFlip(void);
|
||||||
void G_GhostAddScale(UINT16 scale);
|
void G_GhostAddScale(fixed_t scale);
|
||||||
void G_GhostAddHit(mobj_t *victim);
|
void G_GhostAddHit(mobj_t *victim);
|
||||||
void G_WriteGhostTic(mobj_t *ghost);
|
void G_WriteGhostTic(mobj_t *ghost);
|
||||||
void G_ConsGhostTic(void);
|
void G_ConsGhostTic(void);
|
||||||
|
@ -174,6 +174,7 @@ void G_NextLevel(void);
|
||||||
void G_Continue(void);
|
void G_Continue(void);
|
||||||
void G_UseContinue(void);
|
void G_UseContinue(void);
|
||||||
void G_AfterIntermission(void);
|
void G_AfterIntermission(void);
|
||||||
|
void G_EndGame(void); // moved from y_inter.c/h and renamed
|
||||||
|
|
||||||
void G_Ticker(boolean run);
|
void G_Ticker(boolean run);
|
||||||
boolean G_Responder(event_t *ev);
|
boolean G_Responder(event_t *ev);
|
||||||
|
|
|
@ -78,6 +78,7 @@ typedef struct gr_vissprite_s
|
||||||
//Hurdler: 25/04/2000: now support colormap in hardware mode
|
//Hurdler: 25/04/2000: now support colormap in hardware mode
|
||||||
UINT8 *colormap;
|
UINT8 *colormap;
|
||||||
INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
|
INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
|
||||||
|
float z1, z2;
|
||||||
} gr_vissprite_t;
|
} gr_vissprite_t;
|
||||||
|
|
||||||
// --------
|
// --------
|
||||||
|
|
|
@ -1084,9 +1084,9 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum,
|
||||||
float endheight = 0.0f, endbheight = 0.0f;
|
float endheight = 0.0f, endbheight = 0.0f;
|
||||||
|
|
||||||
fixed_t v1x = FLOAT_TO_FIXED(wallVerts[0].x);
|
fixed_t v1x = FLOAT_TO_FIXED(wallVerts[0].x);
|
||||||
fixed_t v1y = FLOAT_TO_FIXED(wallVerts[0].y);
|
fixed_t v1y = FLOAT_TO_FIXED(wallVerts[0].z); // not a typo
|
||||||
fixed_t v2x = FLOAT_TO_FIXED(wallVerts[1].x);
|
fixed_t v2x = FLOAT_TO_FIXED(wallVerts[1].x);
|
||||||
fixed_t v2y = FLOAT_TO_FIXED(wallVerts[1].y);
|
fixed_t v2y = FLOAT_TO_FIXED(wallVerts[1].z); // not a typo
|
||||||
// compiler complains when P_GetZAt is used in FLOAT_TO_FIXED directly
|
// compiler complains when P_GetZAt is used in FLOAT_TO_FIXED directly
|
||||||
// use this as a temp var to store P_GetZAt's return value each time
|
// use this as a temp var to store P_GetZAt's return value each time
|
||||||
fixed_t temp;
|
fixed_t temp;
|
||||||
|
@ -3721,6 +3721,9 @@ static void HWR_Subsector(size_t num)
|
||||||
|
|
||||||
while (count--)
|
while (count--)
|
||||||
{
|
{
|
||||||
|
#ifdef POLYOBJECTS
|
||||||
|
if (!line->polyseg) // ignore segs that belong to polyobjects
|
||||||
|
#endif
|
||||||
HWR_AddLine(line);
|
HWR_AddLine(line);
|
||||||
line++;
|
line++;
|
||||||
}
|
}
|
||||||
|
@ -4226,6 +4229,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
|
||||||
GLPatch_t *gpatch; // sprite patch converted to hardware
|
GLPatch_t *gpatch; // sprite patch converted to hardware
|
||||||
FSurfaceInfo Surf;
|
FSurfaceInfo Surf;
|
||||||
const boolean hires = (spr->mobj && spr->mobj->skin && ((skin_t *)spr->mobj->skin)->flags & SF_HIRES);
|
const boolean hires = (spr->mobj && spr->mobj->skin && ((skin_t *)spr->mobj->skin)->flags & SF_HIRES);
|
||||||
|
//const boolean papersprite = (spr->mobj && (spr->mobj->frame & FF_PAPERSPRITE));
|
||||||
if (spr->mobj)
|
if (spr->mobj)
|
||||||
this_scale = FIXED_TO_FLOAT(spr->mobj->scale);
|
this_scale = FIXED_TO_FLOAT(spr->mobj->scale);
|
||||||
if (hires)
|
if (hires)
|
||||||
|
@ -4269,7 +4273,8 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
|
||||||
|
|
||||||
// make a wall polygon (with 2 triangles), using the floor/ceiling heights,
|
// make a wall polygon (with 2 triangles), using the floor/ceiling heights,
|
||||||
// and the 2d map coords of start/end vertices
|
// and the 2d map coords of start/end vertices
|
||||||
wallVerts[0].z = wallVerts[1].z = wallVerts[2].z = wallVerts[3].z = spr->tz;
|
wallVerts[0].z = wallVerts[3].z = spr->z1;
|
||||||
|
wallVerts[2].z = wallVerts[1].z = spr->z2;
|
||||||
|
|
||||||
// transform
|
// transform
|
||||||
wv = wallVerts;
|
wv = wallVerts;
|
||||||
|
@ -5065,6 +5070,10 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||||
|
|
||||||
angle_t ang;
|
angle_t ang;
|
||||||
INT32 heightsec, phs;
|
INT32 heightsec, phs;
|
||||||
|
const boolean papersprite = (thing->frame & FF_PAPERSPRITE);
|
||||||
|
float offset;
|
||||||
|
float ang_scale = 1.0f, ang_scalez = 0.0f;
|
||||||
|
float z1, z2;
|
||||||
|
|
||||||
if (!thing)
|
if (!thing)
|
||||||
return;
|
return;
|
||||||
|
@ -5079,7 +5088,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||||
tz = (tr_x * gr_viewcos) + (tr_y * gr_viewsin);
|
tz = (tr_x * gr_viewcos) + (tr_y * gr_viewsin);
|
||||||
|
|
||||||
// thing is behind view plane?
|
// thing is behind view plane?
|
||||||
if (tz < ZCLIP_PLANE && (!cv_grmd2.value || md2_models[thing->sprite].notfound == true)) //Yellow: Only MD2's dont disappear
|
if (tz < ZCLIP_PLANE && !papersprite && (!cv_grmd2.value || md2_models[thing->sprite].notfound == true)) //Yellow: Only MD2's dont disappear
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tx = (tr_x * gr_viewsin) - (tr_y * gr_viewcos);
|
tx = (tr_x * gr_viewsin) - (tr_y * gr_viewcos);
|
||||||
|
@ -5117,6 +5126,27 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||||
I_Error("sprframes NULL for sprite %d\n", thing->sprite);
|
I_Error("sprframes NULL for sprite %d\n", thing->sprite);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (papersprite)
|
||||||
|
{
|
||||||
|
// Use the actual view angle, rather than the angle formed
|
||||||
|
// between the view point and the thing
|
||||||
|
// this makes sure paper sprites always appear at the right angle!
|
||||||
|
// Note: DO NOT do this in software mode version, it actually
|
||||||
|
// makes papersprites look WORSE there (I know, I've tried)
|
||||||
|
// Monster Iestyn - 13/05/17
|
||||||
|
ang = dup_viewangle - thing->angle;
|
||||||
|
ang_scale = FIXED_TO_FLOAT(FINESINE(ang>>ANGLETOFINESHIFT));
|
||||||
|
ang_scalez = FIXED_TO_FLOAT(FINECOSINE(ang>>ANGLETOFINESHIFT));
|
||||||
|
|
||||||
|
if (ang_scale < 0)
|
||||||
|
{
|
||||||
|
ang_scale = -ang_scale;
|
||||||
|
ang_scalez = -ang_scalez;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (sprframe->rotate != SRF_SINGLE)
|
||||||
|
ang = R_PointToAngle (thing->x, thing->y) - thing->angle;
|
||||||
|
|
||||||
if (sprframe->rotate == SRF_SINGLE)
|
if (sprframe->rotate == SRF_SINGLE)
|
||||||
{
|
{
|
||||||
// use single rotation for all views
|
// use single rotation for all views
|
||||||
|
@ -5127,8 +5157,6 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// choose a different rotation based on player view
|
// choose a different rotation based on player view
|
||||||
ang = R_PointToAngle (thing->x, thing->y) - thing->angle;
|
|
||||||
|
|
||||||
if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right
|
if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right
|
||||||
rot = 6; // F7 slot
|
rot = 6; // F7 slot
|
||||||
else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left
|
else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left
|
||||||
|
@ -5146,9 +5174,12 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||||
|
|
||||||
// calculate edges of the shape
|
// calculate edges of the shape
|
||||||
if (flip)
|
if (flip)
|
||||||
tx -= FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width - spritecachedinfo[lumpoff].offset) * this_scale;
|
offset = FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width - spritecachedinfo[lumpoff].offset) * this_scale;
|
||||||
else
|
else
|
||||||
tx -= FIXED_TO_FLOAT(spritecachedinfo[lumpoff].offset) * this_scale;
|
offset = FIXED_TO_FLOAT(spritecachedinfo[lumpoff].offset) * this_scale;
|
||||||
|
|
||||||
|
z1 = tz - (offset * ang_scalez);
|
||||||
|
tx -= offset * ang_scale;
|
||||||
|
|
||||||
// project x
|
// project x
|
||||||
x1 = gr_windowcenterx + (tx * gr_centerx / tz);
|
x1 = gr_windowcenterx + (tx * gr_centerx / tz);
|
||||||
|
@ -5159,7 +5190,14 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||||
|
|
||||||
x1 = tx;
|
x1 = tx;
|
||||||
|
|
||||||
tx += FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width) * this_scale;
|
offset = FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width) * this_scale;
|
||||||
|
|
||||||
|
z2 = z1 + (offset * ang_scalez);
|
||||||
|
tx += offset * ang_scale;
|
||||||
|
|
||||||
|
if (papersprite && max(z1, z2) < ZCLIP_PLANE)
|
||||||
|
return;
|
||||||
|
|
||||||
x2 = gr_windowcenterx + (tx * gr_centerx / tz);
|
x2 = gr_windowcenterx + (tx * gr_centerx / tz);
|
||||||
|
|
||||||
if (vflip)
|
if (vflip)
|
||||||
|
@ -5208,6 +5246,8 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||||
vis->patchlumpnum = sprframe->lumppat[rot];
|
vis->patchlumpnum = sprframe->lumppat[rot];
|
||||||
vis->flip = flip;
|
vis->flip = flip;
|
||||||
vis->mobj = thing;
|
vis->mobj = thing;
|
||||||
|
vis->z1 = z1;
|
||||||
|
vis->z2 = z2;
|
||||||
|
|
||||||
//Hurdler: 25/04/2000: now support colormap in hardware mode
|
//Hurdler: 25/04/2000: now support colormap in hardware mode
|
||||||
if ((vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash"
|
if ((vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash"
|
||||||
|
|
|
@ -244,6 +244,7 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...)
|
||||||
#define pglMaterialfv glMaterialfv
|
#define pglMaterialfv glMaterialfv
|
||||||
|
|
||||||
/* Raster functions */
|
/* Raster functions */
|
||||||
|
#define pglPixelStorei glPixelStorei
|
||||||
#define pglReadPixels glReadPixels
|
#define pglReadPixels glReadPixels
|
||||||
|
|
||||||
/* Texture mapping */
|
/* Texture mapping */
|
||||||
|
@ -262,15 +263,8 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...)
|
||||||
/* texture mapping */ //GL_EXT_copy_texture
|
/* texture mapping */ //GL_EXT_copy_texture
|
||||||
#ifndef KOS_GL_COMPATIBILITY
|
#ifndef KOS_GL_COMPATIBILITY
|
||||||
#define pglCopyTexImage2D glCopyTexImage2D
|
#define pglCopyTexImage2D glCopyTexImage2D
|
||||||
|
#endif
|
||||||
|
|
||||||
/* GLU functions */
|
|
||||||
#define pgluBuild2DMipmaps gluBuild2DMipmaps
|
|
||||||
#endif
|
|
||||||
#ifndef MINI_GL_COMPATIBILITY
|
|
||||||
/* 1.3 functions for multitexturing */
|
|
||||||
#define pglActiveTexture glActiveTexture
|
|
||||||
#define pglMultiTexCoord2f glMultiTexCoord2f
|
|
||||||
#endif
|
|
||||||
#else //!STATIC_OPENGL
|
#else //!STATIC_OPENGL
|
||||||
|
|
||||||
/* 1.0 functions */
|
/* 1.0 functions */
|
||||||
|
@ -365,6 +359,8 @@ typedef void (APIENTRY * PFNglMaterialfv) (GLint face, GLenum pname, GLfloat *pa
|
||||||
static PFNglMaterialfv pglMaterialfv;
|
static PFNglMaterialfv pglMaterialfv;
|
||||||
|
|
||||||
/* Raster functions */
|
/* Raster functions */
|
||||||
|
typedef void (APIENTRY * PFNglPixelStorei) (GLenum pname, GLint param);
|
||||||
|
static PFNglPixelStorei pglPixelStorei;
|
||||||
typedef void (APIENTRY * PFNglReadPixels) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);
|
typedef void (APIENTRY * PFNglReadPixels) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);
|
||||||
static PFNglReadPixels pglReadPixels;
|
static PFNglReadPixels pglReadPixels;
|
||||||
|
|
||||||
|
@ -391,7 +387,7 @@ static PFNglBindTexture pglBindTexture;
|
||||||
/* texture mapping */ //GL_EXT_copy_texture
|
/* texture mapping */ //GL_EXT_copy_texture
|
||||||
typedef void (APIENTRY * PFNglCopyTexImage2D) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
|
typedef void (APIENTRY * PFNglCopyTexImage2D) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
|
||||||
static PFNglCopyTexImage2D pglCopyTexImage2D;
|
static PFNglCopyTexImage2D pglCopyTexImage2D;
|
||||||
|
#endif
|
||||||
/* GLU functions */
|
/* GLU functions */
|
||||||
typedef GLint (APIENTRY * PFNgluBuild2DMipmaps) (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *data);
|
typedef GLint (APIENTRY * PFNgluBuild2DMipmaps) (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *data);
|
||||||
static PFNgluBuild2DMipmaps pgluBuild2DMipmaps;
|
static PFNgluBuild2DMipmaps pgluBuild2DMipmaps;
|
||||||
|
@ -403,7 +399,6 @@ static PFNglActiveTexture pglActiveTexture;
|
||||||
typedef void (APIENTRY *PFNglMultiTexCoord2f) (GLenum, GLfloat, GLfloat);
|
typedef void (APIENTRY *PFNglMultiTexCoord2f) (GLenum, GLfloat, GLfloat);
|
||||||
static PFNglMultiTexCoord2f pglMultiTexCoord2f;
|
static PFNglMultiTexCoord2f pglMultiTexCoord2f;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef MINI_GL_COMPATIBILITY
|
#ifndef MINI_GL_COMPATIBILITY
|
||||||
/* 1.2 Parms */
|
/* 1.2 Parms */
|
||||||
|
@ -494,6 +489,7 @@ boolean SetupGLfunc(void)
|
||||||
GETOPENGLFUNC(pglLightModelfv , glLightModelfv)
|
GETOPENGLFUNC(pglLightModelfv , glLightModelfv)
|
||||||
GETOPENGLFUNC(pglMaterialfv , glMaterialfv)
|
GETOPENGLFUNC(pglMaterialfv , glMaterialfv)
|
||||||
|
|
||||||
|
GETOPENGLFUNC(pglPixelStorei , glPixelStorei)
|
||||||
GETOPENGLFUNC(pglReadPixels , glReadPixels)
|
GETOPENGLFUNC(pglReadPixels , glReadPixels)
|
||||||
|
|
||||||
GETOPENGLFUNC(pglTexEnvi , glTexEnvi)
|
GETOPENGLFUNC(pglTexEnvi , glTexEnvi)
|
||||||
|
@ -519,35 +515,23 @@ boolean SetupGLfunc(void)
|
||||||
// This has to be done after the context is created so the version number can be obtained
|
// This has to be done after the context is created so the version number can be obtained
|
||||||
boolean SetupGLFunc13(void)
|
boolean SetupGLFunc13(void)
|
||||||
{
|
{
|
||||||
|
#ifdef MINI_GL_COMPATIBILITY
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
const GLubyte *version = pglGetString(GL_VERSION);
|
const GLubyte *version = pglGetString(GL_VERSION);
|
||||||
int glmajor, glminor;
|
int glmajor, glminor;
|
||||||
|
|
||||||
gl13 = false;
|
gl13 = false;
|
||||||
#ifdef MINI_GL_COMPATIBILITY
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
#ifdef STATIC_OPENGL
|
|
||||||
gl13 = true;
|
|
||||||
#else
|
|
||||||
|
|
||||||
// Parse the GL version
|
// Parse the GL version
|
||||||
if (version != NULL)
|
if (version != NULL)
|
||||||
{
|
{
|
||||||
if (sscanf((const char*)version, "%d.%d", &glmajor, &glminor) == 2)
|
if (sscanf((const char*)version, "%d.%d", &glmajor, &glminor) == 2)
|
||||||
{
|
{
|
||||||
// Look, we gotta prepare for the inevitable arrival of GL 2.0 code...
|
// Look, we gotta prepare for the inevitable arrival of GL 2.0 code...
|
||||||
switch (glmajor)
|
if (glmajor == 1 && glminor >= 3)
|
||||||
{
|
gl13 = true;
|
||||||
case 1:
|
else if (glmajor > 1)
|
||||||
if (glminor == 3) gl13 = true;
|
gl13 = true;
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
case 3:
|
|
||||||
case 4:
|
|
||||||
gl13 = true;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -568,9 +552,6 @@ boolean SetupGLFunc13(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
DBG_Printf("GL_ARB_multitexture support: disabled\n");
|
DBG_Printf("GL_ARB_multitexture support: disabled\n");
|
||||||
#undef GETOPENGLFUNC
|
|
||||||
|
|
||||||
#endif
|
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -897,7 +878,9 @@ EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height,
|
||||||
GLubyte*top = (GLvoid*)dst_data, *bottom = top + dst_stride * (height - 1);
|
GLubyte*top = (GLvoid*)dst_data, *bottom = top + dst_stride * (height - 1);
|
||||||
GLubyte *row = malloc(dst_stride);
|
GLubyte *row = malloc(dst_stride);
|
||||||
if (!row) return;
|
if (!row) return;
|
||||||
|
pglPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||||
pglReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, dst_data);
|
pglReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, dst_data);
|
||||||
|
pglPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
for(i = 0; i < height/2; i++)
|
for(i = 0; i < height/2; i++)
|
||||||
{
|
{
|
||||||
memcpy(row, top, dst_stride);
|
memcpy(row, top, dst_stride);
|
||||||
|
@ -913,7 +896,9 @@ EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height,
|
||||||
INT32 j;
|
INT32 j;
|
||||||
GLubyte *image = malloc(width*height*3*sizeof (*image));
|
GLubyte *image = malloc(width*height*3*sizeof (*image));
|
||||||
if (!image) return;
|
if (!image) return;
|
||||||
|
pglPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||||
pglReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, image);
|
pglReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, image);
|
||||||
|
pglPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
for (i = height-1; i >= 0; i--)
|
for (i = height-1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
for (j = 0; j < width; j++)
|
for (j = 0; j < width; j++)
|
||||||
|
@ -1815,13 +1800,11 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value)
|
||||||
min_filter = GL_NEAREST;
|
min_filter = GL_NEAREST;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#ifndef STATIC_OPENGL
|
|
||||||
if (!pgluBuild2DMipmaps)
|
if (!pgluBuild2DMipmaps)
|
||||||
{
|
{
|
||||||
MipMap = GL_FALSE;
|
MipMap = GL_FALSE;
|
||||||
min_filter = GL_LINEAR;
|
min_filter = GL_LINEAR;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
Flush(); //??? if we want to change filter mode by texture, remove this
|
Flush(); //??? if we want to change filter mode by texture, remove this
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ enum hook {
|
||||||
hook_ShieldSpawn,
|
hook_ShieldSpawn,
|
||||||
hook_ShieldSpecial,
|
hook_ShieldSpecial,
|
||||||
hook_MobjMoveBlocked,
|
hook_MobjMoveBlocked,
|
||||||
|
hook_MapThingSpawn,
|
||||||
|
|
||||||
hook_MAX // last hook
|
hook_MAX // last hook
|
||||||
};
|
};
|
||||||
|
@ -83,5 +84,6 @@ boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8
|
||||||
#define LUAh_ShieldSpawn(player) LUAh_PlayerHook(player, hook_ShieldSpawn) // Hook for P_SpawnShieldOrb
|
#define LUAh_ShieldSpawn(player) LUAh_PlayerHook(player, hook_ShieldSpawn) // Hook for P_SpawnShieldOrb
|
||||||
#define LUAh_ShieldSpecial(player) LUAh_PlayerHook(player, hook_ShieldSpecial) // Hook for shield abilities
|
#define LUAh_ShieldSpecial(player) LUAh_PlayerHook(player, hook_ShieldSpecial) // Hook for shield abilities
|
||||||
#define LUAh_MobjMoveBlocked(mo) LUAh_MobjHook(mo, hook_MobjMoveBlocked) // Hook for P_XYMovement (when movement is blocked)
|
#define LUAh_MobjMoveBlocked(mo) LUAh_MobjHook(mo, hook_MobjMoveBlocked) // Hook for P_XYMovement (when movement is blocked)
|
||||||
|
boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing); // Hook for P_SpawnMapThing by mobj type
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -57,6 +57,7 @@ const char *const hookNames[hook_MAX+1] = {
|
||||||
"ShieldSpawn",
|
"ShieldSpawn",
|
||||||
"ShieldSpecial",
|
"ShieldSpecial",
|
||||||
"MobjMoveBlocked",
|
"MobjMoveBlocked",
|
||||||
|
"MapThingSpawn",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -128,6 +129,7 @@ static int lib_addHook(lua_State *L)
|
||||||
case hook_MobjRemoved:
|
case hook_MobjRemoved:
|
||||||
case hook_HurtMsg:
|
case hook_HurtMsg:
|
||||||
case hook_MobjMoveBlocked:
|
case hook_MobjMoveBlocked:
|
||||||
|
case hook_MapThingSpawn:
|
||||||
hook.s.mt = MT_NULL;
|
hook.s.mt = MT_NULL;
|
||||||
if (lua_isnumber(L, 2))
|
if (lua_isnumber(L, 2))
|
||||||
hook.s.mt = lua_tonumber(L, 2);
|
hook.s.mt = lua_tonumber(L, 2);
|
||||||
|
@ -187,6 +189,7 @@ static int lib_addHook(lua_State *L)
|
||||||
case hook_BossDeath:
|
case hook_BossDeath:
|
||||||
case hook_MobjRemoved:
|
case hook_MobjRemoved:
|
||||||
case hook_MobjMoveBlocked:
|
case hook_MobjMoveBlocked:
|
||||||
|
case hook_MapThingSpawn:
|
||||||
lastp = &mobjhooks[hook.s.mt];
|
lastp = &mobjhooks[hook.s.mt];
|
||||||
break;
|
break;
|
||||||
case hook_JumpSpecial:
|
case hook_JumpSpecial:
|
||||||
|
@ -1073,4 +1076,66 @@ void LUAh_NetArchiveHook(lua_CFunction archFunc)
|
||||||
// stack: tables
|
// stack: tables
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing)
|
||||||
|
{
|
||||||
|
hook_p hookp;
|
||||||
|
boolean hooked = false;
|
||||||
|
if (!gL || !(hooksAvailable[hook_MapThingSpawn/8] & (1<<(hook_MapThingSpawn%8))))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
lua_settop(gL, 0);
|
||||||
|
|
||||||
|
// Look for all generic mobj map thing spawn hooks
|
||||||
|
for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next)
|
||||||
|
if (hookp->type == hook_MapThingSpawn)
|
||||||
|
{
|
||||||
|
if (lua_gettop(gL) == 0)
|
||||||
|
{
|
||||||
|
LUA_PushUserdata(gL, mo, META_MOBJ);
|
||||||
|
LUA_PushUserdata(gL, mthing, META_MAPTHING);
|
||||||
|
}
|
||||||
|
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
|
||||||
|
lua_gettable(gL, LUA_REGISTRYINDEX);
|
||||||
|
lua_pushvalue(gL, -3);
|
||||||
|
lua_pushvalue(gL, -3);
|
||||||
|
if (lua_pcall(gL, 2, 1, 0)) {
|
||||||
|
if (!hookp->error || cv_debug & DBG_LUA)
|
||||||
|
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
||||||
|
lua_pop(gL, 1);
|
||||||
|
hookp->error = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (lua_toboolean(gL, -1))
|
||||||
|
hooked = true;
|
||||||
|
lua_pop(gL, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (hookp = mobjhooks[mo->type]; hookp; hookp = hookp->next)
|
||||||
|
if (hookp->type == hook_MapThingSpawn)
|
||||||
|
{
|
||||||
|
if (lua_gettop(gL) == 0)
|
||||||
|
{
|
||||||
|
LUA_PushUserdata(gL, mo, META_MOBJ);
|
||||||
|
LUA_PushUserdata(gL, mthing, META_MAPTHING);
|
||||||
|
}
|
||||||
|
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
|
||||||
|
lua_gettable(gL, LUA_REGISTRYINDEX);
|
||||||
|
lua_pushvalue(gL, -3);
|
||||||
|
lua_pushvalue(gL, -3);
|
||||||
|
if (lua_pcall(gL, 2, 1, 0)) {
|
||||||
|
if (!hookp->error || cv_debug & DBG_LUA)
|
||||||
|
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
||||||
|
lua_pop(gL, 1);
|
||||||
|
hookp->error = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (lua_toboolean(gL, -1))
|
||||||
|
hooked = true;
|
||||||
|
lua_pop(gL, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_settop(gL, 0);
|
||||||
|
return hooked;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -596,14 +596,14 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
||||||
{
|
{
|
||||||
mobjinfo_t *info = *((mobjinfo_t **)lua_touserdata(gL, myindex));
|
mobjinfo_t *info = *((mobjinfo_t **)lua_touserdata(gL, myindex));
|
||||||
WRITEUINT8(save_p, ARCH_MOBJINFO);
|
WRITEUINT8(save_p, ARCH_MOBJINFO);
|
||||||
WRITEUINT8(save_p, info - mobjinfo);
|
WRITEUINT16(save_p, info - mobjinfo);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ARCH_STATE:
|
case ARCH_STATE:
|
||||||
{
|
{
|
||||||
state_t *state = *((state_t **)lua_touserdata(gL, myindex));
|
state_t *state = *((state_t **)lua_touserdata(gL, myindex));
|
||||||
WRITEUINT8(save_p, ARCH_STATE);
|
WRITEUINT8(save_p, ARCH_STATE);
|
||||||
WRITEUINT8(save_p, state - states);
|
WRITEUINT16(save_p, state - states);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ARCH_MOBJ:
|
case ARCH_MOBJ:
|
||||||
|
|
|
@ -16,89 +16,127 @@
|
||||||
#include "lua_script.h"
|
#include "lua_script.h"
|
||||||
#include "lua_libs.h"
|
#include "lua_libs.h"
|
||||||
|
|
||||||
|
#define META_ITERATIONSTATE "iteration state"
|
||||||
|
|
||||||
static const char *const iter_opt[] = {
|
static const char *const iter_opt[] = {
|
||||||
"all",
|
"all",
|
||||||
"mobj",
|
"mobj",
|
||||||
NULL};
|
NULL};
|
||||||
|
|
||||||
|
static const actionf_p1 iter_funcs[] = {
|
||||||
|
NULL,
|
||||||
|
(actionf_p1)P_MobjThinker
|
||||||
|
};
|
||||||
|
|
||||||
|
struct iterationState {
|
||||||
|
actionf_p1 filter;
|
||||||
|
int next;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int iterationState_gc(lua_State *L)
|
||||||
|
{
|
||||||
|
struct iterationState *it = luaL_checkudata(L, -1, META_ITERATIONSTATE);
|
||||||
|
if (it->next != LUA_REFNIL)
|
||||||
|
{
|
||||||
|
luaL_unref(L, LUA_REGISTRYINDEX, it->next);
|
||||||
|
it->next = LUA_REFNIL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define push_thinker(th) {\
|
||||||
|
if ((th)->function.acp1 == (actionf_p1)P_MobjThinker) \
|
||||||
|
LUA_PushUserdata(L, (th), META_MOBJ); \
|
||||||
|
else \
|
||||||
|
lua_pushlightuserdata(L, (th)); \
|
||||||
|
}
|
||||||
|
|
||||||
static int lib_iterateThinkers(lua_State *L)
|
static int lib_iterateThinkers(lua_State *L)
|
||||||
{
|
{
|
||||||
int state = luaL_checkoption(L, 1, "mobj", iter_opt);
|
thinker_t *th = NULL, *next = NULL;
|
||||||
|
struct iterationState *it;
|
||||||
thinker_t *th = NULL;
|
|
||||||
actionf_p1 searchFunc;
|
|
||||||
const char *searchMeta;
|
|
||||||
|
|
||||||
if (gamestate != GS_LEVEL)
|
if (gamestate != GS_LEVEL)
|
||||||
return luaL_error(L, "This function can only be used in a level!");
|
return luaL_error(L, "This function can only be used in a level!");
|
||||||
|
|
||||||
lua_settop(L, 2);
|
it = luaL_checkudata(L, 1, META_ITERATIONSTATE);
|
||||||
lua_remove(L, 1); // remove state now.
|
|
||||||
|
|
||||||
switch(state)
|
lua_settop(L, 2);
|
||||||
|
|
||||||
|
if (lua_isnil(L, 2))
|
||||||
|
th = &thinkercap;
|
||||||
|
else if (lua_isuserdata(L, 2))
|
||||||
{
|
{
|
||||||
case 0:
|
if (lua_islightuserdata(L, 2))
|
||||||
searchFunc = NULL;
|
th = lua_touserdata(L, 2);
|
||||||
searchMeta = NULL;
|
else
|
||||||
break;
|
{
|
||||||
case 1:
|
th = *(thinker_t **)lua_touserdata(L, -1);
|
||||||
default:
|
if (!th)
|
||||||
searchFunc = (actionf_p1)P_MobjThinker;
|
{
|
||||||
searchMeta = META_MOBJ;
|
if (it->next == LUA_REFNIL)
|
||||||
break;
|
return 0;
|
||||||
|
|
||||||
|
lua_rawgeti(L, LUA_REGISTRYINDEX, it->next);
|
||||||
|
if (lua_islightuserdata(L, -1))
|
||||||
|
next = lua_touserdata(L, -1);
|
||||||
|
else
|
||||||
|
next = *(thinker_t **)lua_touserdata(L, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!lua_isnil(L, 1)) {
|
luaL_unref(L, LUA_REGISTRYINDEX, it->next);
|
||||||
if (lua_islightuserdata(L, 1))
|
it->next = LUA_REFNIL;
|
||||||
th = (thinker_t *)lua_touserdata(L, 1);
|
|
||||||
else if (searchMeta)
|
|
||||||
th = *((thinker_t **)luaL_checkudata(L, 1, searchMeta));
|
|
||||||
else
|
|
||||||
th = *((thinker_t **)lua_touserdata(L, 1));
|
|
||||||
} else
|
|
||||||
th = &thinkercap;
|
|
||||||
|
|
||||||
if (!th) // something got our userdata invalidated!
|
if (th && !next)
|
||||||
return 0;
|
next = th->next;
|
||||||
|
if (!next)
|
||||||
|
return luaL_error(L, "next thinker invalidated during iteration");
|
||||||
|
|
||||||
if (searchFunc == NULL)
|
for (; next != &thinkercap; next = next->next)
|
||||||
{
|
if (!it->filter || next->function.acp1 == it->filter)
|
||||||
if ((th = th->next) != &thinkercap)
|
|
||||||
{
|
{
|
||||||
if (th->function.acp1 == (actionf_p1)P_MobjThinker)
|
push_thinker(next);
|
||||||
LUA_PushUserdata(L, th, META_MOBJ);
|
if (next->next != &thinkercap)
|
||||||
else
|
{
|
||||||
lua_pushlightuserdata(L, th);
|
push_thinker(next->next);
|
||||||
|
it->next = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (th = th->next; th != &thinkercap; th = th->next)
|
|
||||||
{
|
|
||||||
if (th->function.acp1 != searchFunc)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
LUA_PushUserdata(L, th, searchMeta);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lib_startIterate(lua_State *L)
|
static int lib_startIterate(lua_State *L)
|
||||||
{
|
{
|
||||||
|
struct iterationState *it;
|
||||||
|
|
||||||
if (gamestate != GS_LEVEL)
|
if (gamestate != GS_LEVEL)
|
||||||
return luaL_error(L, "This function can only be used in a level!");
|
return luaL_error(L, "This function can only be used in a level!");
|
||||||
luaL_checkoption(L, 1, iter_opt[0], iter_opt);
|
|
||||||
lua_pushcfunction(L, lib_iterateThinkers);
|
lua_pushvalue(L, lua_upvalueindex(1));
|
||||||
lua_pushvalue(L, 1);
|
it = lua_newuserdata(L, sizeof(struct iterationState));
|
||||||
|
luaL_getmetatable(L, META_ITERATIONSTATE);
|
||||||
|
lua_setmetatable(L, -2);
|
||||||
|
|
||||||
|
it->filter = iter_funcs[luaL_checkoption(L, 1, "mobj", iter_opt)];
|
||||||
|
it->next = LUA_REFNIL;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef push_thinker
|
||||||
|
|
||||||
int LUA_ThinkerLib(lua_State *L)
|
int LUA_ThinkerLib(lua_State *L)
|
||||||
{
|
{
|
||||||
|
luaL_newmetatable(L, META_ITERATIONSTATE);
|
||||||
|
lua_pushcfunction(L, iterationState_gc);
|
||||||
|
lua_setfield(L, -2, "__gc");
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
lua_createtable(L, 0, 1);
|
lua_createtable(L, 0, 1);
|
||||||
lua_pushcfunction(L, lib_startIterate);
|
lua_pushcfunction(L, lib_iterateThinkers);
|
||||||
|
lua_pushcclosure(L, lib_startIterate, 1);
|
||||||
lua_setfield(L, -2, "iterate");
|
lua_setfield(L, -2, "iterate");
|
||||||
lua_setglobal(L, "thinkers");
|
lua_setglobal(L, "thinkers");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -2113,6 +2113,7 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
|
||||||
boolean inAndOut = false;
|
boolean inAndOut = false;
|
||||||
boolean floortouch = false;
|
boolean floortouch = false;
|
||||||
fixed_t bottomheight, topheight;
|
fixed_t bottomheight, topheight;
|
||||||
|
msecnode_t *node;
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
|
@ -2174,7 +2175,23 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
|
||||||
if ((netgame || multiplayer) && players[j].spectator)
|
if ((netgame || multiplayer) && players[j].spectator)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (players[j].mo->subsector->sector != targetsec)
|
if (players[j].mo->subsector->sector == targetsec)
|
||||||
|
;
|
||||||
|
else if (sec->flags & SF_TRIGGERSPECIAL_TOUCH)
|
||||||
|
{
|
||||||
|
boolean insector = false;
|
||||||
|
for (node = players[j].mo->touching_sectorlist; node; node = node->m_sectorlist_next)
|
||||||
|
{
|
||||||
|
if (node->m_sector == targetsec)
|
||||||
|
{
|
||||||
|
insector = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!insector)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
topheight = P_GetSpecialTopZ(players[j].mo, sec, targetsec);
|
topheight = P_GetSpecialTopZ(players[j].mo, sec, targetsec);
|
||||||
|
@ -2224,7 +2241,27 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
|
||||||
if ((netgame || multiplayer) && players[i].spectator)
|
if ((netgame || multiplayer) && players[i].spectator)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (players[i].mo->subsector->sector != sec)
|
if (players[i].mo->subsector->sector == sec)
|
||||||
|
;
|
||||||
|
else if (sec->flags & SF_TRIGGERSPECIAL_TOUCH)
|
||||||
|
{
|
||||||
|
boolean insector = false;
|
||||||
|
for (node = players[i].mo->touching_sectorlist; node; node = node->m_sectorlist_next)
|
||||||
|
{
|
||||||
|
if (node->m_sector == sec)
|
||||||
|
{
|
||||||
|
insector = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!insector)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!(players[i].mo->subsector->sector == sec
|
||||||
|
|| P_PlayerTouchingSectorSpecial(&players[i], 2, (GETSECSPECIAL(sec->special, 2))) == sec))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (floortouch == true && P_IsObjectOnGroundIn(players[i].mo, sec))
|
if (floortouch == true && P_IsObjectOnGroundIn(players[i].mo, sec))
|
||||||
|
|
14
src/p_map.c
14
src/p_map.c
|
@ -1117,6 +1117,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
if (iwassprung) // this spring caused you to gain MFE_SPRUNG just now...
|
if (iwassprung) // this spring caused you to gain MFE_SPRUNG just now...
|
||||||
return false; // "cancel" P_TryMove via blocking so you keep your current position
|
return false; // "cancel" P_TryMove via blocking so you keep your current position
|
||||||
}
|
}
|
||||||
|
else if (tmthing->flags & MF_SPRING && (thing->player || thing->flags & MF_PUSHABLE))
|
||||||
|
; // Fix a few nasty spring-jumping bugs that happen sometimes.
|
||||||
// Monitors are not treated as solid to players who are jumping, spinning or gliding,
|
// Monitors are not treated as solid to players who are jumping, spinning or gliding,
|
||||||
// unless it's a CTF team monitor and you're on the wrong team
|
// unless it's a CTF team monitor and you're on the wrong team
|
||||||
else if (thing->flags & MF_MONITOR && tmthing->player
|
else if (thing->flags & MF_MONITOR && tmthing->player
|
||||||
|
@ -1155,11 +1157,13 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
|
|
||||||
topz = thing->z - thing->scale; // FixedMul(FRACUNIT, thing->scale), but thing->scale == FRACUNIT in base scale anyways
|
topz = thing->z - thing->scale; // FixedMul(FRACUNIT, thing->scale), but thing->scale == FRACUNIT in base scale anyways
|
||||||
|
|
||||||
|
if (thing->flags & MF_SPRING)
|
||||||
|
;
|
||||||
// block only when jumping not high enough,
|
// block only when jumping not high enough,
|
||||||
// (dont climb max. 24units while already in air)
|
// (dont climb max. 24units while already in air)
|
||||||
// since return false doesn't handle momentum properly,
|
// since return false doesn't handle momentum properly,
|
||||||
// we lie to P_TryMove() so it's always too high
|
// we lie to P_TryMove() so it's always too high
|
||||||
if (tmthing->player && tmthing->z + tmthing->height > topz
|
else if (tmthing->player && tmthing->z + tmthing->height > topz
|
||||||
&& tmthing->z + tmthing->height < tmthing->ceilingz)
|
&& tmthing->z + tmthing->height < tmthing->ceilingz)
|
||||||
{
|
{
|
||||||
if (thing->flags & MF_GRENADEBOUNCE && (thing->flags & MF_MONITOR || thing->flags2 & MF2_STANDONME)) // Gold monitor hack...
|
if (thing->flags & MF_GRENADEBOUNCE && (thing->flags & MF_MONITOR || thing->flags2 & MF2_STANDONME)) // Gold monitor hack...
|
||||||
|
@ -1171,8 +1175,6 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
#endif
|
#endif
|
||||||
tmfloorthing = thing; // needed for side collision
|
tmfloorthing = thing; // needed for side collision
|
||||||
}
|
}
|
||||||
else if (thing->flags & MF_SPRING)
|
|
||||||
;
|
|
||||||
else if (topz < tmceilingz && tmthing->z <= thing->z+thing->height)
|
else if (topz < tmceilingz && tmthing->z <= thing->z+thing->height)
|
||||||
{
|
{
|
||||||
tmceilingz = topz;
|
tmceilingz = topz;
|
||||||
|
@ -1201,11 +1203,13 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
|
|
||||||
topz = thing->z + thing->height + thing->scale; // FixedMul(FRACUNIT, thing->scale), but thing->scale == FRACUNIT in base scale anyways
|
topz = thing->z + thing->height + thing->scale; // FixedMul(FRACUNIT, thing->scale), but thing->scale == FRACUNIT in base scale anyways
|
||||||
|
|
||||||
|
if (thing->flags & MF_SPRING)
|
||||||
|
;
|
||||||
// block only when jumping not high enough,
|
// block only when jumping not high enough,
|
||||||
// (dont climb max. 24units while already in air)
|
// (dont climb max. 24units while already in air)
|
||||||
// since return false doesn't handle momentum properly,
|
// since return false doesn't handle momentum properly,
|
||||||
// we lie to P_TryMove() so it's always too high
|
// we lie to P_TryMove() so it's always too high
|
||||||
if (tmthing->player && tmthing->z < topz
|
else if (tmthing->player && tmthing->z < topz
|
||||||
&& tmthing->z > tmthing->floorz)
|
&& tmthing->z > tmthing->floorz)
|
||||||
{
|
{
|
||||||
if (thing->flags & MF_GRENADEBOUNCE && (thing->flags & MF_MONITOR || thing->flags2 & MF2_STANDONME)) // Gold monitor hack...
|
if (thing->flags & MF_GRENADEBOUNCE && (thing->flags & MF_MONITOR || thing->flags2 & MF2_STANDONME)) // Gold monitor hack...
|
||||||
|
@ -1217,8 +1221,6 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
#endif
|
#endif
|
||||||
tmfloorthing = thing; // needed for side collision
|
tmfloorthing = thing; // needed for side collision
|
||||||
}
|
}
|
||||||
else if (thing->flags & MF_SPRING)
|
|
||||||
;
|
|
||||||
else if (topz > tmfloorz && tmthing->z+tmthing->height >= thing->z)
|
else if (topz > tmfloorz && tmthing->z+tmthing->height >= thing->z)
|
||||||
{
|
{
|
||||||
tmfloorz = topz;
|
tmfloorz = topz;
|
||||||
|
|
39
src/p_mobj.c
39
src/p_mobj.c
|
@ -2560,10 +2560,18 @@ boolean P_CheckSolidLava(mobj_t *mo, ffloor_t *rover)
|
||||||
I_Assert(mo != NULL);
|
I_Assert(mo != NULL);
|
||||||
I_Assert(!P_MobjWasRemoved(mo));
|
I_Assert(!P_MobjWasRemoved(mo));
|
||||||
|
|
||||||
if (rover->flags & FF_SWIMMABLE && GETSECSPECIAL(rover->master->frontsector->special, 1) == 3
|
{
|
||||||
&& !(rover->master->flags & ML_BLOCKMONSTERS)
|
fixed_t topheight =
|
||||||
&& ((rover->master->flags & ML_EFFECT3) || mo->z-mo->momz > *rover->topheight - FixedMul(16*FRACUNIT, mo->scale)))
|
#ifdef ESLOPE
|
||||||
return true;
|
*rover->t_slope ? P_GetZAt(*rover->t_slope, mo->x, mo->y) :
|
||||||
|
#endif
|
||||||
|
*rover->topheight;
|
||||||
|
|
||||||
|
if (rover->flags & FF_SWIMMABLE && GETSECSPECIAL(rover->master->frontsector->special, 1) == 3
|
||||||
|
&& !(rover->master->flags & ML_BLOCKMONSTERS)
|
||||||
|
&& ((rover->master->flags & ML_EFFECT3) || mo->z-mo->momz > topheight - FixedMul(16*FRACUNIT, mo->scale)))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2802,7 +2810,7 @@ static boolean P_ZMovement(mobj_t *mo)
|
||||||
mo->z = mo->floorz;
|
mo->z = mo->floorz;
|
||||||
|
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
if (mo->standingslope) // You're still on the ground; why are we here?
|
if (!(mo->flags & MF_MISSILE) && mo->standingslope) // You're still on the ground; why are we here?
|
||||||
{
|
{
|
||||||
mo->momz = 0;
|
mo->momz = 0;
|
||||||
return true;
|
return true;
|
||||||
|
@ -3578,11 +3586,17 @@ static boolean P_SceneryZMovement(mobj_t *mo)
|
||||||
//
|
//
|
||||||
boolean P_CanRunOnWater(player_t *player, ffloor_t *rover)
|
boolean P_CanRunOnWater(player_t *player, ffloor_t *rover)
|
||||||
{
|
{
|
||||||
|
fixed_t topheight =
|
||||||
|
#ifdef ESLOPE
|
||||||
|
*rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) :
|
||||||
|
#endif
|
||||||
|
*rover->topheight;
|
||||||
|
|
||||||
if (!player->powers[pw_carry] && !player->homing
|
if (!player->powers[pw_carry] && !player->homing
|
||||||
&& ((player->powers[pw_super] || player->charflags & SF_RUNONWATER || player->dashmode >= 3*TICRATE) && player->mo->ceilingz-*rover->topheight >= player->mo->height)
|
&& ((player->powers[pw_super] || player->charflags & SF_RUNONWATER || player->dashmode >= 3*TICRATE) && player->mo->ceilingz-topheight >= player->mo->height)
|
||||||
&& (rover->flags & FF_SWIMMABLE) && !(player->pflags & PF_SPINNING) && player->speed > FixedMul(player->runspeed, player->mo->scale)
|
&& (rover->flags & FF_SWIMMABLE) && !(player->pflags & PF_SPINNING) && player->speed > FixedMul(player->runspeed, player->mo->scale)
|
||||||
&& !(player->pflags & PF_SLIDING)
|
&& !(player->pflags & PF_SLIDING)
|
||||||
&& abs(player->mo->z - *rover->topheight) < FixedMul(30*FRACUNIT, player->mo->scale))
|
&& abs(player->mo->z - topheight) < FixedMul(30*FRACUNIT, player->mo->scale))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -8515,6 +8529,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
||||||
break;
|
break;
|
||||||
case MT_EGGCAPSULE:
|
case MT_EGGCAPSULE:
|
||||||
mobj->extravalue1 = -1; // timer for how long a player has been at the capsule
|
mobj->extravalue1 = -1; // timer for how long a player has been at the capsule
|
||||||
|
break;
|
||||||
case MT_REDTEAMRING:
|
case MT_REDTEAMRING:
|
||||||
mobj->color = skincolor_redteam;
|
mobj->color = skincolor_redteam;
|
||||||
break;
|
break;
|
||||||
|
@ -9714,6 +9729,16 @@ void P_SpawnMapThing(mapthing_t *mthing)
|
||||||
mobj = P_SpawnMobj(x, y, z, i);
|
mobj = P_SpawnMobj(x, y, z, i);
|
||||||
mobj->spawnpoint = mthing;
|
mobj->spawnpoint = mthing;
|
||||||
|
|
||||||
|
#ifdef HAVE_BLUA
|
||||||
|
if (LUAh_MapThingSpawn(mobj, mthing))
|
||||||
|
{
|
||||||
|
if (P_MobjWasRemoved(mobj))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (P_MobjWasRemoved(mobj))
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
switch(mobj->type)
|
switch(mobj->type)
|
||||||
{
|
{
|
||||||
case MT_SKYBOX:
|
case MT_SKYBOX:
|
||||||
|
|
220
src/p_spec.c
220
src/p_spec.c
|
@ -456,7 +456,8 @@ void P_ParseAnimationDefintion(SINT8 istexture)
|
||||||
|
|
||||||
// Search for existing animdef
|
// Search for existing animdef
|
||||||
for (i = 0; i < maxanims; i++)
|
for (i = 0; i < maxanims; i++)
|
||||||
if (stricmp(animdefsToken, animdefs[i].startname) == 0)
|
if (animdefs[i].istexture == istexture // Check if it's the same type!
|
||||||
|
&& stricmp(animdefsToken, animdefs[i].startname) == 0)
|
||||||
{
|
{
|
||||||
//CONS_Alert(CONS_NOTICE, "Duplicate animation: %s\n", animdefsToken);
|
//CONS_Alert(CONS_NOTICE, "Duplicate animation: %s\n", animdefsToken);
|
||||||
|
|
||||||
|
@ -2444,73 +2445,81 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
||||||
|
|
||||||
case 414: // Play SFX
|
case 414: // Play SFX
|
||||||
{
|
{
|
||||||
fixed_t sfxnum;
|
INT32 sfxnum;
|
||||||
|
|
||||||
sfxnum = sides[line->sidenum[0]].toptexture;
|
sfxnum = sides[line->sidenum[0]].toptexture;
|
||||||
|
|
||||||
if (line->tag != 0 && line->flags & ML_EFFECT5)
|
if (sfxnum == sfx_None)
|
||||||
|
return; // Do nothing!
|
||||||
|
if (sfxnum < sfx_None || sfxnum >= NUMSFX)
|
||||||
{
|
{
|
||||||
sector_t *sec;
|
CONS_Debug(DBG_GAMELOGIC, "Line type 414 Executor: sfx number %d is invalid!\n", sfxnum);
|
||||||
|
return;
|
||||||
while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0)
|
}
|
||||||
|
if (line->tag != 0) // Do special stuff only if a non-zero linedef tag is set
|
||||||
|
{
|
||||||
|
if (line->flags & ML_EFFECT5) // Repeat Midtexture
|
||||||
{
|
{
|
||||||
sec = §ors[secnum];
|
// Additionally play the sound from tagged sectors' soundorgs
|
||||||
S_StartSound(&sec->soundorg, sfxnum);
|
sector_t *sec;
|
||||||
|
|
||||||
|
while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0)
|
||||||
|
{
|
||||||
|
sec = §ors[secnum];
|
||||||
|
S_StartSound(&sec->soundorg, sfxnum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mo) // A mobj must have triggered the executor
|
||||||
|
{
|
||||||
|
// Only trigger if mobj is touching the tag
|
||||||
|
ffloor_t *rover;
|
||||||
|
boolean foundit = false;
|
||||||
|
|
||||||
|
for(rover = mo->subsector->sector->ffloors; rover; rover = rover->next)
|
||||||
|
{
|
||||||
|
if (rover->master->frontsector->tag != line->tag)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (mo->z > P_GetSpecialTopZ(mo, sectors + rover->secnum, mo->subsector->sector))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (mo->z + mo->height < P_GetSpecialBottomZ(mo, sectors + rover->secnum, mo->subsector->sector))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
foundit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mo->subsector->sector->tag == line->tag)
|
||||||
|
foundit = true;
|
||||||
|
|
||||||
|
if (!foundit)
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (line->tag != 0 && mo)
|
|
||||||
|
if (line->flags & ML_NOCLIMB)
|
||||||
{
|
{
|
||||||
// Only trigger if mobj is touching the tag
|
// play the sound from nowhere, but only if display player triggered it
|
||||||
ffloor_t *rover;
|
if (mo && mo->player && (mo->player == &players[displayplayer] || mo->player == &players[secondarydisplayplayer]))
|
||||||
boolean foundit = false;
|
|
||||||
|
|
||||||
for(rover = mo->subsector->sector->ffloors; rover; rover = rover->next)
|
|
||||||
{
|
|
||||||
if (rover->master->frontsector->tag != line->tag)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (mo->z > P_GetSpecialTopZ(mo, sectors + rover->secnum, mo->subsector->sector))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (mo->z + mo->height < P_GetSpecialBottomZ(mo, sectors + rover->secnum, mo->subsector->sector))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
foundit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mo->subsector->sector->tag == line->tag)
|
|
||||||
foundit = true;
|
|
||||||
|
|
||||||
if (!foundit)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sfxnum < NUMSFX && sfxnum > sfx_None)
|
|
||||||
{
|
|
||||||
if (line->flags & ML_NOCLIMB)
|
|
||||||
{
|
|
||||||
// play the sound from nowhere, but only if display player triggered it
|
|
||||||
if (mo && mo->player && (mo->player == &players[displayplayer] || mo->player == &players[secondarydisplayplayer]))
|
|
||||||
S_StartSound(NULL, sfxnum);
|
|
||||||
}
|
|
||||||
else if (line->flags & ML_EFFECT4)
|
|
||||||
{
|
|
||||||
// play the sound from nowhere
|
|
||||||
S_StartSound(NULL, sfxnum);
|
S_StartSound(NULL, sfxnum);
|
||||||
}
|
}
|
||||||
else if (line->flags & ML_BLOCKMONSTERS)
|
else if (line->flags & ML_EFFECT4)
|
||||||
{
|
{
|
||||||
// play the sound from calling sector's soundorg
|
// play the sound from nowhere
|
||||||
if (callsec)
|
S_StartSound(NULL, sfxnum);
|
||||||
S_StartSound(&callsec->soundorg, sfxnum);
|
}
|
||||||
else if (mo)
|
else if (line->flags & ML_BLOCKMONSTERS)
|
||||||
S_StartSound(&mo->subsector->sector->soundorg, sfxnum);
|
{
|
||||||
}
|
// play the sound from calling sector's soundorg
|
||||||
|
if (callsec)
|
||||||
|
S_StartSound(&callsec->soundorg, sfxnum);
|
||||||
else if (mo)
|
else if (mo)
|
||||||
{
|
S_StartSound(&mo->subsector->sector->soundorg, sfxnum);
|
||||||
// play the sound from mobj that triggered it
|
}
|
||||||
S_StartSound(mo, sfxnum);
|
else if (mo)
|
||||||
}
|
{
|
||||||
|
// play the sound from mobj that triggered it
|
||||||
|
S_StartSound(mo, sfxnum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -3569,7 +3578,7 @@ static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *tar
|
||||||
//
|
//
|
||||||
// Is player standing on the sector's "ground"?
|
// Is player standing on the sector's "ground"?
|
||||||
//
|
//
|
||||||
static inline boolean P_MobjReadyToTrigger(mobj_t *mo, sector_t *sec)
|
static boolean P_MobjReadyToTrigger(mobj_t *mo, sector_t *sec)
|
||||||
{
|
{
|
||||||
if (mo->eflags & MFE_VERTICALFLIP)
|
if (mo->eflags & MFE_VERTICALFLIP)
|
||||||
return (mo->z+mo->height == P_GetSpecialTopZ(mo, sec, sec) && sec->flags & SF_FLIPSPECIAL_CEILING);
|
return (mo->z+mo->height == P_GetSpecialTopZ(mo, sec, sec) && sec->flags & SF_FLIPSPECIAL_CEILING);
|
||||||
|
@ -3702,14 +3711,49 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
|
||||||
{
|
{
|
||||||
if (roversector)
|
if (roversector)
|
||||||
{
|
{
|
||||||
if (players[i].mo->subsector->sector != roversector)
|
if (players[i].mo->subsector->sector == roversector)
|
||||||
|
;
|
||||||
|
else if (sector->flags & SF_TRIGGERSPECIAL_TOUCH)
|
||||||
|
{
|
||||||
|
boolean insector = false;
|
||||||
|
msecnode_t *node;
|
||||||
|
for (node = players[i].mo->touching_sectorlist; node; node = node->m_sectorlist_next)
|
||||||
|
{
|
||||||
|
if (node->m_sector == roversector)
|
||||||
|
{
|
||||||
|
insector = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!insector)
|
||||||
|
goto DoneSection2;
|
||||||
|
}
|
||||||
|
else
|
||||||
goto DoneSection2;
|
goto DoneSection2;
|
||||||
|
|
||||||
if (!P_ThingIsOnThe3DFloor(players[i].mo, sector, roversector))
|
if (!P_ThingIsOnThe3DFloor(players[i].mo, sector, roversector))
|
||||||
goto DoneSection2;
|
goto DoneSection2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (players[i].mo->subsector->sector != sector)
|
if (players[i].mo->subsector->sector == sector)
|
||||||
|
;
|
||||||
|
else if (sector->flags & SF_TRIGGERSPECIAL_TOUCH)
|
||||||
|
{
|
||||||
|
boolean insector = false;
|
||||||
|
msecnode_t *node;
|
||||||
|
for (node = players[i].mo->touching_sectorlist; node; node = node->m_sectorlist_next)
|
||||||
|
{
|
||||||
|
if (node->m_sector == sector)
|
||||||
|
{
|
||||||
|
insector = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!insector)
|
||||||
|
goto DoneSection2;
|
||||||
|
}
|
||||||
|
else
|
||||||
goto DoneSection2;
|
goto DoneSection2;
|
||||||
|
|
||||||
if (special == 3 && !P_MobjReadyToTrigger(players[i].mo, sector))
|
if (special == 3 && !P_MobjReadyToTrigger(players[i].mo, sector))
|
||||||
|
@ -4490,6 +4534,7 @@ sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo)
|
||||||
{
|
{
|
||||||
sector_t *sector;
|
sector_t *sector;
|
||||||
ffloor_t *rover;
|
ffloor_t *rover;
|
||||||
|
fixed_t topheight, bottomheight;
|
||||||
|
|
||||||
sector = mo->subsector->sector;
|
sector = mo->subsector->sector;
|
||||||
if (!sector->ffloors)
|
if (!sector->ffloors)
|
||||||
|
@ -4497,8 +4542,6 @@ sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo)
|
||||||
|
|
||||||
for (rover = sector->ffloors; rover; rover = rover->next)
|
for (rover = sector->ffloors; rover; rover = rover->next)
|
||||||
{
|
{
|
||||||
fixed_t topheight, bottomheight;
|
|
||||||
|
|
||||||
if (!rover->master->frontsector->special)
|
if (!rover->master->frontsector->special)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -4546,6 +4589,8 @@ sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define TELEPORTED (player->mo->subsector->sector != originalsector)
|
||||||
|
|
||||||
/** Checks if a player is standing on or is inside a 3D floor (e.g. water) and
|
/** Checks if a player is standing on or is inside a 3D floor (e.g. water) and
|
||||||
* applies any specials.
|
* applies any specials.
|
||||||
*
|
*
|
||||||
|
@ -4554,12 +4599,12 @@ sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo)
|
||||||
*/
|
*/
|
||||||
static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector)
|
static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector)
|
||||||
{
|
{
|
||||||
|
sector_t *originalsector = player->mo->subsector->sector;
|
||||||
ffloor_t *rover;
|
ffloor_t *rover;
|
||||||
|
fixed_t topheight, bottomheight;
|
||||||
|
|
||||||
for (rover = sector->ffloors; rover; rover = rover->next)
|
for (rover = sector->ffloors; rover; rover = rover->next)
|
||||||
{
|
{
|
||||||
fixed_t topheight, bottomheight;
|
|
||||||
|
|
||||||
if (!rover->master->frontsector->special)
|
if (!rover->master->frontsector->special)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -4603,7 +4648,10 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector)
|
||||||
// This FOF has the special we're looking for, but are we allowed to touch it?
|
// This FOF has the special we're looking for, but are we allowed to touch it?
|
||||||
if (sector == player->mo->subsector->sector
|
if (sector == player->mo->subsector->sector
|
||||||
|| (rover->master->frontsector->flags & SF_TRIGGERSPECIAL_TOUCH))
|
|| (rover->master->frontsector->flags & SF_TRIGGERSPECIAL_TOUCH))
|
||||||
|
{
|
||||||
P_ProcessSpecialSector(player, rover->master->frontsector, sector);
|
P_ProcessSpecialSector(player, rover->master->frontsector, sector);
|
||||||
|
if TELEPORTED return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow sector specials to be applied to polyobjects!
|
// Allow sector specials to be applied to polyobjects!
|
||||||
|
@ -4614,7 +4662,7 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector)
|
||||||
boolean touching = false;
|
boolean touching = false;
|
||||||
boolean inside = false;
|
boolean inside = false;
|
||||||
|
|
||||||
while(po)
|
while (po)
|
||||||
{
|
{
|
||||||
if (po->flags & POF_NOSPECIALS)
|
if (po->flags & POF_NOSPECIALS)
|
||||||
{
|
{
|
||||||
|
@ -4690,6 +4738,7 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector)
|
||||||
}
|
}
|
||||||
|
|
||||||
P_ProcessSpecialSector(player, polysec, sector);
|
P_ProcessSpecialSector(player, polysec, sector);
|
||||||
|
if TELEPORTED return;
|
||||||
|
|
||||||
po = (polyobj_t *)(po->link.next);
|
po = (polyobj_t *)(po->link.next);
|
||||||
}
|
}
|
||||||
|
@ -4794,40 +4843,43 @@ static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector)
|
||||||
*/
|
*/
|
||||||
void P_PlayerInSpecialSector(player_t *player)
|
void P_PlayerInSpecialSector(player_t *player)
|
||||||
{
|
{
|
||||||
sector_t *sector;
|
sector_t *originalsector;
|
||||||
|
sector_t *loopsector;
|
||||||
msecnode_t *node;
|
msecnode_t *node;
|
||||||
|
|
||||||
if (!player->mo)
|
if (!player->mo)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Do your ->subsector->sector first
|
originalsector = player->mo->subsector->sector;
|
||||||
sector = player->mo->subsector->sector;
|
|
||||||
P_PlayerOnSpecial3DFloor(player, sector);
|
|
||||||
// After P_PlayerOnSpecial3DFloor, recheck if the player is in that sector,
|
|
||||||
// because the player can be teleported in between these times.
|
|
||||||
if (sector == player->mo->subsector->sector)
|
|
||||||
P_RunSpecialSectorCheck(player, sector);
|
|
||||||
|
|
||||||
// Iterate through touching_sectorlist
|
P_PlayerOnSpecial3DFloor(player, originalsector); // Handle FOFs first.
|
||||||
|
if TELEPORTED return;
|
||||||
|
|
||||||
|
P_RunSpecialSectorCheck(player, originalsector);
|
||||||
|
if TELEPORTED return;
|
||||||
|
|
||||||
|
// Iterate through touching_sectorlist for SF_TRIGGERSPECIAL_TOUCH
|
||||||
for (node = player->mo->touching_sectorlist; node; node = node->m_sectorlist_next)
|
for (node = player->mo->touching_sectorlist; node; node = node->m_sectorlist_next)
|
||||||
{
|
{
|
||||||
sector = node->m_sector;
|
loopsector = node->m_sector;
|
||||||
|
|
||||||
if (sector == player->mo->subsector->sector) // Don't duplicate
|
if (loopsector == originalsector) // Don't duplicate
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Check 3D floors...
|
// Check 3D floors...
|
||||||
P_PlayerOnSpecial3DFloor(player, sector);
|
P_PlayerOnSpecial3DFloor(player, loopsector);
|
||||||
|
if TELEPORTED return;
|
||||||
|
|
||||||
if (!(sector->flags & SF_TRIGGERSPECIAL_TOUCH))
|
if (!(loopsector->flags & SF_TRIGGERSPECIAL_TOUCH))
|
||||||
return;
|
continue;
|
||||||
// After P_PlayerOnSpecial3DFloor, recheck if the player is in that sector,
|
|
||||||
// because the player can be teleported in between these times.
|
P_RunSpecialSectorCheck(player, loopsector);
|
||||||
if (sector == player->mo->subsector->sector)
|
if TELEPORTED return;
|
||||||
P_RunSpecialSectorCheck(player, sector);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef TELEPORTED
|
||||||
|
|
||||||
/** Animate planes, scroll walls, etc. and keeps track of level timelimit and exits if time is up.
|
/** Animate planes, scroll walls, etc. and keeps track of level timelimit and exits if time is up.
|
||||||
*
|
*
|
||||||
* \sa P_CheckTimeLimit, P_CheckPointLimit
|
* \sa P_CheckTimeLimit, P_CheckPointLimit
|
||||||
|
|
129
src/p_user.c
129
src/p_user.c
|
@ -1706,9 +1706,8 @@ void P_DoPlayerExit(player_t *player)
|
||||||
#define SPACESPECIAL 12
|
#define SPACESPECIAL 12
|
||||||
boolean P_InSpaceSector(mobj_t *mo) // Returns true if you are in space
|
boolean P_InSpaceSector(mobj_t *mo) // Returns true if you are in space
|
||||||
{
|
{
|
||||||
sector_t *sector;
|
sector_t *sector = mo->subsector->sector;
|
||||||
|
fixed_t topheight, bottomheight;
|
||||||
sector = mo->subsector->sector;
|
|
||||||
|
|
||||||
if (GETSECSPECIAL(sector->special, 1) == SPACESPECIAL)
|
if (GETSECSPECIAL(sector->special, 1) == SPACESPECIAL)
|
||||||
return true;
|
return true;
|
||||||
|
@ -1721,11 +1720,18 @@ boolean P_InSpaceSector(mobj_t *mo) // Returns true if you are in space
|
||||||
{
|
{
|
||||||
if (GETSECSPECIAL(rover->master->frontsector->special, 1) != SPACESPECIAL)
|
if (GETSECSPECIAL(rover->master->frontsector->special, 1) != SPACESPECIAL)
|
||||||
continue;
|
continue;
|
||||||
|
#ifdef ESLOPE
|
||||||
|
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, mo->x, mo->y) : *rover->topheight;
|
||||||
|
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, mo->x, mo->y) : *rover->bottomheight;
|
||||||
|
#else
|
||||||
|
topheight = *rover->topheight;
|
||||||
|
bottomheight = *rover->bottomheight;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (mo->z > *rover->topheight)
|
if (mo->z + (mo->height/2) > topheight)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (mo->z + (mo->height/2) < *rover->bottomheight)
|
if (mo->z + (mo->height/2) < bottomheight)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1737,9 +1743,10 @@ boolean P_InSpaceSector(mobj_t *mo) // Returns true if you are in space
|
||||||
|
|
||||||
boolean P_InQuicksand(mobj_t *mo) // Returns true if you are in quicksand
|
boolean P_InQuicksand(mobj_t *mo) // Returns true if you are in quicksand
|
||||||
{
|
{
|
||||||
sector_t *sector;
|
sector_t *sector = mo->subsector->sector;
|
||||||
|
fixed_t topheight, bottomheight;
|
||||||
|
|
||||||
sector = mo->subsector->sector;
|
fixed_t flipoffset = ((mo->eflags & MFE_VERTICALFLIP) ? (mo->height/2) : 0);
|
||||||
|
|
||||||
if (sector->ffloors)
|
if (sector->ffloors)
|
||||||
{
|
{
|
||||||
|
@ -1753,10 +1760,18 @@ boolean P_InQuicksand(mobj_t *mo) // Returns true if you are in quicksand
|
||||||
if (!(rover->flags & FF_QUICKSAND))
|
if (!(rover->flags & FF_QUICKSAND))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (mo->z > *rover->topheight)
|
#ifdef ESLOPE
|
||||||
|
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, mo->x, mo->y) : *rover->topheight;
|
||||||
|
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, mo->x, mo->y) : *rover->bottomheight;
|
||||||
|
#else
|
||||||
|
topheight = *rover->topheight;
|
||||||
|
bottomheight = *rover->bottomheight;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (mo->z + flipoffset > topheight)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (mo->z + (mo->height/2) < *rover->bottomheight)
|
if (mo->z + (mo->height/2) + flipoffset < bottomheight)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -2067,6 +2082,7 @@ static void P_CheckQuicksand(player_t *player)
|
||||||
{
|
{
|
||||||
ffloor_t *rover;
|
ffloor_t *rover;
|
||||||
fixed_t sinkspeed, friction;
|
fixed_t sinkspeed, friction;
|
||||||
|
fixed_t topheight, bottomheight;
|
||||||
|
|
||||||
if (!(player->mo->subsector->sector->ffloors && player->mo->momz <= 0))
|
if (!(player->mo->subsector->sector->ffloors && player->mo->momz <= 0))
|
||||||
return;
|
return;
|
||||||
|
@ -2078,16 +2094,38 @@ static void P_CheckQuicksand(player_t *player)
|
||||||
if (!(rover->flags & FF_QUICKSAND))
|
if (!(rover->flags & FF_QUICKSAND))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (*rover->topheight >= player->mo->z && *rover->bottomheight < player->mo->z + player->mo->height)
|
#ifdef ESLOPE
|
||||||
|
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight;
|
||||||
|
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight;
|
||||||
|
#else
|
||||||
|
topheight = *rover->topheight;
|
||||||
|
bottomheight = *rover->bottomheight;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (topheight >= player->mo->z && bottomheight < player->mo->z + player->mo->height)
|
||||||
{
|
{
|
||||||
sinkspeed = abs(rover->master->v1->x - rover->master->v2->x)>>1;
|
sinkspeed = abs(rover->master->v1->x - rover->master->v2->x)>>1;
|
||||||
|
|
||||||
sinkspeed = FixedDiv(sinkspeed,TICRATE*FRACUNIT);
|
sinkspeed = FixedDiv(sinkspeed,TICRATE*FRACUNIT);
|
||||||
|
|
||||||
player->mo->z -= sinkspeed;
|
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||||
|
{
|
||||||
|
fixed_t ceilingheight = P_GetCeilingZ(player->mo, player->mo->subsector->sector, player->mo->x, player->mo->y, NULL);
|
||||||
|
|
||||||
if (player->mo->z <= player->mo->subsector->sector->floorheight)
|
player->mo->z += sinkspeed;
|
||||||
player->mo->z = player->mo->subsector->sector->floorheight;
|
|
||||||
|
if (player->mo->z + player->mo->height >= ceilingheight)
|
||||||
|
player->mo->z = ceilingheight - player->mo->height;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fixed_t floorheight = P_GetFloorZ(player->mo, player->mo->subsector->sector, player->mo->x, player->mo->y, NULL);
|
||||||
|
|
||||||
|
player->mo->z -= sinkspeed;
|
||||||
|
|
||||||
|
if (player->mo->z <= floorheight)
|
||||||
|
player->mo->z = floorheight;
|
||||||
|
}
|
||||||
|
|
||||||
friction = abs(rover->master->v1->y - rover->master->v2->y)>>6;
|
friction = abs(rover->master->v1->y - rover->master->v2->y)>>6;
|
||||||
|
|
||||||
|
@ -2437,11 +2475,11 @@ static void P_DoClimbing(player_t *player)
|
||||||
floorclimb = true;
|
floorclimb = true;
|
||||||
|
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight;
|
|
||||||
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight;
|
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight;
|
||||||
|
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight;
|
||||||
#else
|
#else
|
||||||
bottomheight = *rover->bottomheight;
|
|
||||||
topheight = *rover->topheight;
|
topheight = *rover->topheight;
|
||||||
|
bottomheight = *rover->bottomheight;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Only supports rovers that are moving like an 'elevator', not just the top or bottom.
|
// Only supports rovers that are moving like an 'elevator', not just the top or bottom.
|
||||||
|
@ -2630,13 +2668,20 @@ static void P_DoClimbing(player_t *player)
|
||||||
// Is there a FOF directly below that we can move onto?
|
// Is there a FOF directly below that we can move onto?
|
||||||
if (glidesector->sector->ffloors)
|
if (glidesector->sector->ffloors)
|
||||||
{
|
{
|
||||||
|
fixed_t topheight;
|
||||||
ffloor_t *rover;
|
ffloor_t *rover;
|
||||||
for (rover = glidesector->sector->ffloors; rover; rover = rover->next)
|
for (rover = glidesector->sector->ffloors; rover; rover = rover->next)
|
||||||
{
|
{
|
||||||
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
|
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (*rover->topheight > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale))
|
#ifdef ESLOPE
|
||||||
|
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight;
|
||||||
|
#else
|
||||||
|
topheight = *rover->topheight;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (topheight > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale))
|
||||||
{
|
{
|
||||||
foundfof = true;
|
foundfof = true;
|
||||||
break;
|
break;
|
||||||
|
@ -3014,14 +3059,12 @@ static void P_DoTeeter(player_t *player)
|
||||||
{
|
{
|
||||||
if (!(rover->flags & FF_EXISTS)) continue;
|
if (!(rover->flags & FF_EXISTS)) continue;
|
||||||
|
|
||||||
|
#ifdef ESLOPE
|
||||||
|
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight;
|
||||||
|
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight;
|
||||||
|
#else
|
||||||
topheight = *rover->topheight;
|
topheight = *rover->topheight;
|
||||||
bottomheight = *rover->bottomheight;
|
bottomheight = *rover->bottomheight;
|
||||||
|
|
||||||
#ifdef ESLOPE
|
|
||||||
if (*rover->t_slope)
|
|
||||||
topheight = P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y);
|
|
||||||
if (*rover->b_slope)
|
|
||||||
bottomheight = P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (P_CheckSolidLava(player->mo, rover))
|
if (P_CheckSolidLava(player->mo, rover))
|
||||||
|
@ -9007,13 +9050,23 @@ static void P_CalcPostImg(player_t *player)
|
||||||
else if (sector->ffloors)
|
else if (sector->ffloors)
|
||||||
{
|
{
|
||||||
ffloor_t *rover;
|
ffloor_t *rover;
|
||||||
|
fixed_t topheight;
|
||||||
|
fixed_t bottomheight;
|
||||||
|
|
||||||
for (rover = sector->ffloors; rover; rover = rover->next)
|
for (rover = sector->ffloors; rover; rover = rover->next)
|
||||||
{
|
{
|
||||||
if (!(rover->flags & FF_EXISTS))
|
if (!(rover->flags & FF_EXISTS))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (pviewheight >= *rover->topheight || pviewheight <= *rover->bottomheight)
|
#ifdef ESLOPE
|
||||||
|
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight;
|
||||||
|
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight;
|
||||||
|
#else
|
||||||
|
topheight = *rover->topheight;
|
||||||
|
bottomheight = *rover->bottomheight;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (pviewheight >= topheight || pviewheight <= bottomheight)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (P_FindSpecialLineFromTag(13, rover->master->frontsector->tag, -1) != -1)
|
if (P_FindSpecialLineFromTag(13, rover->master->frontsector->tag, -1) != -1)
|
||||||
|
@ -9025,13 +9078,23 @@ static void P_CalcPostImg(player_t *player)
|
||||||
if (sector->ffloors)
|
if (sector->ffloors)
|
||||||
{
|
{
|
||||||
ffloor_t *rover;
|
ffloor_t *rover;
|
||||||
|
fixed_t topheight;
|
||||||
|
fixed_t bottomheight;
|
||||||
|
|
||||||
for (rover = sector->ffloors; rover; rover = rover->next)
|
for (rover = sector->ffloors; rover; rover = rover->next)
|
||||||
{
|
{
|
||||||
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKPLAYER)
|
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKPLAYER)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (pviewheight >= *rover->topheight || pviewheight <= *rover->bottomheight)
|
#ifdef ESLOPE
|
||||||
|
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight;
|
||||||
|
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight;
|
||||||
|
#else
|
||||||
|
topheight = *rover->topheight;
|
||||||
|
bottomheight = *rover->bottomheight;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (pviewheight >= topheight || pviewheight <= bottomheight)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
*type = postimg_water;
|
*type = postimg_water;
|
||||||
|
@ -9137,8 +9200,9 @@ void P_PlayerThink(player_t *player)
|
||||||
if (player->panim != PA_ABILITY)
|
if (player->panim != PA_ABILITY)
|
||||||
P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE);
|
P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE);
|
||||||
}
|
}
|
||||||
else if ((player->pflags & PF_JUMPED && !(player->pflags & PF_NOJUMPDAMAGE))
|
else if ((player->pflags & PF_JUMPED && !(player->pflags & PF_NOJUMPDAMAGE)
|
||||||
&& ((player->charflags & SF_NOJUMPSPIN && player->panim != PA_ROLL)
|
&& (player->mo->state-states != S_PLAY_FLOAT && player->mo->state-states != S_PLAY_FLOAT_RUN))
|
||||||
|
&& ((((player->charflags & (SF_NOJUMPSPIN|SF_NOJUMPDAMAGE)) == (SF_NOJUMPSPIN|SF_NOJUMPDAMAGE)) && player->panim != PA_ROLL)
|
||||||
|| (!(player->charflags & SF_NOJUMPSPIN) && player->panim != PA_JUMP)))
|
|| (!(player->charflags & SF_NOJUMPSPIN) && player->panim != PA_JUMP)))
|
||||||
{
|
{
|
||||||
if (!(player->charflags & SF_NOJUMPSPIN))
|
if (!(player->charflags & SF_NOJUMPSPIN))
|
||||||
|
@ -9262,6 +9326,7 @@ void P_PlayerThink(player_t *player)
|
||||||
// check water content, set stuff in mobj
|
// check water content, set stuff in mobj
|
||||||
P_MobjCheckWater(player->mo);
|
P_MobjCheckWater(player->mo);
|
||||||
|
|
||||||
|
#ifndef SECTORSPECIALSAFTERTHINK
|
||||||
#ifdef POLYOBJECTS
|
#ifdef POLYOBJECTS
|
||||||
if (player->onconveyor != 1 || !P_IsObjectOnGround(player->mo))
|
if (player->onconveyor != 1 || !P_IsObjectOnGround(player->mo))
|
||||||
#endif
|
#endif
|
||||||
|
@ -9270,6 +9335,7 @@ void P_PlayerThink(player_t *player)
|
||||||
|
|
||||||
if (!player->spectator)
|
if (!player->spectator)
|
||||||
P_PlayerInSpecialSector(player);
|
P_PlayerInSpecialSector(player);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (player->playerstate == PST_DEAD)
|
if (player->playerstate == PST_DEAD)
|
||||||
{
|
{
|
||||||
|
@ -9661,6 +9727,17 @@ void P_PlayerAfterThink(player_t *player)
|
||||||
|
|
||||||
cmd = &player->cmd;
|
cmd = &player->cmd;
|
||||||
|
|
||||||
|
#ifdef SECTORSPECIALSAFTERTHINK
|
||||||
|
#ifdef POLYOBJECTS
|
||||||
|
if (player->onconveyor != 1 || !P_IsObjectOnGround(player->mo))
|
||||||
|
#endif
|
||||||
|
player->onconveyor = 0;
|
||||||
|
// check special sectors : damage & secrets
|
||||||
|
|
||||||
|
if (!player->spectator)
|
||||||
|
P_PlayerInSpecialSector(player);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (splitscreen && player == &players[secondarydisplayplayer])
|
if (splitscreen && player == &players[secondarydisplayplayer])
|
||||||
thiscam = &camera2;
|
thiscam = &camera2;
|
||||||
else if (player == &players[displayplayer])
|
else if (player == &players[displayplayer])
|
||||||
|
|
|
@ -1222,6 +1222,9 @@ static void R_Subsector(size_t num)
|
||||||
while (count--)
|
while (count--)
|
||||||
{
|
{
|
||||||
// CONS_Debug(DBG_GAMELOGIC, "Adding normal line %d...(%d)\n", line->linedef-lines, leveltime);
|
// CONS_Debug(DBG_GAMELOGIC, "Adding normal line %d...(%d)\n", line->linedef-lines, leveltime);
|
||||||
|
#ifdef POLYOBJECTS
|
||||||
|
if (!line->polyseg) // ignore segs that belong to polyobjects
|
||||||
|
#endif
|
||||||
R_AddLine(line);
|
R_AddLine(line);
|
||||||
line++;
|
line++;
|
||||||
curline = NULL; /* cph 2001/11/18 - must clear curline now we're done with it, so stuff doesn't try using it for other things */
|
curline = NULL; /* cph 2001/11/18 - must clear curline now we're done with it, so stuff doesn't try using it for other things */
|
||||||
|
|
13
src/r_data.c
13
src/r_data.c
|
@ -1151,23 +1151,24 @@ static void R_InitExtraColormaps(void)
|
||||||
for (cfile = clump = 0; cfile < numwadfiles; cfile++, clump = 0)
|
for (cfile = clump = 0; cfile < numwadfiles; cfile++, clump = 0)
|
||||||
{
|
{
|
||||||
startnum = W_CheckNumForNamePwad("C_START", cfile, clump);
|
startnum = W_CheckNumForNamePwad("C_START", cfile, clump);
|
||||||
if (startnum == LUMPERROR)
|
if (startnum == INT16_MAX)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
endnum = W_CheckNumForNamePwad("C_END", cfile, clump);
|
endnum = W_CheckNumForNamePwad("C_END", cfile, clump);
|
||||||
|
|
||||||
if (endnum == LUMPERROR)
|
if (endnum == INT16_MAX)
|
||||||
I_Error("R_InitExtraColormaps: C_START without C_END\n");
|
I_Error("R_InitExtraColormaps: C_START without C_END\n");
|
||||||
|
|
||||||
if (WADFILENUM(startnum) != WADFILENUM(endnum))
|
// This shouldn't be possible when you use the Pwad function, silly
|
||||||
I_Error("R_InitExtraColormaps: C_START and C_END in different wad files!\n");
|
//if (WADFILENUM(startnum) != WADFILENUM(endnum))
|
||||||
|
//I_Error("R_InitExtraColormaps: C_START and C_END in different wad files!\n");
|
||||||
|
|
||||||
if (numcolormaplumps >= maxcolormaplumps)
|
if (numcolormaplumps >= maxcolormaplumps)
|
||||||
maxcolormaplumps *= 2;
|
maxcolormaplumps *= 2;
|
||||||
colormaplumps = Z_Realloc(colormaplumps,
|
colormaplumps = Z_Realloc(colormaplumps,
|
||||||
sizeof (*colormaplumps) * maxcolormaplumps, PU_STATIC, NULL);
|
sizeof (*colormaplumps) * maxcolormaplumps, PU_STATIC, NULL);
|
||||||
colormaplumps[numcolormaplumps].wadfile = WADFILENUM(startnum);
|
colormaplumps[numcolormaplumps].wadfile = cfile;
|
||||||
colormaplumps[numcolormaplumps].firstlump = LUMPNUM(startnum+1);
|
colormaplumps[numcolormaplumps].firstlump = startnum+1;
|
||||||
colormaplumps[numcolormaplumps].numlumps = endnum - (startnum + 1);
|
colormaplumps[numcolormaplumps].numlumps = endnum - (startnum + 1);
|
||||||
numcolormaplumps++;
|
numcolormaplumps++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -590,70 +590,78 @@ static BOOL I_ReadyConsole(HANDLE ci)
|
||||||
|
|
||||||
static boolean entering_con_command = false;
|
static boolean entering_con_command = false;
|
||||||
|
|
||||||
|
static void Impl_HandleKeyboardConsoleEvent(KEY_EVENT_RECORD evt, HANDLE co)
|
||||||
|
{
|
||||||
|
event_t event;
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO CSBI;
|
||||||
|
DWORD t;
|
||||||
|
|
||||||
|
memset(&event,0x00,sizeof (event));
|
||||||
|
|
||||||
|
if (evt.bKeyDown)
|
||||||
|
{
|
||||||
|
event.type = ev_console;
|
||||||
|
entering_con_command = true;
|
||||||
|
switch (evt.wVirtualKeyCode)
|
||||||
|
{
|
||||||
|
case VK_ESCAPE:
|
||||||
|
case VK_TAB:
|
||||||
|
event.data1 = KEY_NULL;
|
||||||
|
break;
|
||||||
|
case VK_SHIFT:
|
||||||
|
event.data1 = KEY_LSHIFT;
|
||||||
|
break;
|
||||||
|
case VK_RETURN:
|
||||||
|
entering_con_command = false;
|
||||||
|
// Fall through.
|
||||||
|
default:
|
||||||
|
event.data1 = MapVirtualKey(evt.wVirtualKeyCode,2); // convert in to char
|
||||||
|
}
|
||||||
|
if (co != INVALID_HANDLE_VALUE && GetFileType(co) == FILE_TYPE_CHAR && GetConsoleMode(co, &t))
|
||||||
|
{
|
||||||
|
if (event.data1 && event.data1 != KEY_LSHIFT && event.data1 != KEY_RSHIFT)
|
||||||
|
{
|
||||||
|
#ifdef _UNICODE
|
||||||
|
WriteConsole(co, &evt.uChar.UnicodeChar, 1, &t, NULL);
|
||||||
|
#else
|
||||||
|
WriteConsole(co, &evt.uChar.AsciiChar, 1 , &t, NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (evt.wVirtualKeyCode == VK_BACK
|
||||||
|
&& GetConsoleScreenBufferInfo(co,&CSBI))
|
||||||
|
{
|
||||||
|
WriteConsoleOutputCharacterA(co, " ",1, CSBI.dwCursorPosition, &t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
event.type = ev_keyup;
|
||||||
|
switch (evt.wVirtualKeyCode)
|
||||||
|
{
|
||||||
|
case VK_SHIFT:
|
||||||
|
event.data1 = KEY_LSHIFT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (event.data1) D_PostEvent(&event);
|
||||||
|
}
|
||||||
|
|
||||||
void I_GetConsoleEvents(void)
|
void I_GetConsoleEvents(void)
|
||||||
{
|
{
|
||||||
event_t ev = {0,0,0,0};
|
|
||||||
HANDLE ci = GetStdHandle(STD_INPUT_HANDLE);
|
HANDLE ci = GetStdHandle(STD_INPUT_HANDLE);
|
||||||
HANDLE co = GetStdHandle(STD_OUTPUT_HANDLE);
|
HANDLE co = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
CONSOLE_SCREEN_BUFFER_INFO CSBI;
|
|
||||||
INPUT_RECORD input;
|
INPUT_RECORD input;
|
||||||
DWORD t;
|
DWORD t;
|
||||||
|
|
||||||
while (I_ReadyConsole(ci) && ReadConsoleInput(ci, &input, 1, &t) && t)
|
while (I_ReadyConsole(ci) && ReadConsoleInput(ci, &input, 1, &t) && t)
|
||||||
{
|
{
|
||||||
memset(&ev,0x00,sizeof (ev));
|
|
||||||
switch (input.EventType)
|
switch (input.EventType)
|
||||||
{
|
{
|
||||||
case KEY_EVENT:
|
case KEY_EVENT:
|
||||||
if (input.Event.KeyEvent.bKeyDown)
|
Impl_HandleKeyboardConsoleEvent(input.Event.KeyEvent, co);
|
||||||
{
|
|
||||||
ev.type = ev_console;
|
|
||||||
entering_con_command = true;
|
|
||||||
switch (input.Event.KeyEvent.wVirtualKeyCode)
|
|
||||||
{
|
|
||||||
case VK_ESCAPE:
|
|
||||||
case VK_TAB:
|
|
||||||
ev.data1 = KEY_NULL;
|
|
||||||
break;
|
|
||||||
case VK_SHIFT:
|
|
||||||
ev.data1 = KEY_LSHIFT;
|
|
||||||
break;
|
|
||||||
case VK_RETURN:
|
|
||||||
entering_con_command = false;
|
|
||||||
// Fall through.
|
|
||||||
default:
|
|
||||||
ev.data1 = MapVirtualKey(input.Event.KeyEvent.wVirtualKeyCode,2); // convert in to char
|
|
||||||
}
|
|
||||||
if (co != INVALID_HANDLE_VALUE && GetFileType(co) == FILE_TYPE_CHAR && GetConsoleMode(co, &t))
|
|
||||||
{
|
|
||||||
if (ev.data1 && ev.data1 != KEY_LSHIFT && ev.data1 != KEY_RSHIFT)
|
|
||||||
{
|
|
||||||
#ifdef _UNICODE
|
|
||||||
WriteConsole(co, &input.Event.KeyEvent.uChar.UnicodeChar, 1, &t, NULL);
|
|
||||||
#else
|
|
||||||
WriteConsole(co, &input.Event.KeyEvent.uChar.AsciiChar, 1 , &t, NULL);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
if (input.Event.KeyEvent.wVirtualKeyCode == VK_BACK
|
|
||||||
&& GetConsoleScreenBufferInfo(co,&CSBI))
|
|
||||||
{
|
|
||||||
WriteConsoleOutputCharacterA(co, " ",1, CSBI.dwCursorPosition, &t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ev.type = ev_keyup;
|
|
||||||
switch (input.Event.KeyEvent.wVirtualKeyCode)
|
|
||||||
{
|
|
||||||
case VK_SHIFT:
|
|
||||||
ev.data1 = KEY_LSHIFT;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ev.data1) D_PostEvent(&ev);
|
|
||||||
break;
|
break;
|
||||||
case MOUSE_EVENT:
|
case MOUSE_EVENT:
|
||||||
case WINDOW_BUFFER_SIZE_EVENT:
|
case WINDOW_BUFFER_SIZE_EVENT:
|
||||||
|
|
|
@ -158,7 +158,7 @@ static INT32 windowedModes[MAXWINMODES][2] =
|
||||||
static void Impl_VideoSetupSDLBuffer(void);
|
static void Impl_VideoSetupSDLBuffer(void);
|
||||||
static void Impl_VideoSetupBuffer(void);
|
static void Impl_VideoSetupBuffer(void);
|
||||||
static SDL_bool Impl_CreateWindow(SDL_bool fullscreen);
|
static SDL_bool Impl_CreateWindow(SDL_bool fullscreen);
|
||||||
static void Impl_SetWindowName(const char *title);
|
//static void Impl_SetWindowName(const char *title);
|
||||||
static void Impl_SetWindowIcon(void);
|
static void Impl_SetWindowIcon(void);
|
||||||
|
|
||||||
static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen)
|
static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen)
|
||||||
|
@ -181,15 +181,13 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen)
|
||||||
wasfullscreen = SDL_TRUE;
|
wasfullscreen = SDL_TRUE;
|
||||||
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||||
}
|
}
|
||||||
else if (wasfullscreen)
|
else // windowed mode
|
||||||
{
|
|
||||||
wasfullscreen = SDL_FALSE;
|
|
||||||
SDL_SetWindowFullscreen(window, 0);
|
|
||||||
SDL_SetWindowSize(window, width, height);
|
|
||||||
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED_DISPLAY(1), SDL_WINDOWPOS_CENTERED_DISPLAY(1));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
if (wasfullscreen)
|
||||||
|
{
|
||||||
|
wasfullscreen = SDL_FALSE;
|
||||||
|
SDL_SetWindowFullscreen(window, 0);
|
||||||
|
}
|
||||||
// Reposition window only in windowed mode
|
// Reposition window only in windowed mode
|
||||||
SDL_SetWindowSize(window, width, height);
|
SDL_SetWindowSize(window, width, height);
|
||||||
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED_DISPLAY(1), SDL_WINDOWPOS_CENTERED_DISPLAY(1));
|
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED_DISPLAY(1), SDL_WINDOWPOS_CENTERED_DISPLAY(1));
|
||||||
|
@ -899,7 +897,7 @@ static inline boolean I_SkipFrame(void)
|
||||||
{
|
{
|
||||||
static boolean skip = false;
|
static boolean skip = false;
|
||||||
|
|
||||||
if (render_soft != rendermode)
|
if (rendermode != render_soft)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
skip = !skip;
|
skip = !skip;
|
||||||
|
@ -935,7 +933,7 @@ void I_FinishUpdate(void)
|
||||||
if (cv_ticrate.value)
|
if (cv_ticrate.value)
|
||||||
SCR_DisplayTicRate();
|
SCR_DisplayTicRate();
|
||||||
|
|
||||||
if (render_soft == rendermode && screens[0])
|
if (rendermode == render_soft && screens[0])
|
||||||
{
|
{
|
||||||
SDL_Rect rect;
|
SDL_Rect rect;
|
||||||
|
|
||||||
|
@ -962,7 +960,7 @@ void I_FinishUpdate(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
else
|
else if (rendermode == render_opengl)
|
||||||
{
|
{
|
||||||
OglSdlFinishUpdate(cv_vidwait.value);
|
OglSdlFinishUpdate(cv_vidwait.value);
|
||||||
}
|
}
|
||||||
|
@ -1190,11 +1188,11 @@ INT32 VID_SetMode(INT32 modeNum)
|
||||||
}
|
}
|
||||||
vid.modenum = -1;
|
vid.modenum = -1;
|
||||||
}
|
}
|
||||||
Impl_SetWindowName("SRB2 "VERSIONSTRING);
|
//Impl_SetWindowName("SRB2 "VERSIONSTRING);
|
||||||
|
|
||||||
SDLSetMode(windowedModes[modeNum][0], windowedModes[modeNum][1], USE_FULLSCREEN);
|
SDLSetMode(vid.width, vid.height, USE_FULLSCREEN);
|
||||||
|
|
||||||
if (render_soft == rendermode)
|
if (rendermode == render_soft)
|
||||||
{
|
{
|
||||||
if (bufSurface)
|
if (bufSurface)
|
||||||
{
|
{
|
||||||
|
@ -1213,30 +1211,20 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen)
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
|
||||||
if (rendermode == render_none) // dedicated
|
if (rendermode == render_none) // dedicated
|
||||||
{
|
|
||||||
return SDL_TRUE; // Monster Iestyn -- not sure if it really matters what we return here tbh
|
return SDL_TRUE; // Monster Iestyn -- not sure if it really matters what we return here tbh
|
||||||
}
|
|
||||||
|
|
||||||
if (window != NULL)
|
if (window != NULL)
|
||||||
{
|
|
||||||
return SDL_FALSE;
|
return SDL_FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
if (fullscreen)
|
if (fullscreen)
|
||||||
{
|
|
||||||
flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||||
}
|
|
||||||
|
|
||||||
if (borderlesswindow)
|
if (borderlesswindow)
|
||||||
{
|
|
||||||
flags |= SDL_WINDOW_BORDERLESS;
|
flags |= SDL_WINDOW_BORDERLESS;
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
if (rendermode == render_opengl)
|
if (rendermode == render_opengl)
|
||||||
{
|
|
||||||
flags |= SDL_WINDOW_OPENGL;
|
flags |= SDL_WINDOW_OPENGL;
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Create a window
|
// Create a window
|
||||||
|
@ -1265,7 +1253,13 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen)
|
||||||
#endif
|
#endif
|
||||||
if (rendermode == render_soft)
|
if (rendermode == render_soft)
|
||||||
{
|
{
|
||||||
renderer = SDL_CreateRenderer(window, -1, (usesdl2soft ? SDL_RENDERER_SOFTWARE : 0) | (cv_vidwait.value && !usesdl2soft ? SDL_RENDERER_PRESENTVSYNC : 0));
|
flags = 0; // Use this to set SDL_RENDERER_* flags now
|
||||||
|
if (usesdl2soft)
|
||||||
|
flags |= SDL_RENDERER_SOFTWARE;
|
||||||
|
else if (cv_vidwait.value)
|
||||||
|
flags |= SDL_RENDERER_PRESENTVSYNC;
|
||||||
|
|
||||||
|
renderer = SDL_CreateRenderer(window, -1, flags);
|
||||||
if (renderer == NULL)
|
if (renderer == NULL)
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("Couldn't create rendering context: %s\n"), SDL_GetError());
|
CONS_Printf(M_GetText("Couldn't create rendering context: %s\n"), SDL_GetError());
|
||||||
|
@ -1277,14 +1271,16 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen)
|
||||||
return SDL_TRUE;
|
return SDL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
static void Impl_SetWindowName(const char *title)
|
static void Impl_SetWindowName(const char *title)
|
||||||
{
|
{
|
||||||
if (window != NULL)
|
if (window == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SDL_SetWindowTitle(window, title);
|
SDL_SetWindowTitle(window, title);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
static void Impl_SetWindowIcon(void)
|
static void Impl_SetWindowIcon(void)
|
||||||
{
|
{
|
||||||
|
@ -1487,7 +1483,7 @@ void I_ShutdownGraphics(void)
|
||||||
rendermode = render_none;
|
rendermode = render_none;
|
||||||
if (icoSurface) SDL_FreeSurface(icoSurface);
|
if (icoSurface) SDL_FreeSurface(icoSurface);
|
||||||
icoSurface = NULL;
|
icoSurface = NULL;
|
||||||
if (render_soft == oldrendermode)
|
if (oldrendermode == render_soft)
|
||||||
{
|
{
|
||||||
if (vidSurface) SDL_FreeSurface(vidSurface);
|
if (vidSurface) SDL_FreeSurface(vidSurface);
|
||||||
vidSurface = NULL;
|
vidSurface = NULL;
|
||||||
|
|
|
@ -1214,7 +1214,7 @@
|
||||||
C01FCF4B08A954540054247B /* Debug */ = {
|
C01FCF4B08A954540054247B /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CURRENT_PROJECT_VERSION = 2.1.18;
|
CURRENT_PROJECT_VERSION = 2.1.19;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
NORMALSRB2,
|
NORMALSRB2,
|
||||||
|
@ -1226,7 +1226,7 @@
|
||||||
C01FCF4C08A954540054247B /* Release */ = {
|
C01FCF4C08A954540054247B /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CURRENT_PROJECT_VERSION = 2.1.18;
|
CURRENT_PROJECT_VERSION = 2.1.19;
|
||||||
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
||||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
|
|
@ -71,7 +71,6 @@ INT32 oglflags = 0;
|
||||||
void *GLUhandle = NULL;
|
void *GLUhandle = NULL;
|
||||||
SDL_GLContext sdlglcontext = 0;
|
SDL_GLContext sdlglcontext = 0;
|
||||||
|
|
||||||
#ifndef STATIC_OPENGL
|
|
||||||
void *GetGLFunc(const char *proc)
|
void *GetGLFunc(const char *proc)
|
||||||
{
|
{
|
||||||
if (strncmp(proc, "glu", 3) == 0)
|
if (strncmp(proc, "glu", 3) == 0)
|
||||||
|
@ -83,7 +82,6 @@ void *GetGLFunc(const char *proc)
|
||||||
}
|
}
|
||||||
return SDL_GL_GetProcAddress(proc);
|
return SDL_GL_GetProcAddress(proc);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
boolean LoadGL(void)
|
boolean LoadGL(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1214,7 +1214,7 @@
|
||||||
C01FCF4B08A954540054247B /* Debug */ = {
|
C01FCF4B08A954540054247B /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CURRENT_PROJECT_VERSION = 2.1.18;
|
CURRENT_PROJECT_VERSION = 2.1.19;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
NORMALSRB2,
|
NORMALSRB2,
|
||||||
|
@ -1226,7 +1226,7 @@
|
||||||
C01FCF4C08A954540054247B /* Release */ = {
|
C01FCF4C08A954540054247B /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CURRENT_PROJECT_VERSION = 2.1.18;
|
CURRENT_PROJECT_VERSION = 2.1.19;
|
||||||
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
||||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
|
|
@ -180,9 +180,9 @@ static LPSTR hms(UINT seconds)
|
||||||
hours = minutes / 60;
|
hours = minutes / 60;
|
||||||
minutes %= 60;
|
minutes %= 60;
|
||||||
if (hours > 0)
|
if (hours > 0)
|
||||||
sprintf (s, "%lu:%02lu:%02lu", hours, minutes, seconds);
|
sprintf (s, "%lu:%02lu:%02lu", (long unsigned int)hours, (long unsigned int)minutes, (long unsigned int)seconds);
|
||||||
else
|
else
|
||||||
sprintf (s, "%2lu:%02lu", minutes, seconds);
|
sprintf (s, "%2lu:%02lu", (long unsigned int)minutes, (long unsigned int)seconds);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -470,7 +470,7 @@ static inline BOOL tlErrorMessage(const TCHAR *err)
|
||||||
//
|
//
|
||||||
// warn user if there is one
|
// warn user if there is one
|
||||||
//
|
//
|
||||||
printf("Error %Ts..\n", err);
|
printf("Error %s..\n", err);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
MessageBox(hWndMain, err, TEXT("ERROR"), MB_OK);
|
MessageBox(hWndMain, err, TEXT("ERROR"), MB_OK);
|
||||||
|
|
|
@ -160,6 +160,20 @@ static void Y_CalculateMatchWinners(void);
|
||||||
static void Y_FollowIntermission(void);
|
static void Y_FollowIntermission(void);
|
||||||
static void Y_UnloadData(void);
|
static void Y_UnloadData(void);
|
||||||
|
|
||||||
|
// Stuff copy+pasted from st_stuff.c
|
||||||
|
static INT32 SCX(INT32 x)
|
||||||
|
{
|
||||||
|
return FixedInt(FixedMul(x<<FRACBITS, vid.fdupx));
|
||||||
|
}
|
||||||
|
static INT32 SCY(INT32 z)
|
||||||
|
{
|
||||||
|
return FixedInt(FixedMul(z<<FRACBITS, vid.fdupy));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ST_DrawNumFromHud(h,n) V_DrawTallNum(SCX(hudinfo[h].x), SCY(hudinfo[h].y), V_NOSCALESTART, n)
|
||||||
|
#define ST_DrawPadNumFromHud(h,n,q) V_DrawPaddedTallNum(SCX(hudinfo[h].x), SCY(hudinfo[h].y), V_NOSCALESTART, n, q)
|
||||||
|
#define ST_DrawPatchFromHud(h,p) V_DrawScaledPatch(SCX(hudinfo[h].x), SCY(hudinfo[h].y), V_NOSCALESTART, p)
|
||||||
|
|
||||||
static void Y_IntermissionTokenDrawer(void)
|
static void Y_IntermissionTokenDrawer(void)
|
||||||
{
|
{
|
||||||
INT32 y;
|
INT32 y;
|
||||||
|
@ -242,28 +256,31 @@ void Y_IntermissionDrawer(void)
|
||||||
Y_IntermissionTokenDrawer();
|
Y_IntermissionTokenDrawer();
|
||||||
|
|
||||||
// draw score
|
// draw score
|
||||||
V_DrawScaledPatch(hudinfo[HUD_SCORE].x, hudinfo[HUD_SCORE].y, V_SNAPTOLEFT, sboscore);
|
ST_DrawPatchFromHud(HUD_SCORE, sboscore);
|
||||||
V_DrawTallNum(hudinfo[HUD_SCORENUM].x, hudinfo[HUD_SCORENUM].y, V_SNAPTOLEFT, data.coop.score);
|
ST_DrawNumFromHud(HUD_SCORENUM, data.coop.score);
|
||||||
|
|
||||||
// draw time
|
// draw time
|
||||||
V_DrawScaledPatch(hudinfo[HUD_TIME].x, hudinfo[HUD_TIME].y, V_SNAPTOLEFT, sbotime);
|
ST_DrawPatchFromHud(HUD_TIME, sbotime);
|
||||||
if (cv_timetic.value == 1)
|
if (cv_timetic.value == 1)
|
||||||
V_DrawTallNum(hudinfo[HUD_SECONDS].x, hudinfo[HUD_SECONDS].y, V_SNAPTOLEFT, data.coop.tics);
|
ST_DrawNumFromHud(HUD_SECONDS, data.coop.tics);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
INT32 seconds, minutes, tictrn;
|
||||||
|
|
||||||
|
seconds = G_TicsToSeconds(data.coop.tics);
|
||||||
|
minutes = G_TicsToMinutes(data.coop.tics, true);
|
||||||
|
tictrn = G_TicsToCentiseconds(data.coop.tics);
|
||||||
|
|
||||||
|
ST_DrawNumFromHud(HUD_MINUTES, minutes); // Minutes
|
||||||
|
ST_DrawPatchFromHud(HUD_TIMECOLON, sbocolon); // Colon
|
||||||
|
ST_DrawPadNumFromHud(HUD_SECONDS, seconds, 2); // Seconds
|
||||||
|
|
||||||
// we should show centiseconds on the intermission screen too, if the conditions are right.
|
// we should show centiseconds on the intermission screen too, if the conditions are right.
|
||||||
if (modeattacking || cv_timetic.value == 2)
|
if (modeattacking || cv_timetic.value == 2)
|
||||||
{
|
{
|
||||||
V_DrawPaddedTallNum(hudinfo[HUD_TICS].x, hudinfo[HUD_TICS].y, V_SNAPTOLEFT,
|
ST_DrawPatchFromHud(HUD_TIMETICCOLON, sboperiod); // Period
|
||||||
G_TicsToCentiseconds(data.coop.tics), 2);
|
ST_DrawPadNumFromHud(HUD_TICS, tictrn, 2); // Tics
|
||||||
V_DrawScaledPatch(hudinfo[HUD_TIMETICCOLON].x, hudinfo[HUD_TIMETICCOLON].y, V_SNAPTOLEFT, sboperiod);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
V_DrawPaddedTallNum(hudinfo[HUD_SECONDS].x, hudinfo[HUD_SECONDS].y, V_SNAPTOLEFT,
|
|
||||||
G_TicsToSeconds(data.coop.tics), 2);
|
|
||||||
V_DrawScaledPatch(hudinfo[HUD_TIMECOLON].x, hudinfo[HUD_TIMECOLON].y, V_SNAPTOLEFT, sbocolon);
|
|
||||||
V_DrawTallNum(hudinfo[HUD_MINUTES].x, hudinfo[HUD_MINUTES].y, V_SNAPTOLEFT,
|
|
||||||
G_TicsToMinutes(data.coop.tics, false));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw the "got through act" lines and act number
|
// draw the "got through act" lines and act number
|
||||||
|
@ -1008,7 +1025,8 @@ void Y_StartIntermission(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We couldn't display the intermission even if we wanted to.
|
// We couldn't display the intermission even if we wanted to.
|
||||||
if (dedicated) return;
|
// But we still need to give the players their score bonuses, dummy.
|
||||||
|
//if (dedicated) return;
|
||||||
|
|
||||||
// This should always exist, but just in case...
|
// This should always exist, but just in case...
|
||||||
if(!mapheaderinfo[prevmap])
|
if(!mapheaderinfo[prevmap])
|
||||||
|
@ -1823,37 +1841,6 @@ void Y_EndIntermission(void)
|
||||||
usebuffer = false;
|
usebuffer = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Y_EndGame
|
|
||||||
//
|
|
||||||
// Why end the game?
|
|
||||||
// Because Y_FollowIntermission and F_EndCutscene would
|
|
||||||
// both do this exact same thing *in different ways* otherwise,
|
|
||||||
// which made it so that you could only unlock Ultimate mode
|
|
||||||
// if you had a cutscene after the final level and crap like that.
|
|
||||||
// This function simplifies it so only one place has to be updated
|
|
||||||
// when something new is added.
|
|
||||||
void Y_EndGame(void)
|
|
||||||
{
|
|
||||||
// Only do evaluation and credits in coop games.
|
|
||||||
if (gametype == GT_COOP)
|
|
||||||
{
|
|
||||||
if (nextmap == 1102-1) // end game with credits
|
|
||||||
{
|
|
||||||
F_StartCredits();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (nextmap == 1101-1) // end game with evaluation
|
|
||||||
{
|
|
||||||
F_StartGameEvaluation();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1100 or competitive multiplayer, so go back to title screen.
|
|
||||||
D_StartTitle();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Y_FollowIntermission
|
// Y_FollowIntermission
|
||||||
//
|
//
|
||||||
|
@ -1865,21 +1852,10 @@ static void Y_FollowIntermission(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextmap < 1100-1)
|
// This handles whether to play a post-level cutscene, end the game,
|
||||||
{
|
// or simply go to the next level.
|
||||||
// normal level
|
// No need to duplicate the code here!
|
||||||
G_AfterIntermission();
|
G_AfterIntermission();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start a custom cutscene if there is one.
|
|
||||||
if (mapheaderinfo[gamemap-1]->cutscenenum && !modeattacking)
|
|
||||||
{
|
|
||||||
F_StartCustomCutscene(mapheaderinfo[gamemap-1]->cutscenenum-1, false, false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Y_EndGame();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define UNLOAD(x) Z_ChangeTag(x, PU_CACHE); x = NULL
|
#define UNLOAD(x) Z_ChangeTag(x, PU_CACHE); x = NULL
|
||||||
|
|
|
@ -15,7 +15,6 @@ void Y_IntermissionDrawer(void);
|
||||||
void Y_Ticker(void);
|
void Y_Ticker(void);
|
||||||
void Y_StartIntermission(void);
|
void Y_StartIntermission(void);
|
||||||
void Y_EndIntermission(void);
|
void Y_EndIntermission(void);
|
||||||
void Y_EndGame(void);
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue