mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-01-31 13:40:45 +00:00
Merge branch 'next' of git@git.magicalgirl.moe:STJr/SRB2.git into dye
This commit is contained in:
commit
80edefa56e
87 changed files with 3580 additions and 2134 deletions
|
@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0)
|
|||
# DO NOT CHANGE THIS SRB2 STRING! Some variable names depend on this string.
|
||||
# Version change is fine.
|
||||
project(SRB2
|
||||
VERSION 2.2.0
|
||||
VERSION 2.2.1
|
||||
LANGUAGES C)
|
||||
|
||||
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})
|
||||
|
|
17
appveyor.yml
17
appveyor.yml
|
@ -1,4 +1,4 @@
|
|||
version: 2.2.0.{branch}-{build}
|
||||
version: 2.2.1.{branch}-{build}
|
||||
os: MinGW
|
||||
|
||||
environment:
|
||||
|
@ -83,7 +83,14 @@ before_build:
|
|||
- ccache -V
|
||||
- ccache -s
|
||||
- if [%NOUPX%] == [1] ( set "NOUPX=NOUPX=1" ) else ( set "NOUPX=" )
|
||||
- set "SRB2_MFLAGS=-C src WARNINGMODE=1 CCACHE=1 NOOBJDUMP=1 %NOUPX%"
|
||||
- if defined [%APPVEYOR_PULL_REQUEST_HEAD_COMMIT%] ( set "COMMIT=%APPVEYOR_PULL_REQUEST_HEAD_COMMIT%" ) else ( set "COMMIT=%APPVEYOR_REPO_COMMIT%" )
|
||||
- cmd: git rev-parse --short %COMMIT%>%TMP%/gitshort.txt
|
||||
- cmd: set /P GITSHORT=<%TMP%/gitshort.txt
|
||||
# for pull requests, take the owner's name only, if this isn't the same repo of course
|
||||
- set "REPO=%APPVEYOR_REPO_BRANCH%"
|
||||
- if not [%APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME%] == [] ( if not [%APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME%] == [%APPVEYOR_REPO_NAME%] ( for /f "delims=/" %%a in ("%APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME%") do set "REPO=%%a-%APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH%" ) )
|
||||
- set "EXENAME=EXENAME=srb2win-%REPO%-%GITSHORT%.exe"
|
||||
- set "SRB2_MFLAGS=-C src WARNINGMODE=1 CCACHE=1 NOOBJDUMP=1 %NOUPX% %EXENAME%"
|
||||
- if [%X86_64%] == [1] ( set "MINGW_FLAGS=MINGW64=1 X86_64=1 GCC81=1" ) else ( set "MINGW_FLAGS=MINGW=1 GCC91=1" )
|
||||
- set "SRB2_MFLAGS=%SRB2_MFLAGS% %MINGW_FLAGS% %CONFIGURATION%=1"
|
||||
|
||||
|
@ -99,10 +106,8 @@ after_build:
|
|||
)
|
||||
- if [%X86_64%] == [1] ( set "CONFIGURATION=%CONFIGURATION%64" )
|
||||
- ccache -s
|
||||
- cmd: git rev-parse --short %APPVEYOR_REPO_COMMIT%>%TMP%/gitshort.txt
|
||||
- cmd: set /P GITSHORT=<%TMP%/gitshort.txt
|
||||
- set BUILD_ARCHIVE=%APPVEYOR_REPO_BRANCH%-%GITSHORT%-%CONFIGURATION%.7z
|
||||
- set BUILDSARCHIVE=%APPVEYOR_REPO_BRANCH%-%CONFIGURATION%.7z
|
||||
- set BUILD_ARCHIVE=%REPO%-%GITSHORT%-%CONFIGURATION%.7z
|
||||
- set BUILDSARCHIVE=%REPO%-%CONFIGURATION%.7z
|
||||
- cmd: 7z a %BUILD_ARCHIVE% %BUILD_PATH% -xr!.gitignore
|
||||
- appveyor PushArtifact %BUILD_ARCHIVE%
|
||||
- cmd: copy %BUILD_ARCHIVE% %BUILDSARCHIVE%
|
||||
|
|
124
src/am_map.c
124
src/am_map.c
|
@ -160,6 +160,7 @@ static boolean am_stopped = true;
|
|||
static INT32 f_x, f_y; // location of window on screen (always zero for both)
|
||||
static INT32 f_w, f_h; // size of window on screen (always the screen width and height respectively)
|
||||
|
||||
static boolean m_keydown[4]; // which window panning keys are being pressed down?
|
||||
static mpoint_t m_paninc; // how far the window pans each tic (map coords)
|
||||
static fixed_t mtof_zoommul; // how far the window zooms in each tic (map coords)
|
||||
static fixed_t ftom_zoommul; // how far the window zooms in each tic (fb coords)
|
||||
|
@ -205,6 +206,7 @@ static boolean followplayer = true; // specifies whether to follow the player ar
|
|||
typedef void (*AMDRAWFLINEFUNC) (const fline_t *fl, INT32 color);
|
||||
static AMDRAWFLINEFUNC AM_drawFline;
|
||||
|
||||
static void AM_drawPixel(INT32 xx, INT32 yy, INT32 cc);
|
||||
static void AM_drawFline_soft(const fline_t *fl, INT32 color);
|
||||
|
||||
static void AM_activateNewScale(void)
|
||||
|
@ -344,22 +346,22 @@ static void AM_initVariables(void)
|
|||
old_m_h = m_h;
|
||||
}
|
||||
|
||||
//
|
||||
// Called when the screen size changes.
|
||||
//
|
||||
static void AM_FrameBufferInit(void)
|
||||
{
|
||||
f_x = f_y = 0;
|
||||
f_w = vid.width;
|
||||
f_h = vid.height;
|
||||
}
|
||||
|
||||
//
|
||||
// should be called at the start of every level
|
||||
// right now, i figure it out myself
|
||||
//
|
||||
static void AM_LevelInit(void)
|
||||
{
|
||||
f_x = f_y = 0;
|
||||
f_w = vid.width;
|
||||
f_h = vid.height;
|
||||
|
||||
AM_drawFline = AM_drawFline_soft;
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
AM_drawFline = HWR_drawAMline;
|
||||
#endif
|
||||
|
||||
AM_findMinMaxBoundaries();
|
||||
scale_mtof = FixedDiv(min_scale_mtof*10, 7*FRACUNIT);
|
||||
if (scale_mtof > max_scale_mtof)
|
||||
|
@ -381,7 +383,7 @@ void AM_Stop(void)
|
|||
*
|
||||
* \sa AM_Stop
|
||||
*/
|
||||
static inline void AM_Start(void)
|
||||
void AM_Start(void)
|
||||
{
|
||||
static INT32 lastlevel = -1;
|
||||
|
||||
|
@ -390,8 +392,12 @@ static inline void AM_Start(void)
|
|||
am_stopped = false;
|
||||
if (lastlevel != gamemap || am_recalc) // screen size changed
|
||||
{
|
||||
AM_LevelInit();
|
||||
lastlevel = gamemap;
|
||||
AM_FrameBufferInit();
|
||||
if (lastlevel != gamemap)
|
||||
{
|
||||
AM_LevelInit();
|
||||
lastlevel = gamemap;
|
||||
}
|
||||
am_recalc = false;
|
||||
}
|
||||
AM_initVariables();
|
||||
|
@ -417,6 +423,28 @@ static void AM_maxOutWindowScale(void)
|
|||
AM_activateNewScale();
|
||||
}
|
||||
|
||||
//
|
||||
// set window panning
|
||||
//
|
||||
static void AM_setWindowPanning(void)
|
||||
{
|
||||
// up and down
|
||||
if (m_keydown[2]) // pan up
|
||||
m_paninc.y = FTOM(F_PANINC);
|
||||
else if (m_keydown[3]) // pan down
|
||||
m_paninc.y = -FTOM(F_PANINC);
|
||||
else
|
||||
m_paninc.y = 0;
|
||||
|
||||
// left and right
|
||||
if (m_keydown[0]) // pan right
|
||||
m_paninc.x = FTOM(F_PANINC);
|
||||
else if (m_keydown[1]) // pan left
|
||||
m_paninc.x = -FTOM(F_PANINC);
|
||||
else
|
||||
m_paninc.x = 0;
|
||||
}
|
||||
|
||||
/** Responds to user inputs in automap mode.
|
||||
*
|
||||
* \param ev Event to possibly respond to.
|
||||
|
@ -449,35 +477,49 @@ boolean AM_Responder(event_t *ev)
|
|||
{
|
||||
case AM_PANRIGHTKEY: // pan right
|
||||
if (!followplayer)
|
||||
m_paninc.x = FTOM(F_PANINC);
|
||||
{
|
||||
m_keydown[0] = true;
|
||||
AM_setWindowPanning();
|
||||
}
|
||||
else
|
||||
rc = false;
|
||||
break;
|
||||
case AM_PANLEFTKEY: // pan left
|
||||
if (!followplayer)
|
||||
m_paninc.x = -FTOM(F_PANINC);
|
||||
{
|
||||
m_keydown[1] = true;
|
||||
AM_setWindowPanning();
|
||||
}
|
||||
else
|
||||
rc = false;
|
||||
break;
|
||||
case AM_PANUPKEY: // pan up
|
||||
if (!followplayer)
|
||||
m_paninc.y = FTOM(F_PANINC);
|
||||
{
|
||||
m_keydown[2] = true;
|
||||
AM_setWindowPanning();
|
||||
}
|
||||
else
|
||||
rc = false;
|
||||
break;
|
||||
case AM_PANDOWNKEY: // pan down
|
||||
if (!followplayer)
|
||||
m_paninc.y = -FTOM(F_PANINC);
|
||||
{
|
||||
m_keydown[3] = true;
|
||||
AM_setWindowPanning();
|
||||
}
|
||||
else
|
||||
rc = false;
|
||||
break;
|
||||
case AM_ZOOMOUTKEY: // zoom out
|
||||
mtof_zoommul = M_ZOOMOUT;
|
||||
ftom_zoommul = M_ZOOMIN;
|
||||
AM_setWindowPanning();
|
||||
break;
|
||||
case AM_ZOOMINKEY: // zoom in
|
||||
mtof_zoommul = M_ZOOMIN;
|
||||
ftom_zoommul = M_ZOOMOUT;
|
||||
AM_setWindowPanning();
|
||||
break;
|
||||
case AM_TOGGLEKEY:
|
||||
AM_Stop();
|
||||
|
@ -491,6 +533,7 @@ boolean AM_Responder(event_t *ev)
|
|||
}
|
||||
else
|
||||
AM_restoreScaleAndLoc();
|
||||
AM_setWindowPanning();
|
||||
break;
|
||||
case AM_FOLLOWKEY:
|
||||
followplayer = !followplayer;
|
||||
|
@ -510,14 +553,32 @@ boolean AM_Responder(event_t *ev)
|
|||
switch (ev->data1)
|
||||
{
|
||||
case AM_PANRIGHTKEY:
|
||||
if (!followplayer)
|
||||
{
|
||||
m_keydown[0] = false;
|
||||
AM_setWindowPanning();
|
||||
}
|
||||
break;
|
||||
case AM_PANLEFTKEY:
|
||||
if (!followplayer)
|
||||
m_paninc.x = 0;
|
||||
{
|
||||
m_keydown[1] = false;
|
||||
AM_setWindowPanning();
|
||||
}
|
||||
break;
|
||||
case AM_PANUPKEY:
|
||||
if (!followplayer)
|
||||
{
|
||||
m_keydown[2] = false;
|
||||
AM_setWindowPanning();
|
||||
}
|
||||
break;
|
||||
case AM_PANDOWNKEY:
|
||||
if (!followplayer)
|
||||
m_paninc.y = 0;
|
||||
{
|
||||
m_keydown[3] = false;
|
||||
AM_setWindowPanning();
|
||||
}
|
||||
break;
|
||||
case AM_ZOOMOUTKEY:
|
||||
case AM_ZOOMINKEY:
|
||||
|
@ -718,6 +779,17 @@ static boolean AM_clipMline(const mline_t *ml, fline_t *fl)
|
|||
}
|
||||
#undef DOOUTCODE
|
||||
|
||||
//
|
||||
// Draws a pixel.
|
||||
//
|
||||
static void AM_drawPixel(INT32 xx, INT32 yy, INT32 cc)
|
||||
{
|
||||
UINT8 *dest = screens[0];
|
||||
if (xx < 0 || yy < 0 || xx >= vid.width || yy >= vid.height)
|
||||
return; // off the screen
|
||||
dest[(yy*vid.width) + xx] = cc;
|
||||
}
|
||||
|
||||
//
|
||||
// Classic Bresenham w/ whatever optimizations needed for speed
|
||||
//
|
||||
|
@ -739,8 +811,6 @@ static void AM_drawFline_soft(const fline_t *fl, INT32 color)
|
|||
}
|
||||
#endif
|
||||
|
||||
#define PUTDOT(xx,yy,cc) V_DrawFill(xx,yy,1,1,cc|V_NOSCALESTART);
|
||||
|
||||
dx = fl->b.x - fl->a.x;
|
||||
ax = 2 * (dx < 0 ? -dx : dx);
|
||||
sx = dx < 0 ? -1 : 1;
|
||||
|
@ -757,7 +827,7 @@ static void AM_drawFline_soft(const fline_t *fl, INT32 color)
|
|||
d = ay - ax/2;
|
||||
for (;;)
|
||||
{
|
||||
PUTDOT(x, y, color)
|
||||
AM_drawPixel(x, y, color);
|
||||
if (x == fl->b.x)
|
||||
return;
|
||||
if (d >= 0)
|
||||
|
@ -774,7 +844,7 @@ static void AM_drawFline_soft(const fline_t *fl, INT32 color)
|
|||
d = ax - ay/2;
|
||||
for (;;)
|
||||
{
|
||||
PUTDOT(x, y, color)
|
||||
AM_drawPixel(x, y, color);
|
||||
if (y == fl->b.y)
|
||||
return;
|
||||
if (d >= 0)
|
||||
|
@ -786,8 +856,6 @@ static void AM_drawFline_soft(const fline_t *fl, INT32 color)
|
|||
d += ax;
|
||||
}
|
||||
}
|
||||
|
||||
#undef PUTDOT
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1100,6 +1168,12 @@ void AM_Drawer(void)
|
|||
if (!automapactive)
|
||||
return;
|
||||
|
||||
AM_drawFline = AM_drawFline_soft;
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
AM_drawFline = HWR_drawAMline;
|
||||
#endif
|
||||
|
||||
AM_clearFB(BACKGROUND);
|
||||
if (draw_grid) AM_drawGrid(GRIDCOLORS);
|
||||
AM_drawWalls();
|
||||
|
|
|
@ -38,6 +38,9 @@ void AM_Ticker(void);
|
|||
// Called by main loop, instead of view drawer if automap is active.
|
||||
void AM_Drawer(void);
|
||||
|
||||
// Enables the automap.
|
||||
void AM_Start(void);
|
||||
|
||||
// Called to force the automap to quit if the level is completed while it is up.
|
||||
void AM_Stop(void);
|
||||
|
||||
|
|
|
@ -823,8 +823,13 @@ static void COM_Help_f(void)
|
|||
if (!stricmp(cvar->PossibleValue[MINVAL].strvalue, "MIN"))
|
||||
{
|
||||
if (floatmode)
|
||||
CONS_Printf(" range from %f to %f\n", FIXED_TO_FLOAT(cvar->PossibleValue[MINVAL].value),
|
||||
FIXED_TO_FLOAT(cvar->PossibleValue[MAXVAL].value));
|
||||
{
|
||||
float fu = FIXED_TO_FLOAT(cvar->PossibleValue[MINVAL].value);
|
||||
float ck = FIXED_TO_FLOAT(cvar->PossibleValue[MAXVAL].value);
|
||||
CONS_Printf(" range from %ld%s to %ld%s\n",
|
||||
(long)fu, M_Ftrim(fu),
|
||||
(long)ck, M_Ftrim(ck));
|
||||
}
|
||||
else
|
||||
CONS_Printf(" range from %d to %d\n", cvar->PossibleValue[MINVAL].value,
|
||||
cvar->PossibleValue[MAXVAL].value);
|
||||
|
@ -973,7 +978,10 @@ static void COM_Add_f(void)
|
|||
}
|
||||
|
||||
if (( cvar->flags & CV_FLOAT ))
|
||||
CV_Set(cvar, va("%f", FIXED_TO_FLOAT (cvar->value) + atof(COM_Argv(2))));
|
||||
{
|
||||
float n =FIXED_TO_FLOAT (cvar->value) + atof(COM_Argv(2));
|
||||
CV_Set(cvar, va("%ld%s", (long)n, M_Ftrim(n)));
|
||||
}
|
||||
else
|
||||
CV_AddValue(cvar, atoi(COM_Argv(2)));
|
||||
}
|
||||
|
@ -1457,15 +1465,8 @@ static void Got_NetVar(UINT8 **p, INT32 playernum)
|
|||
{
|
||||
// not from server or remote admin, must be hacked/buggy client
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal netvar command received from %s\n"), player_names[playernum]);
|
||||
|
||||
if (server)
|
||||
{
|
||||
UINT8 buf[2];
|
||||
|
||||
buf[0] = (UINT8)playernum;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
return;
|
||||
}
|
||||
netid = READUINT16(*p);
|
||||
|
|
|
@ -26,12 +26,12 @@
|
|||
#else
|
||||
|
||||
/* Manually defined asset hashes for non-CMake builds
|
||||
* Last updated 2019 / 12 / 06 - v2.2.0 - main assets
|
||||
* Last updated 2020 / 02 / 15 - v2.2.1 - main assets
|
||||
* Last updated 20?? / ?? / ?? - v2.2.? - patch.pk3
|
||||
*/
|
||||
#define ASSET_HASH_SRB2_PK3 "51419a33b4982d840c6772c159ba7c0a"
|
||||
#define ASSET_HASH_ZONES_PK3 "df74843919fd51af26a0baa8e21e4c19"
|
||||
#define ASSET_HASH_PLAYER_DTA "56a247e074dd0dc794b6617efef1e918"
|
||||
#define ASSET_HASH_SRB2_PK3 "0277c9416756627004e83cbb5b2e3e28"
|
||||
#define ASSET_HASH_ZONES_PK3 "f7e88afb6af7996a834c7d663144bead"
|
||||
#define ASSET_HASH_PLAYER_DTA "ad49e07b17cc662f1ad70c454910b4ae"
|
||||
#ifdef USE_PATCH_DTA
|
||||
#define ASSET_HASH_PATCH_PK3 "there is no patch.pk3, only zuul"
|
||||
#endif
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "d_main.h"
|
||||
#include "m_menu.h"
|
||||
#include "filesrch.h"
|
||||
#include "m_misc.h"
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include "win32/win_main.h"
|
||||
|
@ -815,6 +816,33 @@ boolean CON_Responder(event_t *ev)
|
|||
|| key == KEY_LALT || key == KEY_RALT)
|
||||
return true;
|
||||
|
||||
if (key == KEY_LEFTARROW)
|
||||
{
|
||||
if (input_cur != 0)
|
||||
{
|
||||
if (ctrldown)
|
||||
input_cur = M_JumpWordReverse(inputlines[inputline], input_cur);
|
||||
else
|
||||
--input_cur;
|
||||
}
|
||||
if (!shiftdown)
|
||||
input_sel = input_cur;
|
||||
return true;
|
||||
}
|
||||
else if (key == KEY_RIGHTARROW)
|
||||
{
|
||||
if (input_cur < input_len)
|
||||
{
|
||||
if (ctrldown)
|
||||
input_cur += M_JumpWord(&inputlines[inputline][input_cur]);
|
||||
else
|
||||
++input_cur;
|
||||
}
|
||||
if (!shiftdown)
|
||||
input_sel = input_cur;
|
||||
return true;
|
||||
}
|
||||
|
||||
// ctrl modifier -- changes behavior, adds shortcuts
|
||||
if (ctrldown)
|
||||
{
|
||||
|
@ -967,23 +995,6 @@ boolean CON_Responder(event_t *ev)
|
|||
con_scrollup--;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (key == KEY_LEFTARROW)
|
||||
{
|
||||
if (input_cur != 0)
|
||||
--input_cur;
|
||||
if (!shiftdown)
|
||||
input_sel = input_cur;
|
||||
return true;
|
||||
}
|
||||
else if (key == KEY_RIGHTARROW)
|
||||
{
|
||||
if (input_cur < input_len)
|
||||
++input_cur;
|
||||
if (!shiftdown)
|
||||
input_sel = input_cur;
|
||||
return true;
|
||||
}
|
||||
else if (key == KEY_HOME)
|
||||
{
|
||||
input_cur = 0;
|
||||
|
@ -1551,9 +1562,14 @@ static void CON_DrawConsole(void)
|
|||
if (cons_backpic.value || con_forcepic)
|
||||
{
|
||||
patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_PATCH);
|
||||
int h;
|
||||
|
||||
h = con_curlines/vid.dupy;
|
||||
|
||||
// Jimita: CON_DrawBackpic just called V_DrawScaledPatch
|
||||
V_DrawScaledPatch(0, 0, 0, con_backpic);
|
||||
//V_DrawScaledPatch(0, 0, 0, con_backpic);
|
||||
V_DrawCroppedPatch(0, 0, FRACUNIT, 0, con_backpic,
|
||||
0, ( BASEVIDHEIGHT - h ), BASEVIDWIDTH, h);
|
||||
|
||||
W_UnlockCachedPatch(con_backpic);
|
||||
}
|
||||
|
|
429
src/d_clisrv.c
429
src/d_clisrv.c
|
@ -21,6 +21,7 @@
|
|||
#include "d_net.h"
|
||||
#include "d_main.h"
|
||||
#include "g_game.h"
|
||||
#include "st_stuff.h"
|
||||
#include "hu_stuff.h"
|
||||
#include "keys.h"
|
||||
#include "g_input.h" // JOY1
|
||||
|
@ -76,6 +77,7 @@ char motd[254], server_context[8]; // Message of the Day, Unique Context (even w
|
|||
|
||||
// Server specific vars
|
||||
UINT8 playernode[MAXPLAYERS];
|
||||
char playeraddress[MAXPLAYERS][64];
|
||||
|
||||
// Minimum timeout for sending the savegame
|
||||
// The actual timeout will be longer depending on the savegame length
|
||||
|
@ -391,11 +393,7 @@ static void ExtraDataTicker(void)
|
|||
{
|
||||
if (server)
|
||||
{
|
||||
UINT8 buf[3];
|
||||
|
||||
buf[0] = (UINT8)i;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
SendKick(i, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
DEBFILE(va("player %d kicked [gametic=%u] reason as follows:\n", i, gametic));
|
||||
}
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Got unknown net command [%s]=%d (max %d)\n"), sizeu1(curpos - bufferstart), *curpos, bufferstart[0]);
|
||||
|
@ -406,8 +404,8 @@ static void ExtraDataTicker(void)
|
|||
}
|
||||
|
||||
// If you are a client, you can safely forget the net commands for this tic
|
||||
// If you are the server, you need to remember them until every client has been aknowledged,
|
||||
// because if you need to resend a PT_SERVERTICS packet, you need to put the commands in it
|
||||
// If you are the server, you need to remember them until every client has been acknowledged,
|
||||
// because if you need to resend a PT_SERVERTICS packet, you will need to put the commands in it
|
||||
if (client)
|
||||
D_FreeTextcmd(gametic);
|
||||
}
|
||||
|
@ -437,6 +435,18 @@ void D_ResetTiccmds(void)
|
|||
D_Clearticcmd(textcmds[i]->tic);
|
||||
}
|
||||
|
||||
void SendKick(UINT8 playernum, UINT8 msg)
|
||||
{
|
||||
UINT8 buf[2];
|
||||
|
||||
if (!(server && cv_rejointimeout.value))
|
||||
msg &= ~KICK_MSG_KEEP_BODY;
|
||||
|
||||
buf[0] = playernum;
|
||||
buf[1] = msg;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// end of extra data function
|
||||
// -----------------------------------------------------------------
|
||||
|
@ -1053,10 +1063,7 @@ static void SV_SendResynch(INT32 node)
|
|||
|
||||
if (resynch_score[node] > (unsigned)cv_resynchattempts.value*250)
|
||||
{
|
||||
UINT8 buf[2];
|
||||
buf[0] = (UINT8)nodetoplayer[node];
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
SendKick(nodetoplayer[node], KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
resynch_score[node] = 0;
|
||||
}
|
||||
}
|
||||
|
@ -1271,8 +1278,14 @@ static boolean CL_SendJoin(void)
|
|||
netbuffer->u.clientcfg.subversion = SUBVERSION;
|
||||
strncpy(netbuffer->u.clientcfg.application, SRB2APPLICATION,
|
||||
sizeof netbuffer->u.clientcfg.application);
|
||||
|
||||
CleanupPlayerName(consoleplayer, cv_playername.zstring);
|
||||
if (splitscreen)
|
||||
CleanupPlayerName(1, cv_playername2.zstring);/* 1 is a HACK? oh no */
|
||||
|
||||
strncpy(netbuffer->u.clientcfg.names[0], cv_playername.zstring, MAXPLAYERNAME);
|
||||
strncpy(netbuffer->u.clientcfg.names[1], cv_playername2.zstring, MAXPLAYERNAME);
|
||||
|
||||
return HSendPacket(servernode, true, 0, sizeof (clientconfig_pak));
|
||||
}
|
||||
|
||||
|
@ -1346,11 +1359,11 @@ static void SV_SendPlayerInfo(INT32 node)
|
|||
{
|
||||
if (!playeringame[i])
|
||||
{
|
||||
netbuffer->u.playerinfo[i].node = 255; // This slot is empty.
|
||||
netbuffer->u.playerinfo[i].num = 255; // This slot is empty.
|
||||
continue;
|
||||
}
|
||||
|
||||
netbuffer->u.playerinfo[i].node = i;
|
||||
netbuffer->u.playerinfo[i].num = i;
|
||||
strncpy(netbuffer->u.playerinfo[i].name, (const char *)&player_names[i], MAXPLAYERNAME+1);
|
||||
netbuffer->u.playerinfo[i].name[MAXPLAYERNAME] = '\0';
|
||||
|
||||
|
@ -1625,6 +1638,7 @@ static void CL_LoadReceivedSavegame(void)
|
|||
|
||||
paused = false;
|
||||
demoplayback = false;
|
||||
titlemapinaction = TITLEMAP_OFF;
|
||||
titledemo = false;
|
||||
automapactive = false;
|
||||
|
||||
|
@ -2410,6 +2424,7 @@ void CL_ClearPlayer(INT32 playernum)
|
|||
if (players[playernum].mo)
|
||||
P_RemoveMobj(players[playernum].mo);
|
||||
memset(&players[playernum], 0, sizeof (player_t));
|
||||
memset(playeraddress[playernum], 0, sizeof(*playeraddress));
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -2417,7 +2432,7 @@ void CL_ClearPlayer(INT32 playernum)
|
|||
//
|
||||
// Removes a player from the current game
|
||||
//
|
||||
static void CL_RemovePlayer(INT32 playernum, INT32 reason)
|
||||
static void CL_RemovePlayer(INT32 playernum, kickreason_t reason)
|
||||
{
|
||||
// Sanity check: exceptional cases (i.e. c-fails) can cause multiple
|
||||
// kick commands to be issued for the same player.
|
||||
|
@ -2430,9 +2445,6 @@ static void CL_RemovePlayer(INT32 playernum, INT32 reason)
|
|||
playerpernode[node]--;
|
||||
if (playerpernode[node] <= 0)
|
||||
{
|
||||
// If a resynch was in progress, well, it no longer needs to be.
|
||||
SV_InitResynchVars(playernode[playernum]);
|
||||
|
||||
nodeingame[playernode[playernum]] = false;
|
||||
Net_CloseConnection(playernode[playernum]);
|
||||
ResetNode(node);
|
||||
|
@ -2554,6 +2566,7 @@ void CL_Reset(void)
|
|||
multiplayer = false;
|
||||
servernode = 0;
|
||||
server = true;
|
||||
resynch_local_inprogress = false;
|
||||
doomcom->numnodes = 1;
|
||||
doomcom->numslots = 1;
|
||||
SV_StopServer();
|
||||
|
@ -2827,9 +2840,12 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
|||
char buf[3 + MAX_REASONLENGTH];
|
||||
char *reason = buf;
|
||||
kickreason_t kickreason = KR_KICK;
|
||||
boolean keepbody;
|
||||
|
||||
pnum = READUINT8(*p);
|
||||
msg = READUINT8(*p);
|
||||
keepbody = (msg & KICK_MSG_KEEP_BODY) != 0;
|
||||
msg &= ~KICK_MSG_KEEP_BODY;
|
||||
|
||||
if (pnum == serverplayer && IsPlayerAdmin(playernum))
|
||||
{
|
||||
|
@ -2889,6 +2905,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
|||
*/
|
||||
pnum = playernum;
|
||||
msg = KICK_MSG_CON_FAIL;
|
||||
keepbody = true;
|
||||
}
|
||||
|
||||
//CONS_Printf("\x82%s ", player_names[pnum]);
|
||||
|
@ -2908,7 +2925,8 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
|||
switch (msg)
|
||||
{
|
||||
case KICK_MSG_GO_AWAY:
|
||||
HU_AddChatText(va("\x82*%s has been kicked (Go away)", player_names[pnum]), false);
|
||||
if (!players[pnum].quittime)
|
||||
HU_AddChatText(va("\x82*%s has been kicked (Go away)", player_names[pnum]), false);
|
||||
kickreason = KR_KICK;
|
||||
break;
|
||||
case KICK_MSG_PING_HIGH:
|
||||
|
@ -2957,7 +2975,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
|||
kickreason = KR_TIMEOUT;
|
||||
break;
|
||||
case KICK_MSG_PLAYER_QUIT:
|
||||
if (netgame) // not splitscreen/bots
|
||||
if (netgame && !players[pnum].quittime) // not splitscreen/bots or soulless body
|
||||
HU_AddChatText(va("\x82*%s left the game", player_names[pnum]), false);
|
||||
kickreason = KR_LEAVE;
|
||||
break;
|
||||
|
@ -2998,6 +3016,24 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
|||
else
|
||||
M_StartMessage(M_GetText("You have been kicked by the server\n\nPress ESC\n"), NULL, MM_NOTHING);
|
||||
}
|
||||
else if (keepbody)
|
||||
{
|
||||
if (server && !demoplayback)
|
||||
{
|
||||
INT32 node = playernode[pnum];
|
||||
playerpernode[node]--;
|
||||
if (playerpernode[node] <= 0)
|
||||
{
|
||||
nodeingame[node] = false;
|
||||
Net_CloseConnection(node);
|
||||
ResetNode(node);
|
||||
}
|
||||
}
|
||||
|
||||
playernode[pnum] = UINT8_MAX;
|
||||
|
||||
players[pnum].quittime = 1;
|
||||
}
|
||||
else
|
||||
CL_RemovePlayer(pnum, kickreason);
|
||||
}
|
||||
|
@ -3006,6 +3042,9 @@ consvar_t cv_allownewplayer = {"allowjoin", "On", CV_NETVAR, CV_OnOff, NULL, 0,
|
|||
consvar_t cv_joinnextround = {"joinnextround", "Off", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; /// \todo not done
|
||||
static CV_PossibleValue_t maxplayers_cons_t[] = {{2, "MIN"}, {32, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_maxplayers = {"maxplayers", "8", CV_SAVE, maxplayers_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
static CV_PossibleValue_t rejointimeout_cons_t[] = {{1, "MIN"}, {60 * FRACUNIT, "MAX"}, {0, "Off"}, {0, NULL}};
|
||||
consvar_t cv_rejointimeout = {"rejointimeout", "Off", CV_SAVE|CV_FLOAT, rejointimeout_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t resynchattempts_cons_t[] = {{1, "MIN"}, {20, "MAX"}, {0, "No"}, {0, NULL}};
|
||||
consvar_t cv_resynchattempts = {"resynchattempts", "10", CV_SAVE, resynchattempts_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL };
|
||||
consvar_t cv_blamecfail = {"blamecfail", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL };
|
||||
|
@ -3075,6 +3114,7 @@ static void ResetNode(INT32 node)
|
|||
nodewaiting[node] = 0;
|
||||
playerpernode[node] = 0;
|
||||
sendingsavegame[node] = false;
|
||||
SV_InitResynchVars(node);
|
||||
}
|
||||
|
||||
void SV_ResetServer(void)
|
||||
|
@ -3090,13 +3130,8 @@ void SV_ResetServer(void)
|
|||
tictoclear = maketic;
|
||||
|
||||
for (i = 0; i < MAXNETNODES; i++)
|
||||
{
|
||||
ResetNode(i);
|
||||
|
||||
// Make sure resynch status doesn't get carried over!
|
||||
SV_InitResynchVars(i);
|
||||
}
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
#ifdef HAVE_BLUA
|
||||
|
@ -3104,6 +3139,7 @@ void SV_ResetServer(void)
|
|||
#endif
|
||||
playeringame[i] = false;
|
||||
playernode[i] = UINT8_MAX;
|
||||
memset(playeraddress[i], 0, sizeof(*playeraddress));
|
||||
sprintf(player_names[i], "Player %d", i + 1);
|
||||
adminplayers[i] = -1; // Populate the entire adminplayers array with -1.
|
||||
}
|
||||
|
@ -3194,6 +3230,37 @@ void D_QuitNetGame(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
static INT32 FindRejoinerNum(SINT8 node)
|
||||
{
|
||||
char strippednodeaddress[64];
|
||||
const char *nodeaddress;
|
||||
char *port;
|
||||
INT32 i;
|
||||
|
||||
// Make sure there is no dead dress before proceeding to the stripping
|
||||
if (!I_GetNodeAddress)
|
||||
return -1;
|
||||
nodeaddress = I_GetNodeAddress(node);
|
||||
if (!nodeaddress)
|
||||
return -1;
|
||||
|
||||
// Strip the address of its port
|
||||
strcpy(strippednodeaddress, nodeaddress);
|
||||
port = strchr(strippednodeaddress, ':');
|
||||
if (port)
|
||||
*port = '\0';
|
||||
|
||||
// Check if any player matches the stripped address
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i] && playeraddress[i][0] && playernode[i] == UINT8_MAX
|
||||
&& !strcmp(playeraddress[i], strippednodeaddress))
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Adds a node to the game (player will follow at map change or at savegame....)
|
||||
static inline void SV_AddNode(INT32 node)
|
||||
{
|
||||
|
@ -3210,19 +3277,16 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
|||
{
|
||||
INT16 node, newplayernum;
|
||||
boolean splitscreenplayer;
|
||||
boolean rejoined;
|
||||
player_t *newplayer;
|
||||
char *port;
|
||||
|
||||
if (playernum != serverplayer && !IsPlayerAdmin(playernum))
|
||||
{
|
||||
// protect against hacked/buggy client
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal add player command received from %s\n"), player_names[playernum]);
|
||||
if (server)
|
||||
{
|
||||
UINT8 buf[2];
|
||||
|
||||
buf[0] = (UINT8)playernum;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3231,15 +3295,34 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
|||
splitscreenplayer = newplayernum & 0x80;
|
||||
newplayernum &= ~0x80;
|
||||
|
||||
// Clear player before joining, lest some things get set incorrectly
|
||||
// HACK: don't do this for splitscreen, it relies on preset values
|
||||
if (!splitscreen && !botingame)
|
||||
CL_ClearPlayer(newplayernum);
|
||||
playeringame[newplayernum] = true;
|
||||
rejoined = playeringame[newplayernum];
|
||||
|
||||
if (!rejoined)
|
||||
{
|
||||
// Clear player before joining, lest some things get set incorrectly
|
||||
// HACK: don't do this for splitscreen, it relies on preset values
|
||||
if (!splitscreen && !botingame)
|
||||
CL_ClearPlayer(newplayernum);
|
||||
playeringame[newplayernum] = true;
|
||||
G_AddPlayer(newplayernum);
|
||||
if (newplayernum+1 > doomcom->numslots)
|
||||
doomcom->numslots = (INT16)(newplayernum+1);
|
||||
|
||||
if (server && I_GetNodeAddress)
|
||||
{
|
||||
strcpy(playeraddress[newplayernum], I_GetNodeAddress(node));
|
||||
port = strchr(playeraddress[newplayernum], ':');
|
||||
if (port)
|
||||
*port = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
newplayer = &players[newplayernum];
|
||||
|
||||
newplayer->jointime = 0;
|
||||
newplayer->quittime = 0;
|
||||
|
||||
READSTRINGN(*p, player_names[newplayernum], MAXPLAYERNAME);
|
||||
G_AddPlayer(newplayernum);
|
||||
if (newplayernum+1 > doomcom->numslots)
|
||||
doomcom->numslots = (INT16)(newplayernum+1);
|
||||
|
||||
// the server is creating my player
|
||||
if (node == mynode)
|
||||
|
@ -3257,29 +3340,67 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
|||
secondarydisplayplayer = newplayernum;
|
||||
DEBFILE("spawning my brother\n");
|
||||
if (botingame)
|
||||
players[newplayernum].bot = 1;
|
||||
newplayer->bot = 1;
|
||||
}
|
||||
D_SendPlayerConfig();
|
||||
addedtogame = true;
|
||||
|
||||
if (rejoined)
|
||||
{
|
||||
if (newplayer->mo)
|
||||
{
|
||||
if (!splitscreenplayer)
|
||||
localangle = newplayer->mo->angle;
|
||||
else
|
||||
localangle2 = newplayer->mo->angle;
|
||||
|
||||
newplayer->viewheight = 41*newplayer->height/48;
|
||||
|
||||
if (newplayer->mo->eflags & MFE_VERTICALFLIP)
|
||||
newplayer->viewz = newplayer->mo->z + newplayer->mo->height - newplayer->viewheight;
|
||||
else
|
||||
newplayer->viewz = newplayer->mo->z + newplayer->viewheight;
|
||||
}
|
||||
|
||||
// wake up the status bar
|
||||
ST_Start();
|
||||
// wake up the heads up text
|
||||
HU_Start();
|
||||
|
||||
if (camera.chase && !splitscreenplayer)
|
||||
P_ResetCamera(newplayer, &camera);
|
||||
if (camera2.chase && splitscreenplayer)
|
||||
P_ResetCamera(newplayer, &camera2);
|
||||
}
|
||||
}
|
||||
|
||||
if (netgame)
|
||||
{
|
||||
if (server && cv_showjoinaddress.value)
|
||||
{
|
||||
const char *address;
|
||||
if (I_GetNodeAddress && (address = I_GetNodeAddress(node)) != NULL)
|
||||
HU_AddChatText(va("\x82*%s has joined the game (player %d) (%s)", player_names[newplayernum], newplayernum, address), false); // merge join notification + IP to avoid clogging console/chat.
|
||||
}
|
||||
char joinmsg[256];
|
||||
|
||||
if (rejoined)
|
||||
strcpy(joinmsg, M_GetText("\x82*%s has rejoined the game (player %d)"));
|
||||
else
|
||||
HU_AddChatText(va("\x82*%s has joined the game (player %d)", player_names[newplayernum], newplayernum), false); // if you don't wanna see the join address.
|
||||
strcpy(joinmsg, M_GetText("\x82*%s has joined the game (player %d)"));
|
||||
strcpy(joinmsg, va(joinmsg, player_names[newplayernum], newplayernum));
|
||||
|
||||
// Merge join notification + IP to avoid clogging console/chat
|
||||
if (server && cv_showjoinaddress.value && I_GetNodeAddress)
|
||||
{
|
||||
const char *address = I_GetNodeAddress(node);
|
||||
if (address)
|
||||
strcat(joinmsg, va(" (%s)", address));
|
||||
}
|
||||
|
||||
HU_AddChatText(joinmsg, false);
|
||||
}
|
||||
|
||||
if (server && multiplayer && motd[0] != '\0')
|
||||
COM_BufAddText(va("sayto %d %s\n", newplayernum, motd));
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
LUAh_PlayerJoin(newplayernum);
|
||||
if (!rejoined)
|
||||
LUAh_PlayerJoin(newplayernum);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -3288,11 +3409,7 @@ static boolean SV_AddWaitingPlayers(const char *name, const char *name2)
|
|||
INT32 node, n, newplayer = false;
|
||||
UINT8 buf[2 + MAXPLAYERNAME];
|
||||
UINT8 *p;
|
||||
UINT8 newplayernum = 0;
|
||||
|
||||
// What is the reason for this? Why can't newplayernum always be 0?
|
||||
if (dedicated)
|
||||
newplayernum = 1;
|
||||
INT32 newplayernum;
|
||||
|
||||
for (node = 0; node < MAXNETNODES; node++)
|
||||
{
|
||||
|
@ -3301,68 +3418,22 @@ static boolean SV_AddWaitingPlayers(const char *name, const char *name2)
|
|||
{
|
||||
newplayer = true;
|
||||
|
||||
if (netgame)
|
||||
// !!!!!!!!! EXTREMELY SUPER MEGA GIGA ULTRA ULTIMATELY TERRIBLY IMPORTANT !!!!!!!!!
|
||||
//
|
||||
// The line just after that comment is an awful, horrible, terrible, TERRIBLE hack.
|
||||
//
|
||||
// Basically, the fix I did in order to fix the download freezes happens
|
||||
// to cause situations in which a player number does not match
|
||||
// the node number associated to that player.
|
||||
// That is totally normal, there is absolutely *nothing* wrong with that.
|
||||
// Really. Player 7 being tied to node 29, for instance, is totally fine.
|
||||
//
|
||||
// HOWEVER. A few (broken) parts of the netcode do the TERRIBLE mistake
|
||||
// of mixing up the concepts of node and player, resulting in
|
||||
// incorrect handling of cases where a player is tied to a node that has
|
||||
// a different number (which is a totally normal case, or at least should be).
|
||||
// This incorrect handling can go as far as literally
|
||||
// anyone from joining your server at all, forever.
|
||||
//
|
||||
// Given those two facts, there are two options available
|
||||
// in order to let this download freeze fix be:
|
||||
// 1) Fix the broken parts that assume a node is a player or similar bullshit.
|
||||
// 2) Change the part this comment is located at, so that any player who joins
|
||||
// is given the same number as their associated node.
|
||||
//
|
||||
// No need to say, 1) is by far the obvious best, whereas 2) is a terrible hack.
|
||||
// Unfortunately, after trying 1), I most likely didn't manage to find all
|
||||
// of those broken parts, and thus 2) has become the only safe option that remains.
|
||||
//
|
||||
// So I did this hack.
|
||||
//
|
||||
// If it isn't clear enough, in order to get rid of this ugly hack,
|
||||
// you will have to fix all parts of the netcode that
|
||||
// make a confusion between nodes and players.
|
||||
//
|
||||
// And if it STILL isn't clear enough, a node and a player
|
||||
// is NOT the same thing. Never. NEVER. *NEVER*.
|
||||
//
|
||||
// And if someday you make the terrible mistake of
|
||||
// daring to have the unforgivable idea to try thinking
|
||||
// that a node might possibly be the same as a player,
|
||||
// or that a player should have the same number as its node,
|
||||
// be sure that I will somehow know about it and
|
||||
// hunt you down tirelessly and make you regret it,
|
||||
// even if you live on the other side of the world.
|
||||
//
|
||||
// TODO: vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
// \todo >>>>>>>>>> Remove this horrible hack as soon as possible <<<<<<<<<<
|
||||
// TODO: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//
|
||||
// !!!!!!!!! EXTREMELY SUPER MEGA GIGA ULTRA ULTIMATELY TERRIBLY IMPORTANT !!!!!!!!!
|
||||
newplayernum = node; // OMFG SAY WELCOME TO TEH NEW HACK FOR FIX FIL DOWNLOAD!!1!
|
||||
else // Don't use the hack if we don't have to
|
||||
newplayernum = FindRejoinerNum(node);
|
||||
if (newplayernum == -1)
|
||||
{
|
||||
// search for a free playernum
|
||||
// we can't use playeringame since it is not updated here
|
||||
for (; newplayernum < MAXPLAYERS; newplayernum++)
|
||||
for (newplayernum = dedicated ? 1 : 0; newplayernum < MAXPLAYERS; newplayernum++)
|
||||
{
|
||||
if (playeringame[newplayernum])
|
||||
continue;
|
||||
for (n = 0; n < MAXNETNODES; n++)
|
||||
if (nodetoplayer[n] == newplayernum || nodetoplayer2[n] == newplayernum)
|
||||
break;
|
||||
if (n == MAXNETNODES)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// should never happen since we check the playernum
|
||||
// before accepting the join
|
||||
|
@ -3389,8 +3460,6 @@ static boolean SV_AddWaitingPlayers(const char *name, const char *name2)
|
|||
SendNetXCmd(XD_ADDPLAYER, &buf, p - buf);
|
||||
|
||||
DEBFILE(va("Server added player %d node %d\n", newplayernum, node));
|
||||
// use the next free slot (we can't put playeringame[newplayernum] = true here)
|
||||
newplayernum++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3405,14 +3474,10 @@ void CL_AddSplitscreenPlayer(void)
|
|||
|
||||
void CL_RemoveSplitscreenPlayer(void)
|
||||
{
|
||||
UINT8 buf[2];
|
||||
|
||||
if (cl_mode != CL_CONNECTED)
|
||||
return;
|
||||
|
||||
buf[0] = (UINT8)secondarydisplayplayer;
|
||||
buf[1] = KICK_MSG_PLAYER_QUIT;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
SendKick(secondarydisplayplayer, KICK_MSG_PLAYER_QUIT);
|
||||
}
|
||||
|
||||
// is there a game running
|
||||
|
@ -3520,8 +3585,11 @@ static size_t TotalTextCmdPerTic(tic_t tic)
|
|||
static void HandleConnect(SINT8 node)
|
||||
{
|
||||
char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME + 1];
|
||||
INT32 rejoinernum;
|
||||
INT32 i;
|
||||
|
||||
rejoinernum = FindRejoinerNum(node);
|
||||
|
||||
if (bannednode && bannednode[node])
|
||||
SV_SendRefuse(node, M_GetText("You have been banned\nfrom the server"));
|
||||
else if (netbuffer->u.clientcfg._255 != 255 ||
|
||||
|
@ -3533,9 +3601,9 @@ static void HandleConnect(SINT8 node)
|
|||
else if (netbuffer->u.clientcfg.version != VERSION
|
||||
|| netbuffer->u.clientcfg.subversion != SUBVERSION)
|
||||
SV_SendRefuse(node, va(M_GetText("Different SRB2 versions cannot\nplay a netgame!\n(server version %d.%d.%d)"), VERSION/100, VERSION%100, SUBVERSION));
|
||||
else if (!cv_allownewplayer.value && node)
|
||||
else if (!cv_allownewplayer.value && node && rejoinernum == -1)
|
||||
SV_SendRefuse(node, M_GetText("The server is not accepting\njoins for the moment"));
|
||||
else if (D_NumPlayers() >= cv_maxplayers.value)
|
||||
else if (D_NumPlayers() >= cv_maxplayers.value && rejoinernum == -1)
|
||||
SV_SendRefuse(node, va(M_GetText("Maximum players reached: %d"), cv_maxplayers.value));
|
||||
else if (netgame && netbuffer->u.clientcfg.localplayers > 1) // Hacked client?
|
||||
SV_SendRefuse(node, M_GetText("Too many players from\nthis node."));
|
||||
|
@ -3550,7 +3618,7 @@ static void HandleConnect(SINT8 node)
|
|||
for (i = 0; i < netbuffer->u.clientcfg.localplayers - playerpernode[node]; i++)
|
||||
{
|
||||
strlcpy(names[i], netbuffer->u.clientcfg.names[i], MAXPLAYERNAME + 1);
|
||||
if (!EnsurePlayerNameIsGood(names[i], -1))
|
||||
if (!EnsurePlayerNameIsGood(names[i], rejoinernum))
|
||||
{
|
||||
SV_SendRefuse(node, "Bad player name");
|
||||
return;
|
||||
|
@ -3951,13 +4019,10 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
if (netcmds[maketic%BACKUPTICS][netconsole].forwardmove > MAXPLMOVE || netcmds[maketic%BACKUPTICS][netconsole].forwardmove < -MAXPLMOVE
|
||||
|| netcmds[maketic%BACKUPTICS][netconsole].sidemove > MAXPLMOVE || netcmds[maketic%BACKUPTICS][netconsole].sidemove < -MAXPLMOVE)
|
||||
{
|
||||
char buf[2];
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal movement value received from node %d\n"), netconsole);
|
||||
//D_Clearticcmd(k);
|
||||
|
||||
buf[0] = (char)netconsole;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
SendKick(netconsole, KICK_MSG_CON_FAIL);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -3994,11 +4059,7 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
}
|
||||
else
|
||||
{
|
||||
UINT8 buf[3];
|
||||
|
||||
buf[0] = (UINT8)netconsole;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
SendKick(netconsole, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
DEBFILE(va("player %d kicked (synch failure) [%u] %d!=%d\n",
|
||||
netconsole, realstart, consistancy[realstart%BACKUPTICS],
|
||||
SHORT(netbuffer->u.clientpak.consistancy)));
|
||||
|
@ -4111,19 +4172,21 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
nodewaiting[node] = 0;
|
||||
if (netconsole != -1 && playeringame[netconsole])
|
||||
{
|
||||
UINT8 buf[2];
|
||||
buf[0] = (UINT8)netconsole;
|
||||
UINT8 kickmsg;
|
||||
|
||||
if (netbuffer->packettype == PT_NODETIMEOUT)
|
||||
buf[1] = KICK_MSG_TIMEOUT;
|
||||
kickmsg = KICK_MSG_TIMEOUT;
|
||||
else
|
||||
buf[1] = KICK_MSG_PLAYER_QUIT;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
kickmsg = KICK_MSG_PLAYER_QUIT;
|
||||
kickmsg |= KICK_MSG_KEEP_BODY;
|
||||
|
||||
SendKick(netconsole, kickmsg);
|
||||
nodetoplayer[node] = -1;
|
||||
|
||||
if (nodetoplayer2[node] != -1 && nodetoplayer2[node] >= 0
|
||||
&& playeringame[(UINT8)nodetoplayer2[node]])
|
||||
{
|
||||
buf[0] = nodetoplayer2[node];
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
SendKick(nodetoplayer2[node], kickmsg);
|
||||
nodetoplayer2[node] = -1;
|
||||
}
|
||||
}
|
||||
|
@ -4136,15 +4199,8 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
if (node != servernode)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_RESYNCHEND", node);
|
||||
|
||||
if (server)
|
||||
{
|
||||
UINT8 buf[2];
|
||||
buf[0] = (UINT8)node;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
|
||||
SendKick(netconsole, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
break;
|
||||
}
|
||||
resynch_local_inprogress = false;
|
||||
|
@ -4161,15 +4217,8 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
if (node != servernode)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_SERVERTICS", node);
|
||||
|
||||
if (server)
|
||||
{
|
||||
UINT8 buf[2];
|
||||
buf[0] = (UINT8)node;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
|
||||
SendKick(netconsole, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -4228,15 +4277,8 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
if (node != servernode)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_RESYNCHING", node);
|
||||
|
||||
if (server)
|
||||
{
|
||||
char buf[2];
|
||||
buf[0] = (char)node;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
|
||||
SendKick(netconsole, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
break;
|
||||
}
|
||||
resynch_local_inprogress = true;
|
||||
|
@ -4247,15 +4289,8 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
if (node != servernode)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_PING", node);
|
||||
|
||||
if (server)
|
||||
{
|
||||
char buf[2];
|
||||
buf[0] = (char)node;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
|
||||
SendKick(netconsole, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -4278,15 +4313,8 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
if (node != servernode)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_FILEFRAGMENT", node);
|
||||
|
||||
if (server)
|
||||
{
|
||||
UINT8 buf[2];
|
||||
buf[0] = (UINT8)node;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
|
||||
SendKick(netconsole, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
break;
|
||||
}
|
||||
if (client)
|
||||
|
@ -4482,7 +4510,7 @@ static void CL_SendClientCmd(void)
|
|||
packetsize = sizeof (clientcmd_pak) - sizeof (ticcmd_t) - sizeof (INT16);
|
||||
HSendPacket(servernode, false, 0, packetsize);
|
||||
}
|
||||
else if (gamestate != GS_NULL)
|
||||
else if (gamestate != GS_NULL && (addedtogame || dedicated))
|
||||
{
|
||||
G_MoveTiccmd(&netbuffer->u.clientpak.cmd, &localcmds, 1);
|
||||
netbuffer->u.clientpak.consistancy = SHORT(consistancy[gametic%BACKUPTICS]);
|
||||
|
@ -4656,8 +4684,14 @@ static void Local_Maketic(INT32 realtics)
|
|||
G_BuildTiccmd(&localcmds2, realtics, 2);
|
||||
|
||||
localcmds.angleturn |= TICCMD_RECEIVED;
|
||||
localcmds2.angleturn |= TICCMD_RECEIVED;
|
||||
}
|
||||
|
||||
// This function is utter bullshit and is responsible for
|
||||
// the random desynch that happens when a player spawns.
|
||||
// This is because ticcmds are resent to clients if a packet
|
||||
// was dropped, and thus modifying them can lead to several
|
||||
// clients having their ticcmds set to different values.
|
||||
void SV_SpawnPlayer(INT32 playernum, INT32 x, INT32 y, angle_t angle)
|
||||
{
|
||||
tic_t tic;
|
||||
|
@ -4691,28 +4725,36 @@ void SV_SpawnPlayer(INT32 playernum, INT32 x, INT32 y, angle_t angle)
|
|||
// create missed tic
|
||||
static void SV_Maketic(void)
|
||||
{
|
||||
INT32 j;
|
||||
INT32 i;
|
||||
|
||||
for (j = 0; j < MAXNETNODES; j++)
|
||||
if (playerpernode[j])
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
|
||||
// We didn't receive this tic
|
||||
if ((netcmds[maketic % BACKUPTICS][i].angleturn & TICCMD_RECEIVED) == 0)
|
||||
{
|
||||
INT32 player = nodetoplayer[j];
|
||||
if ((netcmds[maketic%BACKUPTICS][player].angleturn & TICCMD_RECEIVED) == 0)
|
||||
{ // we didn't receive this tic
|
||||
INT32 i;
|
||||
ticcmd_t * ticcmd = &netcmds[(maketic ) % BACKUPTICS][i];
|
||||
ticcmd_t *prevticcmd = &netcmds[(maketic - 1) % BACKUPTICS][i];
|
||||
|
||||
DEBFILE(va("MISS tic%4d for node %d\n", maketic, j));
|
||||
#if defined(PARANOIA) && 0
|
||||
CONS_Debug(DBG_NETPLAY, "Client Misstic %d\n", maketic);
|
||||
#endif
|
||||
// copy the old tic
|
||||
for (i = 0; i < playerpernode[j]; i++, player = nodetoplayer2[j])
|
||||
{
|
||||
netcmds[maketic%BACKUPTICS][player] = netcmds[(maketic-1)%BACKUPTICS][player];
|
||||
netcmds[maketic%BACKUPTICS][player].angleturn &= ~TICCMD_RECEIVED;
|
||||
}
|
||||
if (players[i].quittime)
|
||||
{
|
||||
// Copy the angle/aiming from the previous tic
|
||||
// and empty the other inputs
|
||||
memset(ticcmd, 0, sizeof(netcmds[0][0]));
|
||||
ticcmd->angleturn = prevticcmd->angleturn | TICCMD_RECEIVED;
|
||||
ticcmd->aiming = prevticcmd->aiming;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBFILE(va("MISS tic%4d for player %d\n", maketic, i));
|
||||
// Copy the input from the previous tic
|
||||
*ticcmd = *prevticcmd;
|
||||
ticcmd->angleturn &= ~TICCMD_RECEIVED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// all tic are now proceed make the next
|
||||
maketic++;
|
||||
|
@ -4833,13 +4875,8 @@ static inline void PingUpdate(void)
|
|||
if (pingtimeout[i] > cv_pingtimeout.value)
|
||||
// ok your net has been bad for too long, you deserve to die.
|
||||
{
|
||||
char buf[2];
|
||||
|
||||
pingtimeout[i] = 0;
|
||||
|
||||
buf[0] = (char)i;
|
||||
buf[1] = KICK_MSG_PING_HIGH;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
SendKick(i, KICK_MSG_PING_HIGH | KICK_MSG_KEEP_BODY);
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
|
|
@ -27,7 +27,7 @@ This version is independent of the mod name, and standard
|
|||
version and subversion. It should only account for the
|
||||
basic fields of the packet, and change infrequently.
|
||||
*/
|
||||
#define PACKETVERSION 1
|
||||
#define PACKETVERSION 2
|
||||
|
||||
// Network play related stuff.
|
||||
// There is a data struct that stores network
|
||||
|
@ -366,7 +366,6 @@ typedef struct
|
|||
UINT8 cheatsenabled;
|
||||
UINT8 isdedicated;
|
||||
UINT8 fileneedednum;
|
||||
SINT8 adminplayer;
|
||||
tic_t time;
|
||||
tic_t leveltime;
|
||||
char servername[MAXSERVERNAME];
|
||||
|
@ -398,7 +397,7 @@ typedef struct
|
|||
// Shorter player information for external use.
|
||||
typedef struct
|
||||
{
|
||||
UINT8 node;
|
||||
UINT8 num;
|
||||
char name[MAXPLAYERNAME+1];
|
||||
UINT8 address[4]; // sending another string would run us up against MAXPACKETLENGTH
|
||||
UINT8 team;
|
||||
|
@ -486,6 +485,7 @@ extern consvar_t cv_playbackspeed;
|
|||
#define KICK_MSG_PING_HIGH 6
|
||||
#define KICK_MSG_CUSTOM_KICK 7
|
||||
#define KICK_MSG_CUSTOM_BAN 8
|
||||
#define KICK_MSG_KEEP_BODY 0x80
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
@ -513,7 +513,9 @@ extern UINT32 realpingtable[MAXPLAYERS];
|
|||
extern UINT32 playerpingtable[MAXPLAYERS];
|
||||
extern tic_t servermaxping;
|
||||
|
||||
extern consvar_t cv_joinnextround, cv_allownewplayer, cv_maxplayers, cv_resynchattempts, cv_blamecfail, cv_maxsend, cv_noticedownload, cv_downloadspeed;
|
||||
extern consvar_t cv_allownewplayer, cv_joinnextround, cv_maxplayers, cv_rejointimeout;
|
||||
extern consvar_t cv_resynchattempts, cv_blamecfail;
|
||||
extern consvar_t cv_maxsend, cv_noticedownload, cv_downloadspeed;
|
||||
|
||||
// Used in d_net, the only dependence
|
||||
tic_t ExpandTics(INT32 low);
|
||||
|
@ -523,6 +525,7 @@ void D_ClientServerInit(void);
|
|||
void RegisterNetXCmd(netxcmd_t id, void (*cmd_f)(UINT8 **p, INT32 playernum));
|
||||
void SendNetXCmd(netxcmd_t id, const void *param, size_t nparam);
|
||||
void SendNetXCmd2(netxcmd_t id, const void *param, size_t nparam); // splitsreen player
|
||||
void SendKick(UINT8 playernum, UINT8 msg);
|
||||
|
||||
// Create any new ticcmds and broadcast to other players.
|
||||
void NetUpdate(void);
|
||||
|
|
18
src/d_main.c
18
src/d_main.c
|
@ -266,6 +266,9 @@ static void D_Display(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
if (rendermode == render_soft && !splitscreen)
|
||||
R_CheckViewMorph();
|
||||
|
||||
// change the view size if needed
|
||||
if (setsizeneeded || setrenderstillneeded)
|
||||
{
|
||||
|
@ -446,6 +449,9 @@ static void D_Display(void)
|
|||
// Image postprocessing effect
|
||||
if (rendermode == render_soft)
|
||||
{
|
||||
if (!splitscreen)
|
||||
R_ApplyViewMorph();
|
||||
|
||||
if (postimgtype)
|
||||
V_DoPostProcessor(0, postimgtype, postimgparam);
|
||||
if (postimgtype2)
|
||||
|
@ -652,8 +658,14 @@ void D_SRB2Loop(void)
|
|||
// hack to start on a nice clear console screen.
|
||||
COM_ImmedExecute("cls;version");
|
||||
|
||||
V_DrawScaledPatch(0, 0, 0, W_CachePatchNum(W_GetNumForName("CONSBACK"), PU_CACHE));
|
||||
I_FinishUpdate(); // page flip or blit buffer
|
||||
/*
|
||||
LMFAO this was showing garbage under OpenGL
|
||||
because I_FinishUpdate was called afterward
|
||||
*/
|
||||
/* Smells like a hack... Don't fade Sonic's ass into the title screen. */
|
||||
if (gamestate != GS_TITLESCREEN)
|
||||
V_DrawScaledPatch(0, 0, 0, W_CachePatchNum(W_GetNumForName("CONSBACK"), PU_CACHE));
|
||||
|
||||
for (;;)
|
||||
{
|
||||
|
@ -1046,10 +1058,8 @@ void D_SRB2Main(void)
|
|||
I_OutputMsg("setvbuf didnt work\n");
|
||||
#endif
|
||||
|
||||
#ifdef GETTEXT
|
||||
// initialise locale code
|
||||
M_StartupLocale();
|
||||
#endif
|
||||
|
||||
// get parameters from a response file (eg: srb2 @parms.txt)
|
||||
M_FindResponseFile();
|
||||
|
@ -1210,7 +1220,7 @@ void D_SRB2Main(void)
|
|||
#endif
|
||||
D_CleanFile();
|
||||
|
||||
#ifndef DEVELOP // md5s last updated 06/12/19 (ddmmyy)
|
||||
#ifndef DEVELOP // md5s last updated 16/02/20 (ddmmyy)
|
||||
|
||||
// Check MD5s of autoloaded files
|
||||
W_VerifyFileMD5(0, ASSET_HASH_SRB2_PK3); // srb2.pk3
|
||||
|
|
151
src/d_netcmd.c
151
src/d_netcmd.c
|
@ -579,6 +579,7 @@ void D_RegisterServerCommands(void)
|
|||
|
||||
// d_clisrv
|
||||
CV_RegisterVar(&cv_maxplayers);
|
||||
CV_RegisterVar(&cv_rejointimeout);
|
||||
CV_RegisterVar(&cv_resynchattempts);
|
||||
CV_RegisterVar(&cv_maxsend);
|
||||
CV_RegisterVar(&cv_noticedownload);
|
||||
|
@ -631,7 +632,7 @@ void D_RegisterClientCommands(void)
|
|||
// Set default player names
|
||||
// Monster Iestyn (12/08/19): not sure where else I could have actually put this, but oh well
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
sprintf(player_names[i], "Player %d", i);
|
||||
sprintf(player_names[i], "Player %d", 1 + i);
|
||||
|
||||
if (dedicated)
|
||||
return;
|
||||
|
@ -676,6 +677,7 @@ void D_RegisterClientCommands(void)
|
|||
// GIF variables
|
||||
CV_RegisterVar(&cv_gif_optimize);
|
||||
CV_RegisterVar(&cv_gif_downscale);
|
||||
CV_RegisterVar(&cv_gif_localcolortable);
|
||||
|
||||
#ifdef WALLSPLATS
|
||||
CV_RegisterVar(&cv_splats);
|
||||
|
@ -1007,7 +1009,7 @@ boolean EnsurePlayerNameIsGood(char *name, INT32 playernum)
|
|||
* SetPlayerName
|
||||
* \author Graue <graue@oceanbase.org>
|
||||
*/
|
||||
static void CleanupPlayerName(INT32 playernum, const char *newname)
|
||||
void CleanupPlayerName(INT32 playernum, const char *newname)
|
||||
{
|
||||
char *buf;
|
||||
char *p;
|
||||
|
@ -1035,6 +1037,17 @@ static void CleanupPlayerName(INT32 playernum, const char *newname)
|
|||
|
||||
tmpname = p;
|
||||
|
||||
do
|
||||
{
|
||||
/* from EnsurePlayerNameIsGood */
|
||||
if (!isprint(*p) || *p == ';' || (UINT8)*p >= 0x80)
|
||||
break;
|
||||
}
|
||||
while (*++p) ;
|
||||
|
||||
if (*p)/* bad char found */
|
||||
break;
|
||||
|
||||
// Remove trailing spaces.
|
||||
p = &tmpname[strlen(tmpname)-1]; // last character
|
||||
while (*p == ' ' && p >= tmpname)
|
||||
|
@ -1124,13 +1137,7 @@ static void SetPlayerName(INT32 playernum, char *newname)
|
|||
{
|
||||
CONS_Printf(M_GetText("Player %d sent a bad name change\n"), playernum+1);
|
||||
if (server && netgame)
|
||||
{
|
||||
UINT8 buf[2];
|
||||
|
||||
buf[0] = (UINT8)playernum;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1205,7 +1212,7 @@ static INT32 snacpending = 0, snac2pending = 0, chmappending = 0;
|
|||
//
|
||||
static void SendNameAndColor(void)
|
||||
{
|
||||
char buf[MAXPLAYERNAME+2];
|
||||
char buf[MAXPLAYERNAME+6];
|
||||
char *p;
|
||||
|
||||
p = buf;
|
||||
|
@ -1488,12 +1495,8 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
|
|||
|
||||
if (kick)
|
||||
{
|
||||
UINT8 buf[2];
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal color change received from %s (team: %d), color: %d)\n"), player_names[playernum], p->ctfteam, p->skincolor);
|
||||
|
||||
buf[0] = (UINT8)playernum;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -2033,13 +2036,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
|
|||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal map change received from %s\n"), player_names[playernum]);
|
||||
if (server)
|
||||
{
|
||||
UINT8 buf[2];
|
||||
|
||||
buf[0] = (UINT8)playernum;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2150,13 +2147,7 @@ static void Got_Pause(UINT8 **cp, INT32 playernum)
|
|||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal pause command received from %s\n"), player_names[playernum]);
|
||||
if (server)
|
||||
{
|
||||
UINT8 buf[2];
|
||||
|
||||
buf[0] = (UINT8)playernum;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2231,13 +2222,7 @@ static void Got_Suicide(UINT8 **cp, INT32 playernum)
|
|||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal suicide command received from %s\n"), player_names[playernum]);
|
||||
if (server)
|
||||
{
|
||||
UINT8 buf[2];
|
||||
|
||||
buf[0] = (UINT8)playernum;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2300,13 +2285,7 @@ static void Got_Clearscores(UINT8 **cp, INT32 playernum)
|
|||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal clear scores command received from %s\n"), player_names[playernum]);
|
||||
if (server)
|
||||
{
|
||||
UINT8 buf[2];
|
||||
|
||||
buf[0] = (UINT8)playernum;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2653,13 +2632,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
|
|||
// this should never happen unless the client is hacked/buggy
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]);
|
||||
if (server)
|
||||
{
|
||||
UINT8 buf[2];
|
||||
|
||||
buf[0] = (UINT8)playernum;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
}
|
||||
|
||||
if (NetPacket.packet.verification) // Special marker that the server sent the request
|
||||
|
@ -2668,13 +2641,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
|
|||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]);
|
||||
if (server)
|
||||
{
|
||||
UINT8 buf[2];
|
||||
|
||||
buf[0] = (UINT8)playernum;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
return;
|
||||
}
|
||||
playernum = NetPacket.packet.playernum;
|
||||
|
@ -2707,13 +2674,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
|
|||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]);
|
||||
if (server)
|
||||
{
|
||||
UINT8 buf[2];
|
||||
|
||||
buf[0] = (UINT8)playernum;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -2771,12 +2732,8 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
|
|||
|
||||
if (server && ((NetPacket.packet.newteam < 0 || NetPacket.packet.newteam > 3) || error))
|
||||
{
|
||||
UINT8 buf[2];
|
||||
|
||||
buf[0] = (UINT8)playernum;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal team change received from player %s\n"), player_names[playernum]);
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
}
|
||||
|
||||
//Safety first!
|
||||
|
@ -3068,13 +3025,7 @@ static void Got_Verification(UINT8 **cp, INT32 playernum)
|
|||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal verification received from %s (serverplayer is %s)\n"), player_names[playernum], player_names[serverplayer]);
|
||||
if (server)
|
||||
{
|
||||
UINT8 buf[2];
|
||||
|
||||
buf[0] = (UINT8)playernum;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3124,13 +3075,7 @@ static void Got_Removal(UINT8 **cp, INT32 playernum)
|
|||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal demotion received from %s (serverplayer is %s)\n"), player_names[playernum], player_names[serverplayer]);
|
||||
if (server)
|
||||
{
|
||||
UINT8 buf[2];
|
||||
|
||||
buf[0] = (UINT8)playernum;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3204,14 +3149,7 @@ static void Got_MotD_f(UINT8 **cp, INT32 playernum)
|
|||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal motd change received from %s\n"), player_names[playernum]);
|
||||
if (server)
|
||||
{
|
||||
UINT8 buf[2];
|
||||
|
||||
buf[0] = (UINT8)playernum;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
|
||||
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
Z_Free(mymotd);
|
||||
return;
|
||||
}
|
||||
|
@ -3267,13 +3205,7 @@ static void Got_RunSOCcmd(UINT8 **cp, INT32 playernum)
|
|||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal runsoc command received from %s\n"), player_names[playernum]);
|
||||
if (server)
|
||||
{
|
||||
UINT8 buf[2];
|
||||
|
||||
buf[0] = (UINT8)playernum;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3430,13 +3362,8 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
|
|||
|
||||
if ((playernum != serverplayer && !IsPlayerAdmin(playernum)) || kick)
|
||||
{
|
||||
UINT8 buf[2];
|
||||
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal addfile command received from %s\n"), player_names[playernum]);
|
||||
|
||||
buf[0] = (UINT8)playernum;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3485,13 +3412,7 @@ static void Got_Addfilecmd(UINT8 **cp, INT32 playernum)
|
|||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal addfile command received from %s\n"), player_names[playernum]);
|
||||
if (server)
|
||||
{
|
||||
UINT8 buf[2];
|
||||
|
||||
buf[0] = (UINT8)playernum;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4284,13 +4205,7 @@ static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum)
|
|||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal exitlevel command received from %s\n"), player_names[playernum]);
|
||||
if (server)
|
||||
{
|
||||
UINT8 buf[2];
|
||||
|
||||
buf[0] = (UINT8)playernum;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -194,6 +194,7 @@ typedef union {
|
|||
// add game commands, needs cleanup
|
||||
void D_RegisterServerCommands(void);
|
||||
void D_RegisterClientCommands(void);
|
||||
void CleanupPlayerName(INT32 playernum, const char *newname);
|
||||
boolean EnsurePlayerNameIsGood(char *name, INT32 playernum);
|
||||
void D_SendPlayerConfig(void);
|
||||
void Command_ExitGame_f(void);
|
||||
|
|
|
@ -326,6 +326,8 @@ typedef struct player_s
|
|||
// bounded/scaled total momentum.
|
||||
fixed_t bob;
|
||||
|
||||
angle_t viewrollangle;
|
||||
|
||||
// Mouse aiming, where the guy is looking at!
|
||||
// It is updated with cmd->aiming.
|
||||
angle_t aiming;
|
||||
|
@ -512,6 +514,7 @@ typedef struct player_s
|
|||
UINT8 bot;
|
||||
|
||||
tic_t jointime; // Timer when player joins game to change skin/color
|
||||
tic_t quittime; // Time elapsed since user disconnected, zero if connected
|
||||
#ifdef HWRENDER
|
||||
fixed_t fovadd; // adjust FOV for hw rendering
|
||||
#endif
|
||||
|
|
183
src/dehacked.c
183
src/dehacked.c
|
@ -585,21 +585,30 @@ static void readfreeslots(MYFILE *f)
|
|||
continue;
|
||||
// Copy in the spr2 name and increment free_spr2.
|
||||
if (free_spr2 < NUMPLAYERSPRITES) {
|
||||
CONS_Printf("Sprite SPR2_%s allocated.\n",word);
|
||||
strncpy(spr2names[free_spr2],word,4);
|
||||
spr2defaults[free_spr2] = 0;
|
||||
spr2names[free_spr2++][4] = 0;
|
||||
} else
|
||||
CONS_Alert(CONS_WARNING, "Ran out of free SPR2 slots!\n");
|
||||
deh_warning("Ran out of free SPR2 slots!\n");
|
||||
}
|
||||
else if (fastcmp(type, "TOL"))
|
||||
{
|
||||
if (lastcustomtol > 31)
|
||||
CONS_Alert(CONS_WARNING, "Ran out of free typeoflevel slots!\n");
|
||||
// Search if we already have a typeoflevel by that name...
|
||||
for (i = 0; TYPEOFLEVEL[i].name; i++)
|
||||
if (fastcmp(word, TYPEOFLEVEL[i].name))
|
||||
break;
|
||||
|
||||
// We found it? Then don't allocate another one.
|
||||
if (TYPEOFLEVEL[i].name)
|
||||
continue;
|
||||
|
||||
// We don't, so freeslot it.
|
||||
if (lastcustomtol == (UINT32)MAXTOL) // Unless you have way too many, since they're flags.
|
||||
deh_warning("Ran out of free typeoflevel slots!\n");
|
||||
else
|
||||
{
|
||||
G_AddTOL((1<<lastcustomtol), word);
|
||||
lastcustomtol++;
|
||||
G_AddTOL(lastcustomtol, word);
|
||||
lastcustomtol <<= 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1105,38 +1114,7 @@ static void readsprite2(MYFILE *f, INT32 num)
|
|||
Z_Free(s);
|
||||
}
|
||||
|
||||
INT32 numtolinfo = NUMBASETOL;
|
||||
UINT32 lastcustomtol = 13;
|
||||
|
||||
tolinfo_t TYPEOFLEVEL[NUMMAXTOL] = {
|
||||
{"SOLO",TOL_SP},
|
||||
{"SP",TOL_SP},
|
||||
{"SINGLEPLAYER",TOL_SP},
|
||||
{"SINGLE",TOL_SP},
|
||||
|
||||
{"COOP",TOL_COOP},
|
||||
{"CO-OP",TOL_COOP},
|
||||
|
||||
{"COMPETITION",TOL_COMPETITION},
|
||||
{"RACE",TOL_RACE},
|
||||
|
||||
{"MATCH",TOL_MATCH},
|
||||
{"TAG",TOL_TAG},
|
||||
{"CTF",TOL_CTF},
|
||||
|
||||
{"2D",TOL_2D},
|
||||
{"MARIO",TOL_MARIO},
|
||||
{"NIGHTS",TOL_NIGHTS},
|
||||
{"OLDBRAK",TOL_ERZ3},
|
||||
|
||||
{"XMAS",TOL_XMAS},
|
||||
{"CHRISTMAS",TOL_XMAS},
|
||||
{"WINTER",TOL_XMAS},
|
||||
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
// copypasted from readPlayer :sleep:
|
||||
// copypasted from readPlayer :]
|
||||
static const char *const GAMETYPERULE_LIST[];
|
||||
static void readgametype(MYFILE *f, char *gtname)
|
||||
{
|
||||
|
@ -1293,10 +1271,7 @@ static void readgametype(MYFILE *f, char *gtname)
|
|||
UINT32 wordgt = 0;
|
||||
for (j = 0; GAMETYPERULE_LIST[j]; j++)
|
||||
if (fastcmp(word, GAMETYPERULE_LIST[j])) {
|
||||
if (!j) // GTR_CAMPAIGN
|
||||
wordgt |= 1;
|
||||
else
|
||||
wordgt |= (1<<j);
|
||||
wordgt |= (1<<j);
|
||||
if (i || word2[0] == 'T' || word2[0] == 'Y')
|
||||
newgtrules |= wordgt;
|
||||
break;
|
||||
|
@ -1629,6 +1604,11 @@ static void readlevelheader(MYFILE *f, INT32 num)
|
|||
mapheaderinfo[num-1]->typeoflevel = tol;
|
||||
}
|
||||
}
|
||||
else if (fastcmp(word, "KEYWORDS"))
|
||||
{
|
||||
deh_strlcpy(mapheaderinfo[num-1]->keywords, word2,
|
||||
sizeof(mapheaderinfo[num-1]->keywords), va("Level header %d: keywords", num));
|
||||
}
|
||||
else if (fastcmp(word, "MUSIC"))
|
||||
{
|
||||
if (fastcmp(word2, "NONE"))
|
||||
|
@ -4941,19 +4921,19 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_PLAY_SUPER_TRANS3",
|
||||
"S_PLAY_SUPER_TRANS4",
|
||||
"S_PLAY_SUPER_TRANS5",
|
||||
"S_PLAY_SUPER_TRANS6", // This has special significance in the code. If you add more frames, search for it and make the appropriate changes.
|
||||
"S_PLAY_SUPER_TRANS6",
|
||||
|
||||
// technically the player goes here but it's an infinite tic state
|
||||
"S_OBJPLACE_DUMMY",
|
||||
|
||||
// 1-Up Box Sprites (uses player sprite)
|
||||
// 1-Up Box Sprites overlay (uses player sprite)
|
||||
"S_PLAY_BOX1",
|
||||
"S_PLAY_BOX2",
|
||||
"S_PLAY_ICON1",
|
||||
"S_PLAY_ICON2",
|
||||
"S_PLAY_ICON3",
|
||||
|
||||
// Level end sign (uses player sprite)
|
||||
// Level end sign overlay (uses player sprite)
|
||||
"S_PLAY_SIGN",
|
||||
|
||||
// NiGHTS character (uses player sprite)
|
||||
|
@ -5201,7 +5181,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_ROBOHOOD_JUMP2",
|
||||
"S_ROBOHOOD_JUMP3",
|
||||
|
||||
// CastleBot FaceStabber
|
||||
// Castlebot Facestabber
|
||||
"S_FACESTABBER_STND1",
|
||||
"S_FACESTABBER_STND2",
|
||||
"S_FACESTABBER_STND3",
|
||||
|
@ -5421,6 +5401,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_EGGMOBILE_FLEE2",
|
||||
"S_EGGMOBILE_BALL",
|
||||
"S_EGGMOBILE_TARGET",
|
||||
|
||||
"S_BOSSEGLZ1",
|
||||
"S_BOSSEGLZ2",
|
||||
|
||||
|
@ -5473,7 +5454,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_EGGMOBILE3_FLEE1",
|
||||
"S_EGGMOBILE3_FLEE2",
|
||||
|
||||
// Boss 3 pinch
|
||||
// Boss 3 Pinch
|
||||
"S_FAKEMOBILE_INIT",
|
||||
"S_FAKEMOBILE",
|
||||
"S_FAKEMOBILE_ATK1",
|
||||
|
@ -5489,7 +5470,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_BOSSSEBH2",
|
||||
|
||||
// Boss 3 Shockwave
|
||||
|
||||
"S_SHOCKWAVE1",
|
||||
"S_SHOCKWAVE2",
|
||||
|
||||
|
@ -5526,9 +5506,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_JETFLAME",
|
||||
|
||||
// Boss 4 Spectator Eggrobo
|
||||
"S_EGGROBO1_IDLE",
|
||||
"S_EGGROBO1_STND",
|
||||
"S_EGGROBO1_BSLAP1",
|
||||
"S_EGGROBO2_BSLAP2",
|
||||
"S_EGGROBO1_BSLAP2",
|
||||
"S_EGGROBO1_PISSED",
|
||||
|
||||
// Boss 4 Spectator Eggrobo jet flame
|
||||
|
@ -5772,7 +5752,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_CYBRAKDEMON_NAPALM_ATTACK1",
|
||||
"S_CYBRAKDEMON_NAPALM_ATTACK2",
|
||||
"S_CYBRAKDEMON_NAPALM_ATTACK3",
|
||||
"S_CYBRAKDEMON_FINISH_ATTACK", // If just attacked, remove MF2_FRET w/out going back to spawnstate
|
||||
"S_CYBRAKDEMON_FINISH_ATTACK1", // If just attacked, remove MF2_FRET w/out going back to spawnstate
|
||||
"S_CYBRAKDEMON_FINISH_ATTACK2", // Force a delay between attacks so you don't get bombarded with them back-to-back
|
||||
"S_CYBRAKDEMON_PAIN1",
|
||||
"S_CYBRAKDEMON_PAIN2",
|
||||
|
@ -6016,6 +5996,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_SIGNSTOP",
|
||||
"S_SIGNBOARD",
|
||||
"S_EGGMANSIGN",
|
||||
"S_CLEARSIGN",
|
||||
|
||||
// Spike Ball
|
||||
"S_SPIKEBALL1",
|
||||
|
@ -6465,7 +6446,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_LITTLETUMBLEWEED_ROLL7",
|
||||
"S_LITTLETUMBLEWEED_ROLL8",
|
||||
|
||||
// Cacti Sprites
|
||||
// Cacti
|
||||
"S_CACTI1",
|
||||
"S_CACTI2",
|
||||
"S_CACTI3",
|
||||
|
@ -6480,7 +6461,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_CACTITINYSEG",
|
||||
"S_CACTISMALLSEG",
|
||||
|
||||
// Warning signs sprites
|
||||
// Warning signs
|
||||
"S_ARIDSIGN_CAUTION",
|
||||
"S_ARIDSIGN_CACTI",
|
||||
"S_ARIDSIGN_SHARPTURN",
|
||||
|
@ -6497,6 +6478,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_TNTBARREL_EXPL4",
|
||||
"S_TNTBARREL_EXPL5",
|
||||
"S_TNTBARREL_EXPL6",
|
||||
"S_TNTBARREL_EXPL7",
|
||||
"S_TNTBARREL_FLYING",
|
||||
|
||||
// TNT proximity shell
|
||||
|
@ -7042,7 +7024,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_ZAPSB10",
|
||||
"S_ZAPSB11", // blank frame
|
||||
|
||||
// Thunder spark
|
||||
//Thunder spark
|
||||
"S_THUNDERCOIN_SPARK",
|
||||
|
||||
// Invincibility Sparkles
|
||||
|
@ -7343,6 +7325,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_BHORIZ7",
|
||||
"S_BHORIZ8",
|
||||
|
||||
// Booster
|
||||
"S_BOOSTERSOUND",
|
||||
"S_YELLOWBOOSTERROLLER",
|
||||
"S_YELLOWBOOSTERSEG_LEFT",
|
||||
|
@ -7373,7 +7356,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_SPLISH8",
|
||||
"S_SPLISH9",
|
||||
|
||||
// Lava splish
|
||||
// Lava Splish
|
||||
"S_LAVASPLISH",
|
||||
|
||||
// added water splash
|
||||
|
@ -7969,6 +7952,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_ROCKCRUMBLEN",
|
||||
"S_ROCKCRUMBLEO",
|
||||
"S_ROCKCRUMBLEP",
|
||||
|
||||
// Level debris
|
||||
"S_GFZDEBRIS",
|
||||
"S_BRICKDEBRIS",
|
||||
"S_WOODDEBRIS",
|
||||
|
@ -7988,7 +7973,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_THOK", // Thok! mobj
|
||||
"MT_PLAYER",
|
||||
"MT_TAILSOVERLAY", // c:
|
||||
"MT_METALJETFUME", // [:
|
||||
"MT_METALJETFUME",
|
||||
|
||||
// Enemies
|
||||
"MT_BLUECRAWLA", // Crawla (Blue)
|
||||
|
@ -8105,7 +8090,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_CYBRAKDEMON_NAPALM_FLAMES",
|
||||
"MT_CYBRAKDEMON_VILE_EXPLOSION",
|
||||
|
||||
// Metal Sonic
|
||||
// Metal Sonic (Boss 9)
|
||||
"MT_METALSONIC_RACE",
|
||||
"MT_METALSONIC_BATTLE",
|
||||
"MT_MSSHIELD_FRONT",
|
||||
|
@ -8119,7 +8104,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_BOMBSPHERE",
|
||||
"MT_REDTEAMRING", //Rings collectable by red team.
|
||||
"MT_BLUETEAMRING", //Rings collectable by blue team.
|
||||
"MT_TOKEN", // Special Stage Token
|
||||
"MT_TOKEN", // Special Stage token for special stage
|
||||
"MT_REDFLAG", // Red CTF Flag
|
||||
"MT_BLUEFLAG", // Blue CTF Flag
|
||||
"MT_EMBLEM",
|
||||
|
@ -8345,22 +8330,22 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
// Arid Canyon Scenery
|
||||
"MT_BIGTUMBLEWEED",
|
||||
"MT_LITTLETUMBLEWEED",
|
||||
"MT_CACTI1",
|
||||
"MT_CACTI2",
|
||||
"MT_CACTI3",
|
||||
"MT_CACTI4",
|
||||
"MT_CACTI5",
|
||||
"MT_CACTI6",
|
||||
"MT_CACTI7",
|
||||
"MT_CACTI8",
|
||||
"MT_CACTI9",
|
||||
"MT_CACTI10",
|
||||
"MT_CACTI11",
|
||||
"MT_CACTITINYSEG",
|
||||
"MT_CACTISMALLSEG",
|
||||
"MT_ARIDSIGN_CAUTION",
|
||||
"MT_ARIDSIGN_CACTI",
|
||||
"MT_ARIDSIGN_SHARPTURN",
|
||||
"MT_CACTI1", // Tiny Red Flower Cactus
|
||||
"MT_CACTI2", // Small Red Flower Cactus
|
||||
"MT_CACTI3", // Tiny Blue Flower Cactus
|
||||
"MT_CACTI4", // Small Blue Flower Cactus
|
||||
"MT_CACTI5", // Prickly Pear
|
||||
"MT_CACTI6", // Barrel Cactus
|
||||
"MT_CACTI7", // Tall Barrel Cactus
|
||||
"MT_CACTI8", // Armed Cactus
|
||||
"MT_CACTI9", // Ball Cactus
|
||||
"MT_CACTI10", // Tiny Cactus
|
||||
"MT_CACTI11", // Small Cactus
|
||||
"MT_CACTITINYSEG", // Tiny Cactus Segment
|
||||
"MT_CACTISMALLSEG", // Small Cactus Segment
|
||||
"MT_ARIDSIGN_CAUTION", // Caution Sign
|
||||
"MT_ARIDSIGN_CACTI", // Cacti Sign
|
||||
"MT_ARIDSIGN_SHARPTURN", // Sharp Turn Sign
|
||||
"MT_OILLAMP",
|
||||
"MT_TNTBARREL",
|
||||
"MT_PROXIMITYTNT",
|
||||
|
@ -8415,7 +8400,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_GLAREGOYLEUP",
|
||||
"MT_GLAREGOYLEDOWN",
|
||||
"MT_GLAREGOYLELONG",
|
||||
"MT_TARGET",
|
||||
"MT_TARGET", // AKA Red Crystal
|
||||
"MT_GREENFLAME",
|
||||
"MT_BLUEGARGOYLE",
|
||||
|
||||
|
@ -8466,7 +8451,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_HHZSTALAGMITE_TALL",
|
||||
"MT_HHZSTALAGMITE_SHORT",
|
||||
|
||||
// Botanic Serenity
|
||||
// Botanic Serenity scenery
|
||||
"MT_BSZTALLFLOWER_RED",
|
||||
"MT_BSZTALLFLOWER_PURPLE",
|
||||
"MT_BSZTALLFLOWER_BLUE",
|
||||
|
@ -8746,6 +8731,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
|
|||
"MT_ROCKCRUMBLE14",
|
||||
"MT_ROCKCRUMBLE15",
|
||||
"MT_ROCKCRUMBLE16",
|
||||
|
||||
// Level debris
|
||||
"MT_GFZDEBRIS",
|
||||
"MT_BRICKDEBRIS",
|
||||
"MT_WOODDEBRIS",
|
||||
|
@ -8842,7 +8829,7 @@ static const char *const MOBJEFLAG_LIST[] = {
|
|||
|
||||
#ifdef HAVE_BLUA
|
||||
static const char *const MAPTHINGFLAG_LIST[4] = {
|
||||
NULL,
|
||||
"EXTRA", // Extra flag for objects.
|
||||
"OBJECTFLIP", // Reverse gravity flag for objects.
|
||||
"OBJECTSPECIAL", // Special flag used with certain objects.
|
||||
"AMBUSH" // Deaf monsters/do not react to sound.
|
||||
|
@ -9141,6 +9128,7 @@ static const char *const HUDITEMS_LIST[] = {
|
|||
|
||||
"RINGS",
|
||||
"RINGSNUM",
|
||||
"RINGSNUMTICS",
|
||||
|
||||
"SCORE",
|
||||
"SCORENUM",
|
||||
|
@ -9160,8 +9148,7 @@ static const char *const HUDITEMS_LIST[] = {
|
|||
"TIMELEFTNUM",
|
||||
"TIMEUP",
|
||||
"HUNTPICS",
|
||||
"POWERUPS",
|
||||
"LAP"
|
||||
"POWERUPS"
|
||||
};
|
||||
|
||||
static const char *const MENUTYPES_LIST[] = {
|
||||
|
@ -9425,7 +9412,7 @@ struct {
|
|||
{"SH_FORCE",SH_FORCE},
|
||||
{"SH_FORCEHP",SH_FORCEHP}, // to be used as a bitmask only
|
||||
// Mostly for use with Mario mode.
|
||||
{"SH_FIREFLOWER", SH_FIREFLOWER},
|
||||
{"SH_FIREFLOWER",SH_FIREFLOWER},
|
||||
{"SH_STACK",SH_STACK},
|
||||
{"SH_NOSTACK",SH_NOSTACK},
|
||||
|
||||
|
@ -9440,7 +9427,7 @@ struct {
|
|||
{"CR_ROPEHANG",CR_ROPEHANG},
|
||||
{"CR_MACESPIN",CR_MACESPIN},
|
||||
{"CR_MINECART",CR_MINECART},
|
||||
{"CR_ROLLOUT", CR_ROLLOUT},
|
||||
{"CR_ROLLOUT",CR_ROLLOUT},
|
||||
{"CR_PTERABYTE",CR_PTERABYTE},
|
||||
|
||||
// Ring weapons (ringweapons_t)
|
||||
|
@ -9607,7 +9594,7 @@ struct {
|
|||
{"NUM_WEAPONS",NUM_WEAPONS},
|
||||
|
||||
// Value for infinite lives
|
||||
{"INFLIVES", INFLIVES},
|
||||
{"INFLIVES",INFLIVES},
|
||||
|
||||
// Got Flags, for player->gotflag!
|
||||
// Used to be MF_ for some stupid reason, now they're GF_ to stop them looking like mobjflags
|
||||
|
@ -9668,10 +9655,11 @@ struct {
|
|||
{"FF_QUICKSAND",FF_QUICKSAND}, ///< Quicksand!
|
||||
{"FF_PLATFORM",FF_PLATFORM}, ///< You can jump up through this to the top.
|
||||
{"FF_REVERSEPLATFORM",FF_REVERSEPLATFORM}, ///< A fall-through floor in normal gravity, a platform in reverse gravity.
|
||||
{"FF_INTANGABLEFLATS",FF_INTANGABLEFLATS}, ///< Both flats are intangable, but the sides are still solid.
|
||||
{"FF_INTANGIBLEFLATS",FF_INTANGIBLEFLATS}, ///< Both flats are intangible, but the sides are still solid.
|
||||
{"FF_INTANGABLEFLATS",FF_INTANGIBLEFLATS}, ///< Both flats are intangable, but the sides are still solid.
|
||||
{"FF_SHATTER",FF_SHATTER}, ///< Used with ::FF_BUSTUP. Bustable on mere touch.
|
||||
{"FF_SPINBUST",FF_SPINBUST}, ///< Used with ::FF_BUSTUP. Also bustable if you're in your spinning frames.
|
||||
{"FF_STRONGBUST",FF_STRONGBUST }, ///< Used with ::FF_BUSTUP. Only bustable by "strong" characters (Knuckles) and abilities (bouncing, twinspin, melee).
|
||||
{"FF_STRONGBUST",FF_STRONGBUST}, ///< Used with ::FF_BUSTUP. Only bustable by "strong" characters (Knuckles) and abilities (bouncing, twinspin, melee).
|
||||
{"FF_RIPPLE",FF_RIPPLE}, ///< Ripple the flats
|
||||
{"FF_COLORMAPONLY",FF_COLORMAPONLY}, ///< Only copy the colormap, not the lightlevel
|
||||
{"FF_GOOWATER",FF_GOOWATER}, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop.
|
||||
|
@ -10462,16 +10450,23 @@ static inline int lib_freeslot(lua_State *L)
|
|||
}
|
||||
else if (fastcmp(type, "TOL"))
|
||||
{
|
||||
if (lastcustomtol > 31)
|
||||
CONS_Alert(CONS_WARNING, "Ran out of free typeoflevel slots!\n");
|
||||
else
|
||||
{
|
||||
UINT32 newtol = (1<<lastcustomtol);
|
||||
CONS_Printf("TypeOfLevel TOL_%s allocated.\n",word);
|
||||
G_AddTOL(newtol, word);
|
||||
lua_pushinteger(L, newtol);
|
||||
lastcustomtol++;
|
||||
r++;
|
||||
// Search if we already have a typeoflevel by that name...
|
||||
int i;
|
||||
for (i = 0; TYPEOFLEVEL[i].name; i++)
|
||||
if (fastcmp(word, TYPEOFLEVEL[i].name))
|
||||
break;
|
||||
|
||||
// We don't, so allocate a new one.
|
||||
if (TYPEOFLEVEL[i].name == NULL) {
|
||||
if (lastcustomtol == (UINT32)MAXTOL) // Unless you have way too many, since they're flags.
|
||||
CONS_Alert(CONS_WARNING, "Ran out of free typeoflevel slots!\n");
|
||||
else {
|
||||
CONS_Printf("TypeOfLevel TOL_%s allocated.\n",word);
|
||||
G_AddTOL(lastcustomtol, word);
|
||||
lua_pushinteger(L, lastcustomtol);
|
||||
lastcustomtol <<= 1;
|
||||
r++;
|
||||
}
|
||||
}
|
||||
}
|
||||
Z_Free(s);
|
||||
|
|
|
@ -98,8 +98,8 @@
|
|||
|
||||
#ifdef GETTEXT
|
||||
#include <libintl.h>
|
||||
#include <locale.h>
|
||||
#endif
|
||||
#include <locale.h> // locale should not be dependent on GETTEXT -- 11/01/20 Monster Iestyn
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -143,9 +143,9 @@ extern char logfilename[1024];
|
|||
// we use comprevision and compbranch instead.
|
||||
#else
|
||||
#define VERSION 202 // Game version
|
||||
#define SUBVERSION 0 // more precise version number
|
||||
#define VERSIONSTRING "v2.2.0"
|
||||
#define VERSIONSTRINGW L"v2.2.0"
|
||||
#define SUBVERSION 1 // more precise version number
|
||||
#define VERSIONSTRING "v2.2.1"
|
||||
#define VERSIONSTRINGW L"v2.2.1"
|
||||
// Hey! If you change this, add 1 to the MODVERSION below!
|
||||
// Otherwise we can't force updates!
|
||||
#endif
|
||||
|
@ -210,7 +210,7 @@ extern char logfilename[1024];
|
|||
// 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.
|
||||
// Note that we use this to help keep internal testing in check; this is why v2.2.0 is not version "1".
|
||||
#define MODVERSION 40
|
||||
#define MODVERSION 41
|
||||
|
||||
// To version config.cfg, MAJOREXECVERSION is set equal to MODVERSION automatically.
|
||||
// Increment MINOREXECVERSION whenever a config change is needed that does not correspond
|
||||
|
@ -454,12 +454,12 @@ char savegamename[256];
|
|||
// m_misc.h
|
||||
#ifdef GETTEXT
|
||||
#define M_GetText(String) gettext(String)
|
||||
void M_StartupLocale(void);
|
||||
#else
|
||||
// If no translations are to be used, make a stub
|
||||
// M_GetText function that just returns the string.
|
||||
#define M_GetText(x) (x)
|
||||
#endif
|
||||
void M_StartupLocale(void);
|
||||
extern void *(*M_Memcpy)(void* dest, const void* src, size_t n) FUNCNONNULL;
|
||||
char *va(const char *format, ...) FUNCPRINTF;
|
||||
char *M_GetToken(const char *inputString);
|
||||
|
@ -490,6 +490,7 @@ extern INT32 cv_debug;
|
|||
#define DBG_SETUP 0x0400
|
||||
#define DBG_LUA 0x0800
|
||||
#define DBG_RANDOMIZER 0x1000
|
||||
#define DBG_VIEWMORPH 0x2000
|
||||
|
||||
// =======================
|
||||
// Misc stuff for later...
|
||||
|
@ -546,6 +547,8 @@ INT32 I_GetKey(void);
|
|||
#define PATHSEP "/"
|
||||
#endif
|
||||
|
||||
#define PUNCTUATION "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"
|
||||
|
||||
// Compile date and time and revision.
|
||||
extern const char *compdate, *comptime, *comprevision, *compbranch;
|
||||
|
||||
|
|
|
@ -289,6 +289,7 @@ typedef struct
|
|||
UINT8 actnum; ///< Act number or 0 for none.
|
||||
UINT32 typeoflevel; ///< Combination of typeoflevel flags.
|
||||
INT16 nextlevel; ///< Map number of next level, or 1100-1102 to end.
|
||||
char keywords[33]; ///< Keywords separated by space to search for. 32 characters.
|
||||
char musname[7]; ///< Music track to play. "" for no music.
|
||||
UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore.
|
||||
UINT32 muspos; ///< Music position to jump to.
|
||||
|
@ -436,6 +437,7 @@ extern const char *Gametype_ConstantNames[NUMGAMETYPES];
|
|||
extern INT32 pointlimits[NUMGAMETYPES];
|
||||
extern INT32 timelimits[NUMGAMETYPES];
|
||||
|
||||
// TypeOfLevel things
|
||||
enum TypeOfLevel
|
||||
{
|
||||
TOL_SP = 0x01, ///< Single Player
|
||||
|
@ -460,16 +462,16 @@ enum TypeOfLevel
|
|||
TOL_XMAS = 0x1000, ///< Christmas NiGHTS
|
||||
};
|
||||
|
||||
#define NUMBASETOL 18
|
||||
#define NUMMAXTOL (18 + NUMGAMETYPEFREESLOTS)
|
||||
#define MAXTOL (1<<31)
|
||||
#define NUMBASETOLNAMES (19)
|
||||
#define NUMTOLNAMES (NUMBASETOLNAMES + NUMGAMETYPEFREESLOTS)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char *name;
|
||||
UINT32 flag;
|
||||
} tolinfo_t;
|
||||
extern tolinfo_t TYPEOFLEVEL[NUMMAXTOL];
|
||||
extern INT32 numtolinfo;
|
||||
extern tolinfo_t TYPEOFLEVEL[NUMTOLNAMES];
|
||||
extern UINT32 lastcustomtol;
|
||||
|
||||
extern tic_t totalplaytime;
|
||||
|
|
|
@ -1120,6 +1120,9 @@ static const char *credits[] = {
|
|||
"\1Sonic Robo Blast II",
|
||||
"\1Credits",
|
||||
"",
|
||||
"\1Producer",
|
||||
"Rob Tisdell",
|
||||
"",
|
||||
"\1Game Design",
|
||||
"Ben \"Mystic\" Geyer",
|
||||
"\"SSNTails\"",
|
||||
|
@ -1165,6 +1168,7 @@ static const char *credits[] = {
|
|||
"Tasos \"tatokis\" Sahanidis", // Corrected C FixedMul, making 64-bit builds netplay compatible
|
||||
"Wessel \"sphere\" Smit",
|
||||
"Ben \"Cue\" Woodford",
|
||||
"Ikaro \"Tatsuru\" Vinhas",
|
||||
// Git contributors with 5+ approved merges of substantive quality,
|
||||
// or contributors with at least one groundbreaking merge, may be named.
|
||||
// Everyone else is acknowledged under "Special Thanks > SRB2 Community Contributors".
|
||||
|
@ -1233,6 +1237,7 @@ static const char *credits[] = {
|
|||
"Thomas \"Shadow Hog\" Igoe",
|
||||
"Alexander \"DrTapeworm\" Moench-Ford",
|
||||
"\"Kaito Sinclaire\"",
|
||||
"Anna \"QueenDelta\" Sandlin",
|
||||
"Wessel \"sphere\" Smit",
|
||||
"\"Spazzo\"",
|
||||
"\"SSNTails\"",
|
||||
|
@ -1256,7 +1261,7 @@ static const char *credits[] = {
|
|||
"Cody \"SRB2 Playah\" Koester",
|
||||
"Skye \"OmegaVelocity\" Meredith",
|
||||
"Stephen \"HEDGESMFG\" Moellering",
|
||||
"Nick \"ST218\" Molina",
|
||||
"Rosalie \"ST218\" Molina",
|
||||
"Samuel \"Prime 2.0\" Peters",
|
||||
"Colin \"Sonict\" Pfaff",
|
||||
"Bill \"Tets\" Reed",
|
||||
|
@ -2693,8 +2698,18 @@ static void F_FigureActiveTtScale(void)
|
|||
SINT8 newttscale = max(1, min(6, vid.dupx));
|
||||
SINT8 oldttscale = activettscale;
|
||||
|
||||
if (newttscale == testttscale)
|
||||
return;
|
||||
if (needpatchrecache)
|
||||
ttloaded[0] = ttloaded[1] = ttloaded[2] = ttloaded[3] = ttloaded[4] = ttloaded[5] = 0;
|
||||
else
|
||||
{
|
||||
if (newttscale == testttscale)
|
||||
return;
|
||||
|
||||
// We have a new ttscale, so load gfx
|
||||
if(oldttscale > 0)
|
||||
F_UnloadAlacroixGraphics(oldttscale);
|
||||
}
|
||||
|
||||
testttscale = newttscale;
|
||||
|
||||
// If ttscale is unavailable: look for lower scales, then higher scales.
|
||||
|
@ -2712,10 +2727,6 @@ static void F_FigureActiveTtScale(void)
|
|||
|
||||
activettscale = (newttscale >= 1 && newttscale <= 6) ? newttscale : 0;
|
||||
|
||||
// We have a new ttscale, so load gfx
|
||||
if(oldttscale > 0)
|
||||
F_UnloadAlacroixGraphics(oldttscale);
|
||||
|
||||
if(activettscale > 0)
|
||||
F_LoadAlacroixGraphics(activettscale);
|
||||
}
|
||||
|
@ -2757,12 +2768,6 @@ void F_TitleScreenDrawer(void)
|
|||
return;
|
||||
#endif
|
||||
|
||||
if (needpatchrecache && (curttmode == TTMODE_ALACROIX))
|
||||
{
|
||||
ttloaded[0] = ttloaded[1] = ttloaded[2] = ttloaded[3] = ttloaded[4] = ttloaded[5] = 0;
|
||||
F_LoadAlacroixGraphics(activettscale);
|
||||
}
|
||||
|
||||
switch(curttmode)
|
||||
{
|
||||
case TTMODE_OLD:
|
||||
|
@ -3628,7 +3633,6 @@ void F_StartContinue(void)
|
|||
}
|
||||
|
||||
wipestyleflags = WSF_FADEOUT;
|
||||
F_TryColormapFade(31);
|
||||
G_SetGamestate(GS_CONTINUING);
|
||||
gameaction = ga_nothing;
|
||||
|
||||
|
|
210
src/g_game.c
210
src/g_game.c
|
@ -352,8 +352,8 @@ static CV_PossibleValue_t chattime_cons_t[] = {{5, "MIN"}, {999, "MAX"}, {0, NUL
|
|||
consvar_t cv_chattime = {"chattime", "8", CV_SAVE, chattime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// chatwidth
|
||||
static CV_PossibleValue_t chatwidth_cons_t[] = {{64, "MIN"}, {150, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_chatwidth = {"chatwidth", "128", CV_SAVE, chatwidth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
static CV_PossibleValue_t chatwidth_cons_t[] = {{64, "MIN"}, {300, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_chatwidth = {"chatwidth", "150", CV_SAVE, chatwidth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// chatheight
|
||||
static CV_PossibleValue_t chatheight_cons_t[] = {{6, "MIN"}, {22, "MAX"}, {0, NULL}};
|
||||
|
@ -1140,7 +1140,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
INT32 *myaiming = (ssplayer == 1 ? &localaiming : &localaiming2);
|
||||
|
||||
angle_t drawangleoffset = (player->powers[pw_carry] == CR_ROLLOUT) ? ANGLE_180 : 0;
|
||||
INT32 chasecam, chasefreelook, alwaysfreelook, usejoystick, invertmouse, mousemove;
|
||||
INT32 chasecam, chasefreelook, alwaysfreelook, usejoystick, invertmouse, turnmultiplier, mousemove;
|
||||
controlstyle_e controlstyle = G_ControlStyle(ssplayer);
|
||||
INT32 *mx; INT32 *my; INT32 *mly;
|
||||
|
||||
|
@ -1163,6 +1163,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
alwaysfreelook = cv_alwaysfreelook.value;
|
||||
usejoystick = cv_usejoystick.value;
|
||||
invertmouse = cv_invertmouse.value;
|
||||
turnmultiplier = cv_cam_turnmultiplier.value;
|
||||
mousemove = cv_mousemove.value;
|
||||
mx = &mousex;
|
||||
my = &mousey;
|
||||
|
@ -1176,6 +1177,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
alwaysfreelook = cv_alwaysfreelook2.value;
|
||||
usejoystick = cv_usejoystick2.value;
|
||||
invertmouse = cv_invertmouse2.value;
|
||||
turnmultiplier = cv_cam2_turnmultiplier.value;
|
||||
mousemove = cv_mousemove2.value;
|
||||
mx = &mouse2x;
|
||||
my = &mouse2y;
|
||||
|
@ -1293,14 +1295,14 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
{
|
||||
if (turnright && turnleft);
|
||||
else if (turnright)
|
||||
cmd->angleturn = (INT16)(cmd->angleturn - ((angleturn[tspeed] * cv_cam_turnmultiplier.value)>>FRACBITS));
|
||||
cmd->angleturn = (INT16)(cmd->angleturn - ((angleturn[tspeed] * turnmultiplier)>>FRACBITS));
|
||||
else if (turnleft)
|
||||
cmd->angleturn = (INT16)(cmd->angleturn + ((angleturn[tspeed] * cv_cam_turnmultiplier.value)>>FRACBITS));
|
||||
cmd->angleturn = (INT16)(cmd->angleturn + ((angleturn[tspeed] * turnmultiplier)>>FRACBITS));
|
||||
|
||||
if (analogjoystickmove && lookjoystickvector.xaxis != 0)
|
||||
{
|
||||
// JOYAXISRANGE should be 1023 (divide by 1024)
|
||||
cmd->angleturn = (INT16)(cmd->angleturn - ((((lookjoystickvector.xaxis * angleturn[1]) >> 10) * cv_cam_turnmultiplier.value)>>FRACBITS)); // ANALOG!
|
||||
cmd->angleturn = (INT16)(cmd->angleturn - ((((lookjoystickvector.xaxis * angleturn[1]) >> 10) * turnmultiplier)>>FRACBITS)); // ANALOG!
|
||||
}
|
||||
|
||||
if (turnright || turnleft || abs(cmd->angleturn) > angleturn[2])
|
||||
|
@ -1939,6 +1941,10 @@ boolean G_IsTitleCardAvailable(void)
|
|||
if (gametyperules & GTR_NOTITLECARD)
|
||||
return false;
|
||||
|
||||
// The current level has no name.
|
||||
if (!mapheaderinfo[gamemap-1]->lvlttl[0])
|
||||
return false;
|
||||
|
||||
// The title card is available.
|
||||
return true;
|
||||
}
|
||||
|
@ -2412,6 +2418,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
INT32 skin;
|
||||
UINT32 availabilities;
|
||||
tic_t jointime;
|
||||
tic_t quittime;
|
||||
boolean spectator;
|
||||
boolean outofcoop;
|
||||
INT16 bot;
|
||||
|
@ -2425,6 +2432,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
ctfteam = players[player].ctfteam;
|
||||
exiting = players[player].exiting;
|
||||
jointime = players[player].jointime;
|
||||
quittime = players[player].quittime;
|
||||
spectator = players[player].spectator;
|
||||
outofcoop = players[player].outofcoop;
|
||||
pflags = (players[player].pflags & (PF_FLIPCAM|PF_ANALOGMODE|PF_DIRECTIONCHAR|PF_AUTOBRAKE|PF_TAGIT|PF_GAMETYPEOVER));
|
||||
|
@ -2496,6 +2504,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
p->pflags = pflags;
|
||||
p->ctfteam = ctfteam;
|
||||
p->jointime = jointime;
|
||||
p->quittime = quittime;
|
||||
p->spectator = spectator;
|
||||
p->outofcoop = outofcoop;
|
||||
|
||||
|
@ -2649,73 +2658,24 @@ static boolean G_CheckSpot(INT32 playernum, mapthing_t *mthing)
|
|||
// or a not-so-appropriate spot, if it initially fails
|
||||
// due to a lack of starts open or something.
|
||||
//
|
||||
void G_SpawnPlayer(INT32 playernum, boolean starpost)
|
||||
void G_SpawnPlayer(INT32 playernum)
|
||||
{
|
||||
mapthing_t *spawnpoint;
|
||||
|
||||
if (!playeringame[playernum])
|
||||
return;
|
||||
|
||||
P_SpawnPlayer(playernum);
|
||||
|
||||
if (starpost) //Don't even bother with looking for a place to spawn.
|
||||
{
|
||||
P_MovePlayerToStarpost(playernum);
|
||||
#ifdef HAVE_BLUA
|
||||
LUAh_PlayerSpawn(&players[playernum]); // Lua hook for player spawning :)
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// -- CTF --
|
||||
// Order: CTF->DM->Coop
|
||||
if ((gametyperules & (GTR_TEAMFLAGS|GTR_TEAMS)) && players[playernum].ctfteam)
|
||||
{
|
||||
if (!(spawnpoint = G_FindCTFStart(playernum)) // find a CTF start
|
||||
&& !(spawnpoint = G_FindMatchStart(playernum))) // find a DM start
|
||||
spawnpoint = G_FindCoopStart(playernum); // fallback
|
||||
}
|
||||
|
||||
// -- DM/Tag/CTF-spectator/etc --
|
||||
// Order: DM->CTF->Coop
|
||||
else if ((gametyperules & GTR_DEATHMATCHSTARTS) && !(players[playernum].pflags & PF_TAGIT))
|
||||
{
|
||||
if (!(spawnpoint = G_FindMatchStart(playernum)) // find a DM start
|
||||
&& !(spawnpoint = G_FindCTFStart(playernum))) // find a CTF start
|
||||
spawnpoint = G_FindCoopStart(playernum); // fallback
|
||||
}
|
||||
|
||||
// -- Other game modes --
|
||||
// Order: Coop->DM->CTF
|
||||
else
|
||||
{
|
||||
if (!(spawnpoint = G_FindCoopStart(playernum)) // find a Co-op start
|
||||
&& !(spawnpoint = G_FindMatchStart(playernum))) // find a DM start
|
||||
spawnpoint = G_FindCTFStart(playernum); // fallback
|
||||
}
|
||||
|
||||
//No spawns found. ANYWHERE.
|
||||
if (!spawnpoint)
|
||||
{
|
||||
if (nummapthings)
|
||||
{
|
||||
if (playernum == consoleplayer || (splitscreen && playernum == secondarydisplayplayer))
|
||||
CONS_Alert(CONS_ERROR, M_GetText("No player spawns found, spawning at the first mapthing!\n"));
|
||||
spawnpoint = &mapthings[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (playernum == consoleplayer || (splitscreen && playernum == secondarydisplayplayer))
|
||||
CONS_Alert(CONS_ERROR, M_GetText("No player spawns found, spawning at the origin!\n"));
|
||||
//P_MovePlayerToSpawn handles this fine if the spawnpoint is NULL.
|
||||
}
|
||||
}
|
||||
P_MovePlayerToSpawn(playernum, spawnpoint);
|
||||
|
||||
G_MovePlayerToSpawnOrStarpost(playernum);
|
||||
#ifdef HAVE_BLUA
|
||||
LUAh_PlayerSpawn(&players[playernum]); // Lua hook for player spawning :)
|
||||
#endif
|
||||
}
|
||||
|
||||
void G_MovePlayerToSpawnOrStarpost(INT32 playernum)
|
||||
{
|
||||
if (players[playernum].starposttime)
|
||||
P_MovePlayerToStarpost(playernum);
|
||||
else
|
||||
P_MovePlayerToSpawn(playernum, G_FindMapStart(playernum));
|
||||
}
|
||||
|
||||
mapthing_t *G_FindCTFStart(INT32 playernum)
|
||||
|
@ -2812,6 +2772,59 @@ mapthing_t *G_FindCoopStart(INT32 playernum)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
mapthing_t *G_FindMapStart(INT32 playernum)
|
||||
{
|
||||
mapthing_t *spawnpoint;
|
||||
|
||||
if (!playeringame[playernum])
|
||||
return NULL;
|
||||
|
||||
// -- CTF --
|
||||
// Order: CTF->DM->Coop
|
||||
if ((gametyperules & (GTR_TEAMFLAGS|GTR_TEAMS)) && players[playernum].ctfteam)
|
||||
{
|
||||
if (!(spawnpoint = G_FindCTFStart(playernum)) // find a CTF start
|
||||
&& !(spawnpoint = G_FindMatchStart(playernum))) // find a DM start
|
||||
spawnpoint = G_FindCoopStart(playernum); // fallback
|
||||
}
|
||||
|
||||
// -- DM/Tag/CTF-spectator/etc --
|
||||
// Order: DM->CTF->Coop
|
||||
else if ((gametyperules & GTR_DEATHMATCHSTARTS) && !(players[playernum].pflags & PF_TAGIT))
|
||||
{
|
||||
if (!(spawnpoint = G_FindMatchStart(playernum)) // find a DM start
|
||||
&& !(spawnpoint = G_FindCTFStart(playernum))) // find a CTF start
|
||||
spawnpoint = G_FindCoopStart(playernum); // fallback
|
||||
}
|
||||
|
||||
// -- Other game modes --
|
||||
// Order: Coop->DM->CTF
|
||||
else
|
||||
{
|
||||
if (!(spawnpoint = G_FindCoopStart(playernum)) // find a Co-op start
|
||||
&& !(spawnpoint = G_FindMatchStart(playernum))) // find a DM start
|
||||
spawnpoint = G_FindCTFStart(playernum); // fallback
|
||||
}
|
||||
|
||||
//No spawns found. ANYWHERE.
|
||||
if (!spawnpoint)
|
||||
{
|
||||
if (nummapthings)
|
||||
{
|
||||
if (playernum == consoleplayer || (splitscreen && playernum == secondarydisplayplayer))
|
||||
CONS_Alert(CONS_ERROR, M_GetText("No player spawns found, spawning at the first mapthing!\n"));
|
||||
spawnpoint = &mapthings[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (playernum == consoleplayer || (splitscreen && playernum == secondarydisplayplayer))
|
||||
CONS_Alert(CONS_ERROR, M_GetText("No player spawns found, spawning at the origin!\n"));
|
||||
}
|
||||
}
|
||||
|
||||
return spawnpoint;
|
||||
}
|
||||
|
||||
// Go back through all the projectiles and remove all references to the old
|
||||
// player mobj, replacing them with the new one.
|
||||
void G_ChangePlayerReferences(mobj_t *oldmo, mobj_t *newmo)
|
||||
|
@ -2990,7 +3003,7 @@ void G_DoReborn(INT32 playernum)
|
|||
{
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
G_SpawnPlayer(i, (players[i].starposttime));
|
||||
G_SpawnPlayer(i);
|
||||
}
|
||||
|
||||
// restore time in netgame (see also p_setup.c)
|
||||
|
@ -3036,7 +3049,7 @@ void G_DoReborn(INT32 playernum)
|
|||
P_RemoveMobj(player->mo);
|
||||
}
|
||||
|
||||
G_SpawnPlayer(playernum, (player->starposttime));
|
||||
G_SpawnPlayer(playernum);
|
||||
if (oldmo)
|
||||
G_ChangePlayerReferences(oldmo, players[playernum].mo);
|
||||
}
|
||||
|
@ -3078,7 +3091,6 @@ void G_AddPlayer(INT32 playernum)
|
|||
}
|
||||
}
|
||||
|
||||
p->jointime = 0;
|
||||
p->playerstate = PST_REBORN;
|
||||
|
||||
p->height = mobjinfo[MT_PLAYER].height;
|
||||
|
@ -3101,6 +3113,8 @@ boolean G_EnoughPlayersFinished(void)
|
|||
{
|
||||
if (!playeringame[i] || players[i].spectator || players[i].bot)
|
||||
continue;
|
||||
if (players[i].quittime > 30 * TICRATE)
|
||||
continue;
|
||||
if (players[i].lives <= 0)
|
||||
continue;
|
||||
|
||||
|
@ -3189,17 +3203,17 @@ UINT32 gametypedefaultrules[NUMGAMETYPES] =
|
|||
GTR_RACE|GTR_SPAWNENEMIES|GTR_SPAWNINVUL|GTR_ALLOWEXIT,
|
||||
|
||||
// Match
|
||||
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_POWERSTONES|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD|GTR_DEATHPENALTY,
|
||||
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME|GTR_POWERSTONES|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD|GTR_DEATHPENALTY,
|
||||
// Team Match
|
||||
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD,
|
||||
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD,
|
||||
|
||||
// Tag
|
||||
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_STARTCOUNTDOWN|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY,
|
||||
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME|GTR_STARTCOUNTDOWN|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY,
|
||||
// Hide and Seek
|
||||
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_STARTCOUNTDOWN|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY,
|
||||
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME|GTR_STARTCOUNTDOWN|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY,
|
||||
|
||||
// CTF
|
||||
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_TEAMFLAGS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_POWERSTONES|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD,
|
||||
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_TEAMFLAGS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME|GTR_POWERSTONES|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD,
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -3242,8 +3256,8 @@ void G_AddGametypeConstant(INT16 gtype, const char *newgtconst)
|
|||
{
|
||||
size_t r = 0; // read
|
||||
size_t w = 0; // write
|
||||
char *gtconst = Z_Calloc(strlen(newgtconst) + 3, PU_STATIC, NULL);
|
||||
char *tmpconst = Z_Calloc(strlen(newgtconst), PU_STATIC, NULL);
|
||||
char *gtconst = Z_Calloc(strlen(newgtconst) + 4, PU_STATIC, NULL);
|
||||
char *tmpconst = Z_Calloc(strlen(newgtconst) + 1, PU_STATIC, NULL);
|
||||
|
||||
// Copy the gametype name.
|
||||
strcpy(tmpconst, newgtconst);
|
||||
|
@ -3370,6 +3384,36 @@ UINT32 gametypetol[NUMGAMETYPES] =
|
|||
TOL_CTF, // CTF
|
||||
};
|
||||
|
||||
tolinfo_t TYPEOFLEVEL[NUMTOLNAMES] = {
|
||||
{"SOLO",TOL_SP},
|
||||
{"SP",TOL_SP},
|
||||
{"SINGLEPLAYER",TOL_SP},
|
||||
{"SINGLE",TOL_SP},
|
||||
|
||||
{"COOP",TOL_COOP},
|
||||
{"CO-OP",TOL_COOP},
|
||||
|
||||
{"COMPETITION",TOL_COMPETITION},
|
||||
{"RACE",TOL_RACE},
|
||||
|
||||
{"MATCH",TOL_MATCH},
|
||||
{"TAG",TOL_TAG},
|
||||
{"CTF",TOL_CTF},
|
||||
|
||||
{"2D",TOL_2D},
|
||||
{"MARIO",TOL_MARIO},
|
||||
{"NIGHTS",TOL_NIGHTS},
|
||||
{"OLDBRAK",TOL_ERZ3},
|
||||
|
||||
{"XMAS",TOL_XMAS},
|
||||
{"CHRISTMAS",TOL_XMAS},
|
||||
{"WINTER",TOL_XMAS},
|
||||
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
UINT32 lastcustomtol = (TOL_XMAS<<1);
|
||||
|
||||
//
|
||||
// G_AddTOL
|
||||
//
|
||||
|
@ -3377,16 +3421,16 @@ UINT32 gametypetol[NUMGAMETYPES] =
|
|||
//
|
||||
void G_AddTOL(UINT32 newtol, const char *tolname)
|
||||
{
|
||||
TYPEOFLEVEL[numtolinfo].name = Z_StrDup(tolname);
|
||||
TYPEOFLEVEL[numtolinfo].flag = newtol;
|
||||
numtolinfo++;
|
||||
INT32 i;
|
||||
for (i = 0; TYPEOFLEVEL[i].name; i++)
|
||||
;
|
||||
|
||||
TYPEOFLEVEL[numtolinfo].name = NULL;
|
||||
TYPEOFLEVEL[numtolinfo].flag = 0;
|
||||
TYPEOFLEVEL[i].name = Z_StrDup(tolname);
|
||||
TYPEOFLEVEL[i].flag = newtol;
|
||||
}
|
||||
|
||||
//
|
||||
// G_AddTOL
|
||||
// G_AddGametypeTOL
|
||||
//
|
||||
// Assigns a type of level to a gametype.
|
||||
//
|
||||
|
@ -3725,7 +3769,10 @@ static void G_DoCompleted(void)
|
|||
}
|
||||
|
||||
if (i == 7)
|
||||
{
|
||||
gottoken = false;
|
||||
token = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (spec && !gottoken)
|
||||
|
@ -4761,6 +4808,9 @@ INT32 G_FindMap(const char *mapname, char **foundmapnamep,
|
|||
measurekeywords(&freq[freqc],
|
||||
&freq[freqc].matchd, &freq[freqc].matchc,
|
||||
realmapname, mapname, wanttable);
|
||||
measurekeywords(&freq[freqc],
|
||||
&freq[freqc].keywhd, &freq[freqc].keywhc,
|
||||
mapheaderinfo[i]->keywords, mapname, wanttable);
|
||||
if (freq[freqc].total)
|
||||
freqc++;
|
||||
}
|
||||
|
|
|
@ -161,7 +161,9 @@ INT32 G_FindMapByNameOrCode(const char *query, char **foundmapnamep);
|
|||
mapthing_t *G_FindCTFStart(INT32 playernum);
|
||||
mapthing_t *G_FindMatchStart(INT32 playernum);
|
||||
mapthing_t *G_FindCoopStart(INT32 playernum);
|
||||
void G_SpawnPlayer(INT32 playernum, boolean starpost);
|
||||
mapthing_t *G_FindMapStart(INT32 playernum);
|
||||
void G_MovePlayerToSpawnOrStarpost(INT32 playernum);
|
||||
void G_SpawnPlayer(INT32 playernum);
|
||||
|
||||
// Can be called by the startup code or M_Responder.
|
||||
// A normal game starts at map 1, but a warp test can start elsewhere
|
||||
|
|
|
@ -662,7 +662,13 @@ INT32 G_KeyStringtoNum(const char *keystr)
|
|||
return keystr[0];
|
||||
|
||||
if (!strncmp(keystr, "KEY", 3) && keystr[3] >= '0' && keystr[3] <= '9')
|
||||
return atoi(&keystr[3]);
|
||||
{
|
||||
/* what if we out of range bruh? */
|
||||
j = atoi(&keystr[3]);
|
||||
if (j < NUMINPUTS)
|
||||
return j;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (j = 0; j < NUMKEYNAMES; j++)
|
||||
if (!stricmp(keynames[j].name, keystr))
|
||||
|
|
|
@ -72,6 +72,7 @@
|
|||
#include "../v_video.h"
|
||||
#include "hw_clip.h"
|
||||
#include "hw_glob.h"
|
||||
#include "../r_main.h"
|
||||
#include "../r_state.h"
|
||||
#include "../tables.h"
|
||||
#include "r_opengl/r_opengl.h"
|
||||
|
@ -328,7 +329,7 @@ angle_t gld_FrustumAngle(void)
|
|||
|
||||
// NEWCLIP TODO: SRB2CBTODO: make a global render_fov for this function
|
||||
|
||||
float render_fov = FIXED_TO_FLOAT(cv_grfov.value);
|
||||
float render_fov = FIXED_TO_FLOAT(cv_fov.value);
|
||||
float render_fovratio = (float)BASEVIDWIDTH / (float)BASEVIDHEIGHT; // SRB2CBTODO: NEWCLIPTODO: Is this right?
|
||||
float render_multiplier = 64.0f / render_fovratio / RMUL;
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "../i_system.h"
|
||||
#include "../m_cheat.h"
|
||||
#include "../f_finale.h"
|
||||
#include "../r_things.h" // R_GetShadowZ
|
||||
#ifdef ESLOPE
|
||||
#include "../p_slopes.h"
|
||||
#endif
|
||||
|
@ -4050,39 +4051,6 @@ static gr_vissprite_t *HWR_NewVisSprite(void)
|
|||
return HWR_GetVisSprite(gr_visspritecount++);
|
||||
}
|
||||
|
||||
#ifdef GLBADSHADOWS
|
||||
// Finds a floor through which light does not pass.
|
||||
static fixed_t HWR_OpaqueFloorAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
|
||||
{
|
||||
const sector_t *sec = R_PointInSubsector(x, y)->sector;
|
||||
fixed_t floorz = sec->floorheight;
|
||||
|
||||
if (sec->ffloors)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
fixed_t delta1, delta2;
|
||||
const fixed_t thingtop = z + height;
|
||||
|
||||
for (rover = sec->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (!(rover->flags & FF_EXISTS)
|
||||
|| !(rover->flags & FF_RENDERPLANES)
|
||||
|| rover->flags & FF_TRANSLUCENT
|
||||
|| rover->flags & FF_FOG
|
||||
|| rover->flags & FF_INVERTPLANES)
|
||||
continue;
|
||||
|
||||
delta1 = z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2));
|
||||
delta2 = thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2));
|
||||
if (*rover->topheight > floorz && abs(delta1) < abs(delta2))
|
||||
floorz = *rover->topheight;
|
||||
}
|
||||
}
|
||||
|
||||
return floorz;
|
||||
}
|
||||
#endif //#ifdef GLBADSHADOWS
|
||||
|
||||
//
|
||||
// HWR_DoCulling
|
||||
// Hardware version of R_DoCulling
|
||||
|
@ -4123,180 +4091,123 @@ static boolean HWR_DoCulling(line_t *cullheight, line_t *viewcullheight, float v
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifdef GLBADSHADOWS
|
||||
static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float this_scale)
|
||||
static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale)
|
||||
{
|
||||
FOutVector swallVerts[4];
|
||||
GLPatch_t *gpatch;
|
||||
FOutVector shadowVerts[4];
|
||||
FSurfaceInfo sSurf;
|
||||
fixed_t floorheight, mobjfloor;
|
||||
float offset = 0;
|
||||
float fscale; float fx; float fy; float offset;
|
||||
UINT8 lightlevel = 255;
|
||||
extracolormap_t *colormap = NULL;
|
||||
UINT8 i;
|
||||
|
||||
mobjfloor = HWR_OpaqueFloorAtPos(
|
||||
spr->mobj->x, spr->mobj->y,
|
||||
spr->mobj->z, spr->mobj->height);
|
||||
if (cv_shadowoffs.value)
|
||||
{
|
||||
angle_t shadowdir;
|
||||
INT32 light;
|
||||
fixed_t scalemul;
|
||||
UINT16 alpha;
|
||||
fixed_t floordiff;
|
||||
fixed_t floorz;
|
||||
fixed_t slopez;
|
||||
pslope_t *floorslope;
|
||||
|
||||
// Set direction
|
||||
if (splitscreen && stplyr == &players[secondarydisplayplayer])
|
||||
shadowdir = localangle2 + FixedAngle(cv_cam2_rotate.value);
|
||||
else
|
||||
shadowdir = localangle + FixedAngle(cv_cam_rotate.value);
|
||||
floorz = R_GetShadowZ(thing, &floorslope);
|
||||
|
||||
// Find floorheight
|
||||
floorheight = HWR_OpaqueFloorAtPos(
|
||||
spr->mobj->x + P_ReturnThrustX(spr->mobj, shadowdir, spr->mobj->z - mobjfloor),
|
||||
spr->mobj->y + P_ReturnThrustY(spr->mobj, shadowdir, spr->mobj->z - mobjfloor),
|
||||
spr->mobj->z, spr->mobj->height);
|
||||
//if (abs(floorz - gr_viewz) / tz > 4) return; // Prevent stretchy shadows and possible crashes
|
||||
|
||||
// The shadow is falling ABOVE it's mobj?
|
||||
// Don't draw it, then!
|
||||
if (spr->mobj->z < floorheight)
|
||||
return;
|
||||
else
|
||||
{
|
||||
fixed_t floorz;
|
||||
floorz = HWR_OpaqueFloorAtPos(
|
||||
spr->mobj->x + P_ReturnThrustX(spr->mobj, shadowdir, spr->mobj->z - floorheight),
|
||||
spr->mobj->y + P_ReturnThrustY(spr->mobj, shadowdir, spr->mobj->z - floorheight),
|
||||
spr->mobj->z, spr->mobj->height);
|
||||
// The shadow would be falling on a wall? Don't draw it, then.
|
||||
// Would draw midair otherwise.
|
||||
if (floorz < floorheight)
|
||||
return;
|
||||
}
|
||||
floordiff = abs(thing->z - floorz);
|
||||
|
||||
floorheight = FixedInt(spr->mobj->z - floorheight);
|
||||
alpha = floordiff / (4*FRACUNIT) + 75;
|
||||
if (alpha >= 255) return;
|
||||
alpha = 255 - alpha;
|
||||
|
||||
offset = floorheight;
|
||||
}
|
||||
else
|
||||
floorheight = FixedInt(spr->mobj->z - mobjfloor);
|
||||
gpatch = (GLPatch_t *)W_CachePatchName("DSHADOW", PU_CACHE);
|
||||
if (!(gpatch && gpatch->mipmap->grInfo.format)) return;
|
||||
HWR_GetPatch(gpatch);
|
||||
|
||||
scalemul = FixedMul(FRACUNIT - floordiff/640, scale);
|
||||
scalemul = FixedMul(scalemul, (thing->radius*2) / gpatch->height);
|
||||
|
||||
fscale = FIXED_TO_FLOAT(scalemul);
|
||||
fx = FIXED_TO_FLOAT(thing->x);
|
||||
fy = FIXED_TO_FLOAT(thing->y);
|
||||
|
||||
// create the sprite billboard
|
||||
//
|
||||
// 3--2
|
||||
// | /|
|
||||
// |/ |
|
||||
// 0--1
|
||||
|
||||
// x1/x2 were already scaled in HWR_ProjectSprite
|
||||
// First match the normal sprite
|
||||
swallVerts[0].x = swallVerts[3].x = spr->x1;
|
||||
swallVerts[2].x = swallVerts[1].x = spr->x2;
|
||||
swallVerts[0].z = swallVerts[3].z = spr->z1;
|
||||
swallVerts[2].z = swallVerts[1].z = spr->z2;
|
||||
if (thing && fabsf(fscale - 1.0f) > 1.0E-36f)
|
||||
offset = (gpatch->height/2) * fscale;
|
||||
else
|
||||
offset = (float)(gpatch->height/2);
|
||||
|
||||
if (spr->mobj && fabsf(this_scale - 1.0f) > 1.0E-36f)
|
||||
shadowVerts[0].x = shadowVerts[3].x = fx - offset;
|
||||
shadowVerts[2].x = shadowVerts[1].x = fx + offset;
|
||||
shadowVerts[0].z = shadowVerts[1].z = fy - offset;
|
||||
shadowVerts[3].z = shadowVerts[2].z = fy + offset;
|
||||
|
||||
if (floorslope)
|
||||
{
|
||||
// Always a pixel above the floor, perfectly flat.
|
||||
swallVerts[0].y = swallVerts[1].y = swallVerts[2].y = swallVerts[3].y = spr->ty - gpatch->topoffset * this_scale - (floorheight+3);
|
||||
|
||||
// Now transform the TOP vertices along the floor in the direction of the camera
|
||||
swallVerts[3].x = spr->x1 + ((gpatch->height * this_scale) + offset) * gr_viewcos;
|
||||
swallVerts[2].x = spr->x2 + ((gpatch->height * this_scale) + offset) * gr_viewcos;
|
||||
swallVerts[3].z = spr->z1 + ((gpatch->height * this_scale) + offset) * gr_viewsin;
|
||||
swallVerts[2].z = spr->z2 + ((gpatch->height * this_scale) + offset) * gr_viewsin;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
slopez = P_GetZAt(floorslope, FLOAT_TO_FIXED(shadowVerts[i].x), FLOAT_TO_FIXED(shadowVerts[i].z));
|
||||
shadowVerts[i].y = FIXED_TO_FLOAT(slopez) + 0.05f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Always a pixel above the floor, perfectly flat.
|
||||
swallVerts[0].y = swallVerts[1].y = swallVerts[2].y = swallVerts[3].y = spr->ty - gpatch->topoffset - (floorheight+3);
|
||||
|
||||
// Now transform the TOP vertices along the floor in the direction of the camera
|
||||
swallVerts[3].x = spr->x1 + (gpatch->height + offset) * gr_viewcos;
|
||||
swallVerts[2].x = spr->x2 + (gpatch->height + offset) * gr_viewcos;
|
||||
swallVerts[3].z = spr->z1 + (gpatch->height + offset) * gr_viewsin;
|
||||
swallVerts[2].z = spr->z2 + (gpatch->height + offset) * gr_viewsin;
|
||||
}
|
||||
|
||||
// We also need to move the bottom ones away when shadowoffs is on
|
||||
if (cv_shadowoffs.value)
|
||||
{
|
||||
swallVerts[0].x = spr->x1 + offset * gr_viewcos;
|
||||
swallVerts[1].x = spr->x2 + offset * gr_viewcos;
|
||||
swallVerts[0].z = spr->z1 + offset * gr_viewsin;
|
||||
swallVerts[1].z = spr->z2 + offset * gr_viewsin;
|
||||
for (i = 0; i < 4; i++)
|
||||
shadowVerts[i].y = FIXED_TO_FLOAT(floorz) + 0.05f;
|
||||
}
|
||||
|
||||
if (spr->flip)
|
||||
{
|
||||
swallVerts[0].sow = swallVerts[3].sow = gpatch->max_s;
|
||||
swallVerts[2].sow = swallVerts[1].sow = 0;
|
||||
shadowVerts[0].sow = shadowVerts[3].sow = gpatch->max_s;
|
||||
shadowVerts[2].sow = shadowVerts[1].sow = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
swallVerts[0].sow = swallVerts[3].sow = 0;
|
||||
swallVerts[2].sow = swallVerts[1].sow = gpatch->max_s;
|
||||
shadowVerts[0].sow = shadowVerts[3].sow = 0;
|
||||
shadowVerts[2].sow = shadowVerts[1].sow = gpatch->max_s;
|
||||
}
|
||||
|
||||
// flip the texture coords (look familiar?)
|
||||
if (spr->vflip)
|
||||
{
|
||||
swallVerts[3].tow = swallVerts[2].tow = gpatch->max_t;
|
||||
swallVerts[0].tow = swallVerts[1].tow = 0;
|
||||
shadowVerts[3].tow = shadowVerts[2].tow = gpatch->max_t;
|
||||
shadowVerts[0].tow = shadowVerts[1].tow = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
swallVerts[3].tow = swallVerts[2].tow = 0;
|
||||
swallVerts[0].tow = swallVerts[1].tow = gpatch->max_t;
|
||||
shadowVerts[3].tow = shadowVerts[2].tow = 0;
|
||||
shadowVerts[0].tow = shadowVerts[1].tow = gpatch->max_t;
|
||||
}
|
||||
|
||||
sSurf.FlatColor.s.red = 0x00;
|
||||
sSurf.FlatColor.s.blue = 0x00;
|
||||
sSurf.FlatColor.s.green = 0x00;
|
||||
|
||||
/*if (spr->mobj->frame & FF_TRANSMASK || spr->mobj->flags2 & MF2_SHADOW)
|
||||
if (thing->subsector->sector->numlights)
|
||||
{
|
||||
sector_t *sector = spr->mobj->subsector->sector;
|
||||
UINT8 lightlevel = 255;
|
||||
extracolormap_t *colormap = sector->extra_colormap;
|
||||
light = R_GetPlaneLight(thing->subsector->sector, floorz, false); // Always use the light at the top instead of whatever I was doing before
|
||||
|
||||
if (sector->numlights)
|
||||
{
|
||||
INT32 light = R_GetPlaneLight(sector, spr->mobj->floorz, false);
|
||||
lightlevel = *thing->subsector->sector->lightlist[light].lightlevel;
|
||||
|
||||
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
||||
lightlevel = *sector->lightlist[light].lightlevel;
|
||||
|
||||
if (*sector->lightlist[light].extra_colormap)
|
||||
colormap = *sector->lightlist[light].extra_colormap;
|
||||
}
|
||||
else
|
||||
{
|
||||
lightlevel = sector->lightlevel;
|
||||
|
||||
if (sector->extra_colormap)
|
||||
colormap = sector->extra_colormap;
|
||||
}
|
||||
|
||||
if (colormap)
|
||||
sSurf.FlatColor.rgba = HWR_Lighting(lightlevel/2, colormap->rgba, colormap->fadergba, false, true);
|
||||
else
|
||||
sSurf.FlatColor.rgba = HWR_Lighting(lightlevel/2, NORMALFOG, FADEFOG, false, true);
|
||||
}*/
|
||||
|
||||
// shadow is always half as translucent as the sprite itself
|
||||
if (!cv_translucency.value) // use default translucency (main sprite won't have any translucency)
|
||||
sSurf.FlatColor.s.alpha = 0x80; // default
|
||||
else if (spr->mobj->flags2 & MF2_SHADOW)
|
||||
sSurf.FlatColor.s.alpha = 0x20;
|
||||
else if (spr->mobj->frame & FF_TRANSMASK)
|
||||
{
|
||||
HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &sSurf);
|
||||
sSurf.FlatColor.s.alpha /= 2; //cut alpha in half!
|
||||
if (*thing->subsector->sector->lightlist[light].extra_colormap)
|
||||
colormap = *thing->subsector->sector->lightlist[light].extra_colormap;
|
||||
}
|
||||
else
|
||||
sSurf.FlatColor.s.alpha = 0x80; // default
|
||||
|
||||
if (sSurf.FlatColor.s.alpha > floorheight/4)
|
||||
{
|
||||
sSurf.FlatColor.s.alpha = (UINT8)(sSurf.FlatColor.s.alpha - floorheight/4);
|
||||
HWD.pfnDrawPolygon(&sSurf, swallVerts, 4, PF_Translucent|PF_Modulated|PF_Clip);
|
||||
lightlevel = thing->subsector->sector->lightlevel;
|
||||
|
||||
if (thing->subsector->sector->extra_colormap)
|
||||
colormap = thing->subsector->sector->extra_colormap;
|
||||
}
|
||||
|
||||
if (colormap)
|
||||
sSurf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false);
|
||||
else
|
||||
sSurf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false);
|
||||
|
||||
sSurf.FlatColor.s.alpha = alpha;
|
||||
|
||||
HWD.pfnDrawPolygon(&sSurf, shadowVerts, 4, PF_Translucent|PF_Modulated|PF_Clip);
|
||||
}
|
||||
#endif //#ifdef GLBADSHADOWS
|
||||
|
||||
// This is expecting a pointer to an array containing 4 wallVerts for a sprite
|
||||
static void HWR_RotateSpritePolyToAim(gr_vissprite_t *spr, FOutVector *wallVerts)
|
||||
|
@ -4372,24 +4283,6 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
|
|||
//Hurdler: 25/04/2000: now support colormap in hardware mode
|
||||
HWR_GetMappedPatch(gpatch, spr->colormap);
|
||||
|
||||
#ifdef GLBADSHADOWS
|
||||
// Draw shadow BEFORE sprite
|
||||
if (cv_shadow.value // Shadows enabled
|
||||
&& (spr->mobj->flags & (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY)) != (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY) // Ceiling scenery have no shadow.
|
||||
&& !(spr->mobj->flags2 & MF2_DEBRIS) // Debris have no corona or shadow.
|
||||
#ifdef ALAM_LIGHTING
|
||||
&& !(t_lspr[spr->mobj->sprite]->type // Things with dynamic lights have no shadow.
|
||||
&& (!spr->mobj->player || spr->mobj->player->powers[pw_super])) // Except for non-super players.
|
||||
#endif
|
||||
&& (spr->mobj->z >= spr->mobj->floorz)) // Without this, your shadow shows on the floor, even after you die and fall through the ground.
|
||||
{
|
||||
////////////////////
|
||||
// SHADOW SPRITE! //
|
||||
////////////////////
|
||||
HWR_DrawSpriteShadow(spr, gpatch, this_scale);
|
||||
}
|
||||
#endif //#ifdef GLBADSHADOWS
|
||||
|
||||
baseWallVerts[0].x = baseWallVerts[3].x = spr->x1;
|
||||
baseWallVerts[2].x = baseWallVerts[1].x = spr->x2;
|
||||
baseWallVerts[0].z = baseWallVerts[3].z = spr->z1;
|
||||
|
@ -4776,24 +4669,6 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
|
|||
//Hurdler: 25/04/2000: now support colormap in hardware mode
|
||||
HWR_GetMappedPatch(gpatch, spr->colormap);
|
||||
|
||||
#ifdef GLBADSHADOWS
|
||||
// Draw shadow BEFORE sprite
|
||||
if (cv_shadow.value // Shadows enabled
|
||||
&& (spr->mobj->flags & (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY)) != (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY) // Ceiling scenery have no shadow.
|
||||
&& !(spr->mobj->flags2 & MF2_DEBRIS) // Debris have no corona or shadow.
|
||||
#ifdef ALAM_LIGHTING
|
||||
&& !(t_lspr[spr->mobj->sprite]->type // Things with dynamic lights have no shadow.
|
||||
&& (!spr->mobj->player || spr->mobj->player->powers[pw_super])) // Except for non-super players.
|
||||
#endif
|
||||
&& (spr->mobj->z >= spr->mobj->floorz)) // Without this, your shadow shows on the floor, even after you die and fall through the ground.
|
||||
{
|
||||
////////////////////
|
||||
// SHADOW SPRITE! //
|
||||
////////////////////
|
||||
HWR_DrawSpriteShadow(spr, gpatch, this_scale);
|
||||
}
|
||||
#endif //#ifdef GLBADSHADOWS
|
||||
|
||||
// if it has a dispoffset, push it a little towards the camera
|
||||
if (spr->dispoffset) {
|
||||
float co = -gr_viewcos*(0.05f*spr->dispoffset);
|
||||
|
@ -5147,12 +5022,7 @@ void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boo
|
|||
|
||||
planeinfo[numplanes].isceiling = isceiling;
|
||||
planeinfo[numplanes].fixedheight = fixedheight;
|
||||
|
||||
if (planecolormap && (planecolormap->fog & 1))
|
||||
planeinfo[numplanes].lightlevel = lightlevel;
|
||||
else
|
||||
planeinfo[numplanes].lightlevel = 255;
|
||||
|
||||
planeinfo[numplanes].lightlevel = (planecolormap && (planecolormap->flags & CMF_FOG)) ? lightlevel : 255;
|
||||
planeinfo[numplanes].levelflat = levelflat;
|
||||
planeinfo[numplanes].xsub = xsub;
|
||||
planeinfo[numplanes].alpha = alpha;
|
||||
|
@ -5184,12 +5054,7 @@ void HWR_AddTransparentPolyobjectFloor(levelflat_t *levelflat, polyobj_t *polyse
|
|||
|
||||
polyplaneinfo[numpolyplanes].isceiling = isceiling;
|
||||
polyplaneinfo[numpolyplanes].fixedheight = fixedheight;
|
||||
|
||||
if (planecolormap && (planecolormap->fog & 1))
|
||||
polyplaneinfo[numpolyplanes].lightlevel = lightlevel;
|
||||
else
|
||||
polyplaneinfo[numpolyplanes].lightlevel = 255;
|
||||
|
||||
polyplaneinfo[numpolyplanes].lightlevel = (planecolormap && (planecolormap->flags & CMF_FOG)) ? lightlevel : 255;
|
||||
polyplaneinfo[numpolyplanes].levelflat = levelflat;
|
||||
polyplaneinfo[numpolyplanes].polysector = polysector;
|
||||
polyplaneinfo[numpolyplanes].alpha = alpha;
|
||||
|
@ -5407,6 +5272,12 @@ static void HWR_DrawSprites(void)
|
|||
HWR_DrawPrecipitationSprite(spr);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (spr->mobj && spr->mobj->shadowscale && cv_shadow.value)
|
||||
{
|
||||
HWR_DrawDropShadow(spr->mobj, spr, spr->mobj->shadowscale);
|
||||
}
|
||||
|
||||
if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
|
||||
{
|
||||
if (!cv_grmodels.value || md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f)
|
||||
|
@ -5427,6 +5298,7 @@ static void HWR_DrawSprites(void)
|
|||
HWR_DrawSprite(spr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5443,7 +5315,7 @@ static void HWR_AddSprites(sector_t *sec)
|
|||
#ifdef HWPRECIP
|
||||
precipmobj_t *precipthing;
|
||||
#endif
|
||||
fixed_t approx_dist, limit_dist, hoop_limit_dist;
|
||||
fixed_t limit_dist, hoop_limit_dist;
|
||||
|
||||
// BSP is traversed by subsector.
|
||||
// A sector might have been split into several
|
||||
|
@ -5462,35 +5334,10 @@ static void HWR_AddSprites(sector_t *sec)
|
|||
// If a limit exists, handle things a tiny bit different.
|
||||
limit_dist = (fixed_t)(cv_drawdist.value) << FRACBITS;
|
||||
hoop_limit_dist = (fixed_t)(cv_drawdist_nights.value) << FRACBITS;
|
||||
if (limit_dist || hoop_limit_dist)
|
||||
for (thing = sec->thinglist; thing; thing = thing->snext)
|
||||
{
|
||||
for (thing = sec->thinglist; thing; thing = thing->snext)
|
||||
{
|
||||
if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW)
|
||||
continue;
|
||||
|
||||
approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
|
||||
|
||||
if (thing->sprite == SPR_HOOP)
|
||||
{
|
||||
if (hoop_limit_dist && approx_dist > hoop_limit_dist)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (limit_dist && approx_dist > limit_dist)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (R_ThingVisibleWithinDist(thing, limit_dist, hoop_limit_dist))
|
||||
HWR_ProjectSprite(thing);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw everything in sector, no checks
|
||||
for (thing = sec->thinglist; thing; thing = thing->snext)
|
||||
if (!(thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW))
|
||||
HWR_ProjectSprite(thing);
|
||||
}
|
||||
|
||||
#ifdef HWPRECIP
|
||||
|
@ -5499,15 +5346,8 @@ static void HWR_AddSprites(sector_t *sec)
|
|||
{
|
||||
for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext)
|
||||
{
|
||||
if (precipthing->precipflags & PCF_INVISIBLE)
|
||||
continue;
|
||||
|
||||
approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y);
|
||||
|
||||
if (approx_dist > limit_dist)
|
||||
continue;
|
||||
|
||||
HWR_ProjectPrecipitationSprite(precipthing);
|
||||
if (R_PrecipThingVisible(precipthing, limit_dist))
|
||||
HWR_ProjectPrecipitationSprite(precipthing);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -5530,6 +5370,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
spritedef_t *sprdef;
|
||||
spriteframe_t *sprframe;
|
||||
spriteinfo_t *sprinfo;
|
||||
md2_t *md2;
|
||||
size_t lumpoff;
|
||||
unsigned rot;
|
||||
UINT16 flip;
|
||||
|
@ -5561,8 +5402,21 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
tz = (tr_x * gr_viewcos) + (tr_y * gr_viewsin);
|
||||
|
||||
// thing is behind view plane?
|
||||
if (tz < ZCLIP_PLANE && !papersprite && (!cv_grmodels.value || md2_models[thing->sprite].notfound == true)) //Yellow: Only MD2's dont disappear
|
||||
return;
|
||||
if (tz < ZCLIP_PLANE && !papersprite)
|
||||
{
|
||||
if (cv_grmodels.value) //Yellow: Only MD2's dont disappear
|
||||
{
|
||||
if (thing->skin && thing->sprite == SPR_PLAY)
|
||||
md2 = &md2_playermodels[( (skin_t *)thing->skin - skins )];
|
||||
else
|
||||
md2 = &md2_models[thing->sprite];
|
||||
|
||||
if (md2->notfound || md2->scale < 0.0f)
|
||||
return;
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
// The above can stay as it works for cutting sprites that are too close
|
||||
tr_x = FIXED_TO_FLOAT(thing->x);
|
||||
|
@ -5747,7 +5601,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer)
|
||||
{
|
||||
// bodge support - not nearly as comprehensive as r_things.c, but better than nothing
|
||||
if (thing->tracer->sprite == SPR_NULL || thing->tracer->flags2 & MF2_DONTDRAW)
|
||||
if (! R_ThingVisible(thing->tracer))
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -5930,7 +5784,7 @@ static void HWR_DrawSkyBackground(player_t *player)
|
|||
if (cv_grskydome.value)
|
||||
{
|
||||
FTransform dometransform;
|
||||
const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd);
|
||||
const float fpov = FIXED_TO_FLOAT(cv_fov.value+player->fovadd);
|
||||
postimg_t *type;
|
||||
|
||||
if (splitscreen && player == &players[secondarydisplayplayer])
|
||||
|
@ -5955,6 +5809,12 @@ static void HWR_DrawSkyBackground(player_t *player)
|
|||
dometransform.scalez = 1;
|
||||
dometransform.fovxangle = fpov; // Tails
|
||||
dometransform.fovyangle = fpov; // Tails
|
||||
if (player->viewrollangle != 0)
|
||||
{
|
||||
fixed_t rol = AngleFixed(player->viewrollangle);
|
||||
dometransform.rollangle = FIXED_TO_FLOAT(rol);
|
||||
dometransform.roll = true;
|
||||
}
|
||||
dometransform.splitscreen = splitscreen;
|
||||
|
||||
HWR_GetTexture(texturetranslation[skytexture]);
|
||||
|
@ -6108,7 +5968,7 @@ void HWR_SetViewSize(void)
|
|||
// ==========================================================================
|
||||
void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player)
|
||||
{
|
||||
const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd);
|
||||
const float fpov = FIXED_TO_FLOAT(cv_fov.value+player->fovadd);
|
||||
postimg_t *type;
|
||||
|
||||
if (splitscreen && player == &players[secondarydisplayplayer])
|
||||
|
@ -6178,6 +6038,12 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player)
|
|||
atransform.scalez = 1;
|
||||
atransform.fovxangle = fpov; // Tails
|
||||
atransform.fovyangle = fpov; // Tails
|
||||
if (player->viewrollangle != 0)
|
||||
{
|
||||
fixed_t rol = AngleFixed(player->viewrollangle);
|
||||
atransform.rollangle = FIXED_TO_FLOAT(rol);
|
||||
atransform.roll = true;
|
||||
}
|
||||
atransform.splitscreen = splitscreen;
|
||||
|
||||
gr_fovlud = (float)(1.0l/tan((double)(fpov*M_PIl/360l)));
|
||||
|
@ -6234,7 +6100,7 @@ if (0)
|
|||
viewangle = localaiming2;
|
||||
|
||||
// Handle stuff when you are looking farther up or down.
|
||||
if ((aimingangle || cv_grfov.value+player->fovadd > 90*FRACUNIT))
|
||||
if ((aimingangle || cv_fov.value+player->fovadd > 90*FRACUNIT))
|
||||
{
|
||||
dup_viewangle += ANGLE_90;
|
||||
HWR_ClearClipSegs();
|
||||
|
@ -6312,7 +6178,7 @@ if (0)
|
|||
// ==========================================================================
|
||||
void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
|
||||
{
|
||||
const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd);
|
||||
const float fpov = FIXED_TO_FLOAT(cv_fov.value+player->fovadd);
|
||||
postimg_t *type;
|
||||
|
||||
const boolean skybox = (skyboxmo[0] && cv_skybox.value); // True if there's a skybox object and skyboxes are on
|
||||
|
@ -6398,6 +6264,12 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
|
|||
atransform.scalez = 1;
|
||||
atransform.fovxangle = fpov; // Tails
|
||||
atransform.fovyangle = fpov; // Tails
|
||||
if (player->viewrollangle != 0)
|
||||
{
|
||||
fixed_t rol = AngleFixed(player->viewrollangle);
|
||||
atransform.rollangle = FIXED_TO_FLOAT(rol);
|
||||
atransform.roll = true;
|
||||
}
|
||||
atransform.splitscreen = splitscreen;
|
||||
|
||||
gr_fovlud = (float)(1.0l/tan((double)(fpov*M_PIl/360l)));
|
||||
|
@ -6454,7 +6326,7 @@ if (0)
|
|||
viewangle = localaiming2;
|
||||
|
||||
// Handle stuff when you are looking farther up or down.
|
||||
if ((aimingangle || cv_grfov.value+player->fovadd > 90*FRACUNIT))
|
||||
if ((aimingangle || cv_fov.value+player->fovadd > 90*FRACUNIT))
|
||||
{
|
||||
dup_viewangle += ANGLE_90;
|
||||
HWR_ClearClipSegs();
|
||||
|
@ -6583,9 +6455,7 @@ static void CV_grmodellighting_OnChange(void);
|
|||
static void CV_grfiltermode_OnChange(void);
|
||||
static void CV_granisotropic_OnChange(void);
|
||||
static void CV_grfogdensity_OnChange(void);
|
||||
static void CV_grfov_OnChange(void);
|
||||
|
||||
static CV_PossibleValue_t grfov_cons_t[] = {{0, "MIN"}, {179*FRACUNIT, "MAX"}, {0, NULL}};
|
||||
static CV_PossibleValue_t grfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSAMPLED, "Nearest"},
|
||||
{HWD_SET_TEXTUREFILTER_BILINEAR, "Bilinear"}, {HWD_SET_TEXTUREFILTER_TRILINEAR, "Trilinear"},
|
||||
{HWD_SET_TEXTUREFILTER_MIXED1, "Linear_Nearest"},
|
||||
|
@ -6594,7 +6464,7 @@ static CV_PossibleValue_t grfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSA
|
|||
{0, NULL}};
|
||||
CV_PossibleValue_t granisotropicmode_cons_t[] = {{1, "MIN"}, {16, "MAX"}, {0, NULL}};
|
||||
|
||||
consvar_t cv_grfovchange = {"gr_fovchange", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_fovchange = {"gr_fovchange", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_grfog = {"gr_fog", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_grfogcolor = {"gr_fogcolor", "AAAAAA", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_grsoftwarefog = {"gr_softwarefog", "Off", CV_SAVE, grsoftwarefog_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
@ -6615,7 +6485,6 @@ consvar_t cv_grskydome = {"gr_skydome", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL,
|
|||
consvar_t cv_grfakecontrast = {"gr_fakecontrast", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_grrounddown = {"gr_rounddown", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_grfov = {"gr_fov", "90", CV_FLOAT|CV_CALL, grfov_cons_t, CV_grfov_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_grfogdensity = {"gr_fogdensity", "150", CV_CALL|CV_NOINIT, CV_Unsigned,
|
||||
CV_grfogdensity_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
|
@ -6651,17 +6520,10 @@ static void CV_granisotropic_OnChange(void)
|
|||
HWD.pfnSetSpecialState(HWD_SET_TEXTUREANISOTROPICMODE, cv_granisotropicmode.value);
|
||||
}
|
||||
|
||||
static void CV_grfov_OnChange(void)
|
||||
{
|
||||
if ((netgame || multiplayer) && !cv_debug && cv_grfov.value != 90*FRACUNIT)
|
||||
CV_Set(&cv_grfov, cv_grfov.defaultvalue);
|
||||
}
|
||||
|
||||
//added by Hurdler: console varibale that are saved
|
||||
void HWR_AddCommands(void)
|
||||
{
|
||||
CV_RegisterVar(&cv_grfovchange);
|
||||
CV_RegisterVar(&cv_grfov);
|
||||
CV_RegisterVar(&cv_fovchange);
|
||||
|
||||
CV_RegisterVar(&cv_grfogdensity);
|
||||
CV_RegisterVar(&cv_grfogcolor);
|
||||
|
|
|
@ -84,7 +84,6 @@ extern consvar_t cv_grstaticlighting;
|
|||
extern consvar_t cv_grcoronas;
|
||||
extern consvar_t cv_grcoronasize;
|
||||
#endif
|
||||
extern consvar_t cv_grfov;
|
||||
extern consvar_t cv_grmodels;
|
||||
extern consvar_t cv_grmodelinterpolation;
|
||||
extern consvar_t cv_grmodellighting;
|
||||
|
@ -95,7 +94,7 @@ extern consvar_t cv_grsoftwarefog;
|
|||
extern consvar_t cv_grfiltermode;
|
||||
extern consvar_t cv_granisotropicmode;
|
||||
extern consvar_t cv_grcorrecttricks;
|
||||
extern consvar_t cv_grfovchange;
|
||||
extern consvar_t cv_fovchange;
|
||||
extern consvar_t cv_grsolvetjoin;
|
||||
extern consvar_t cv_grspritebillboarding;
|
||||
extern consvar_t cv_grskydome;
|
||||
|
|
|
@ -476,8 +476,9 @@ void HWR_InitModels(void)
|
|||
size_t i;
|
||||
INT32 s;
|
||||
FILE *f;
|
||||
char name[18], filename[32];
|
||||
char name[24], filename[32];
|
||||
float scale, offset;
|
||||
size_t prefixlen;
|
||||
|
||||
CONS_Printf("HWR_InitModels()...\n");
|
||||
for (s = 0; s < MAXSKINS; s++)
|
||||
|
@ -509,46 +510,54 @@ void HWR_InitModels(void)
|
|||
nomd2s = true;
|
||||
return;
|
||||
}
|
||||
while (fscanf(f, "%19s %31s %f %f", name, filename, &scale, &offset) == 4)
|
||||
|
||||
// length of the player model prefix
|
||||
prefixlen = strlen(PLAYERMODELPREFIX);
|
||||
|
||||
while (fscanf(f, "%25s %31s %f %f", name, filename, &scale, &offset) == 4)
|
||||
{
|
||||
if (stricmp(name, "PLAY") == 0)
|
||||
char *skinname = name;
|
||||
size_t len = strlen(name);
|
||||
|
||||
// check for the player model prefix.
|
||||
if (!strnicmp(name, PLAYERMODELPREFIX, prefixlen) && (len > prefixlen))
|
||||
{
|
||||
CONS_Printf("Model for sprite PLAY detected in models.dat, use a player skin instead!\n");
|
||||
continue;
|
||||
skinname += prefixlen;
|
||||
goto addskinmodel;
|
||||
}
|
||||
|
||||
for (i = 0; i < NUMSPRITES; i++)
|
||||
// add sprite model
|
||||
if (len == 4) // must be 4 characters long exactly. otherwise it's not a sprite name.
|
||||
{
|
||||
if (stricmp(name, sprnames[i]) == 0)
|
||||
for (i = 0; i < NUMSPRITES; i++)
|
||||
{
|
||||
//if (stricmp(name, "PLAY") == 0)
|
||||
//continue;
|
||||
|
||||
//CONS_Debug(DBG_RENDER, " Found: %s %s %f %f\n", name, filename, scale, offset);
|
||||
md2_models[i].scale = scale;
|
||||
md2_models[i].offset = offset;
|
||||
md2_models[i].notfound = false;
|
||||
strcpy(md2_models[i].filename, filename);
|
||||
goto md2found;
|
||||
if (stricmp(name, sprnames[i]) == 0)
|
||||
{
|
||||
md2_models[i].scale = scale;
|
||||
md2_models[i].offset = offset;
|
||||
md2_models[i].notfound = false;
|
||||
strcpy(md2_models[i].filename, filename);
|
||||
goto modelfound;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addskinmodel:
|
||||
// add player model
|
||||
for (s = 0; s < MAXSKINS; s++)
|
||||
{
|
||||
if (stricmp(name, skins[s].name) == 0)
|
||||
if (stricmp(skinname, skins[s].name) == 0)
|
||||
{
|
||||
//CONS_Printf(" Found: %s %s %f %f\n", name, filename, scale, offset);
|
||||
md2_playermodels[s].skin = s;
|
||||
md2_playermodels[s].scale = scale;
|
||||
md2_playermodels[s].offset = offset;
|
||||
md2_playermodels[s].notfound = false;
|
||||
strcpy(md2_playermodels[s].filename, filename);
|
||||
goto md2found;
|
||||
goto modelfound;
|
||||
}
|
||||
}
|
||||
// no sprite/player skin name found?!?
|
||||
//CONS_Printf("Unknown sprite/player skin %s detected in models.dat\n", name);
|
||||
md2found:
|
||||
|
||||
modelfound:
|
||||
// move on to next line...
|
||||
continue;
|
||||
}
|
||||
|
@ -558,8 +567,9 @@ md2found:
|
|||
void HWR_AddPlayerModel(int skin) // For skins that were added after startup
|
||||
{
|
||||
FILE *f;
|
||||
char name[18], filename[32];
|
||||
char name[24], filename[32];
|
||||
float scale, offset;
|
||||
size_t prefixlen;
|
||||
|
||||
if (nomd2s)
|
||||
return;
|
||||
|
@ -577,32 +587,42 @@ void HWR_AddPlayerModel(int skin) // For skins that were added after startup
|
|||
return;
|
||||
}
|
||||
|
||||
// Check for any model that match the names of player skins!
|
||||
while (fscanf(f, "%19s %31s %f %f", name, filename, &scale, &offset) == 4)
|
||||
// length of the player model prefix
|
||||
prefixlen = strlen(PLAYERMODELPREFIX);
|
||||
|
||||
// Check for any models that match the names of player skins!
|
||||
while (fscanf(f, "%25s %31s %f %f", name, filename, &scale, &offset) == 4)
|
||||
{
|
||||
if (stricmp(name, skins[skin].name) == 0)
|
||||
char *skinname = name;
|
||||
size_t len = strlen(name);
|
||||
|
||||
// ignore the player model prefix.
|
||||
if (!strnicmp(name, PLAYERMODELPREFIX, prefixlen) && (len > prefixlen))
|
||||
skinname += prefixlen;
|
||||
|
||||
if (stricmp(skinname, skins[skin].name) == 0)
|
||||
{
|
||||
md2_playermodels[skin].skin = skin;
|
||||
md2_playermodels[skin].scale = scale;
|
||||
md2_playermodels[skin].offset = offset;
|
||||
md2_playermodels[skin].notfound = false;
|
||||
strcpy(md2_playermodels[skin].filename, filename);
|
||||
goto playermd2found;
|
||||
goto playermodelfound;
|
||||
}
|
||||
}
|
||||
|
||||
//CONS_Printf("Model for player skin %s not found\n", skins[skin].name);
|
||||
md2_playermodels[skin].notfound = true;
|
||||
playermd2found:
|
||||
playermodelfound:
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void HWR_AddSpriteModel(size_t spritenum) // For sprites that were added after startup
|
||||
{
|
||||
FILE *f;
|
||||
// name[18] is used to check for names in the models.dat file that match with sprites or player skins
|
||||
// name[24] is used to check for names in the models.dat file that match with sprites or player skins
|
||||
// sprite names are always 4 characters long, and names is for player skins can be up to 19 characters long
|
||||
char name[18], filename[32];
|
||||
// PLAYERMODELPREFIX is 6 characters long
|
||||
char name[24], filename[32];
|
||||
float scale, offset;
|
||||
|
||||
if (nomd2s)
|
||||
|
@ -622,22 +642,30 @@ void HWR_AddSpriteModel(size_t spritenum) // For sprites that were added after s
|
|||
return;
|
||||
}
|
||||
|
||||
// Check for any MD2s that match the names of sprite names!
|
||||
while (fscanf(f, "%19s %31s %f %f", name, filename, &scale, &offset) == 4)
|
||||
// Check for any models that match the names of sprite names!
|
||||
while (fscanf(f, "%25s %31s %f %f", name, filename, &scale, &offset) == 4)
|
||||
{
|
||||
// length of the sprite name
|
||||
size_t len = strlen(name);
|
||||
if (len != 4) // must be 4 characters long exactly. otherwise it's not a sprite name.
|
||||
continue;
|
||||
|
||||
// check for the player model prefix.
|
||||
if (!strnicmp(name, PLAYERMODELPREFIX, strlen(PLAYERMODELPREFIX)))
|
||||
continue; // that's not a sprite...
|
||||
|
||||
if (stricmp(name, sprnames[spritenum]) == 0)
|
||||
{
|
||||
md2_models[spritenum].scale = scale;
|
||||
md2_models[spritenum].offset = offset;
|
||||
md2_models[spritenum].notfound = false;
|
||||
strcpy(md2_models[spritenum].filename, filename);
|
||||
goto spritemd2found;
|
||||
goto spritemodelfound;
|
||||
}
|
||||
}
|
||||
|
||||
//CONS_Printf("MD2 for sprite %s not found\n", sprnames[spritenum]);
|
||||
md2_models[spritenum].notfound = true;
|
||||
spritemd2found:
|
||||
spritemodelfound:
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
|
|
|
@ -49,4 +49,6 @@ void HWR_AddPlayerModel(INT32 skin);
|
|||
void HWR_AddSpriteModel(size_t spritenum);
|
||||
boolean HWR_DrawModel(gr_vissprite_t *spr);
|
||||
|
||||
#define PLAYERMODELPREFIX "PLAYER"
|
||||
|
||||
#endif // _HW_MD2_H_
|
||||
|
|
|
@ -2222,11 +2222,11 @@ EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration,
|
|||
EXPORT void HWRAPI(SetTransform) (FTransform *stransform)
|
||||
{
|
||||
static boolean special_splitscreen;
|
||||
float used_fov;
|
||||
pglLoadIdentity();
|
||||
if (stransform)
|
||||
{
|
||||
boolean fovx90;
|
||||
|
||||
used_fov = stransform->fovxangle;
|
||||
#ifdef USE_FTRANSFORM_MIRROR
|
||||
// mirroring from Kart
|
||||
if (stransform->mirror)
|
||||
|
@ -2238,36 +2238,34 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform)
|
|||
else
|
||||
pglScalef(stransform->scalex, stransform->scaley, -stransform->scalez);
|
||||
|
||||
if (stransform->roll)
|
||||
pglRotatef(stransform->rollangle, 0.0f, 0.0f, 1.0f);
|
||||
pglRotatef(stransform->anglex , 1.0f, 0.0f, 0.0f);
|
||||
pglRotatef(stransform->angley+270.0f, 0.0f, 1.0f, 0.0f);
|
||||
pglTranslatef(-stransform->x, -stransform->z, -stransform->y);
|
||||
|
||||
pglMatrixMode(GL_PROJECTION);
|
||||
pglLoadIdentity();
|
||||
fovx90 = stransform->fovxangle > 0.0f && fabsf(stransform->fovxangle - 90.0f) < 0.5f;
|
||||
special_splitscreen = (stransform->splitscreen && fovx90);
|
||||
if (special_splitscreen)
|
||||
GLPerspective(53.13f, 2*ASPECT_RATIO); // 53.13 = 2*atan(0.5)
|
||||
else
|
||||
GLPerspective(stransform->fovxangle, ASPECT_RATIO);
|
||||
pglGetFloatv(GL_PROJECTION_MATRIX, projMatrix); // added for new coronas' code (without depth buffer)
|
||||
pglMatrixMode(GL_MODELVIEW);
|
||||
special_splitscreen = stransform->splitscreen;
|
||||
}
|
||||
else
|
||||
{
|
||||
used_fov = fov;
|
||||
pglScalef(1.0f, 1.0f, -1.0f);
|
||||
|
||||
pglMatrixMode(GL_PROJECTION);
|
||||
pglLoadIdentity();
|
||||
if (special_splitscreen)
|
||||
GLPerspective(53.13f, 2*ASPECT_RATIO); // 53.13 = 2*atan(0.5)
|
||||
else
|
||||
//Hurdler: is "fov" correct?
|
||||
GLPerspective(fov, ASPECT_RATIO);
|
||||
pglGetFloatv(GL_PROJECTION_MATRIX, projMatrix); // added for new coronas' code (without depth buffer)
|
||||
pglMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
|
||||
pglMatrixMode(GL_PROJECTION);
|
||||
pglLoadIdentity();
|
||||
|
||||
if (special_splitscreen)
|
||||
{
|
||||
used_fov = atan(tan(used_fov*M_PI/360)*0.8)*360/M_PI;
|
||||
GLPerspective(used_fov, 2*ASPECT_RATIO);
|
||||
}
|
||||
else
|
||||
GLPerspective(used_fov, ASPECT_RATIO);
|
||||
|
||||
pglGetFloatv(GL_PROJECTION_MATRIX, projMatrix); // added for new coronas' code (without depth buffer)
|
||||
pglMatrixMode(GL_MODELVIEW);
|
||||
|
||||
pglGetFloatv(GL_MODELVIEW_MATRIX, modelMatrix); // added for new coronas' code (without depth buffer)
|
||||
}
|
||||
|
||||
|
|
128
src/hu_stuff.c
128
src/hu_stuff.c
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "m_menu.h" // gametype_cons_t
|
||||
#include "m_cond.h" // emblems
|
||||
#include "m_misc.h" // word jumping
|
||||
|
||||
#include "d_clisrv.h"
|
||||
|
||||
|
@ -501,37 +502,31 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags)
|
|||
// what we're gonna do now is check if the player exists
|
||||
// with that logic, characters 4 and 5 are our numbers:
|
||||
const char *newmsg;
|
||||
char *playernum = (char*) malloc(3);
|
||||
char playernum[3];
|
||||
INT32 spc = 1; // used if playernum[1] is a space.
|
||||
|
||||
strncpy(playernum, msg+3, 3);
|
||||
// check for undesirable characters in our "number"
|
||||
if (((playernum[0] < '0') || (playernum[0] > '9')) || ((playernum[1] < '0') || (playernum[1] > '9')))
|
||||
if (((playernum[0] < '0') || (playernum[0] > '9')) || ((playernum[1] < '0') || (playernum[1] > '9')))
|
||||
{
|
||||
// check if playernum[1] is a space
|
||||
if (playernum[1] == ' ')
|
||||
spc = 0;
|
||||
// let it slide
|
||||
// let it slide
|
||||
else
|
||||
{
|
||||
HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<playernum> \'.", false);
|
||||
free(playernum);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// I'm very bad at C, I swear I am, additional checks eww!
|
||||
if (spc != 0)
|
||||
{
|
||||
if (msg[5] != ' ')
|
||||
{
|
||||
HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<playernum> \'.", false);
|
||||
free(playernum);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (spc != 0 && msg[5] != ' ')
|
||||
{
|
||||
HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<playernum> \'.", false);
|
||||
return;
|
||||
}
|
||||
|
||||
target = atoi((const char*) playernum); // turn that into a number
|
||||
free(playernum);
|
||||
target = atoi(playernum); // turn that into a number
|
||||
//CONS_Printf("%d\n", target);
|
||||
|
||||
// check for target player, if it doesn't exist then we can't send the message!
|
||||
|
@ -659,13 +654,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
|
|||
M_GetText("Illegal say command received from %s while muted\n") : M_GetText("Illegal csay command received from non-admin %s\n"),
|
||||
player_names[playernum]);
|
||||
if (server)
|
||||
{
|
||||
UINT8 buf[2];
|
||||
|
||||
buf[0] = (UINT8)playernum;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -679,13 +668,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
|
|||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal say command received from %s containing invalid characters\n"), player_names[playernum]);
|
||||
if (server)
|
||||
{
|
||||
char buf[2];
|
||||
|
||||
buf[0] = (char)playernum;
|
||||
buf[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &buf, 2);
|
||||
}
|
||||
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1033,9 +1016,6 @@ void HU_Ticker(void)
|
|||
#ifndef NONET
|
||||
|
||||
static boolean teamtalk = false;
|
||||
/*static char chatchars[QUEUESIZE];
|
||||
static INT32 head = 0, tail = 0;*/
|
||||
// WHY DO YOU OVERCOMPLICATE EVERYTHING?????????
|
||||
|
||||
// Clear spaces so we don't end up with messages only made out of emptiness
|
||||
static boolean HU_clearChatSpaces(void)
|
||||
|
@ -1094,11 +1074,11 @@ static void HU_queueChatChar(char c)
|
|||
|
||||
if (strlen(msg) > 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm
|
||||
{
|
||||
INT32 spc = 1; // used if nodenum[1] is a space.
|
||||
char *nodenum = (char*) malloc(3);
|
||||
INT32 spc = 1; // used if playernum[1] is a space.
|
||||
char playernum[3];
|
||||
const char *newmsg;
|
||||
|
||||
// what we're gonna do now is check if the node exists
|
||||
// what we're gonna do now is check if the player exists
|
||||
// with that logic, characters 4 and 5 are our numbers:
|
||||
|
||||
// teamtalk can't send PMs, just don't send it, else everyone would be able to see it, and no one wants to see your sex RP sicko.
|
||||
|
@ -1108,18 +1088,17 @@ static void HU_queueChatChar(char c)
|
|||
return;
|
||||
}
|
||||
|
||||
strncpy(nodenum, msg+3, 3);
|
||||
strncpy(playernum, msg+3, 3);
|
||||
// check for undesirable characters in our "number"
|
||||
if (((nodenum[0] < '0') || (nodenum[0] > '9')) || ((nodenum[1] < '0') || (nodenum[1] > '9')))
|
||||
if (((playernum[0] < '0') || (playernum[0] > '9')) || ((playernum[1] < '0') || (playernum[1] > '9')))
|
||||
{
|
||||
// check if nodenum[1] is a space
|
||||
if (nodenum[1] == ' ')
|
||||
// check if playernum[1] is a space
|
||||
if (playernum[1] == ' ')
|
||||
spc = 0;
|
||||
// let it slide
|
||||
else
|
||||
{
|
||||
HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<node> \'.", false);
|
||||
free(nodenum);
|
||||
HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<player num> \'.", false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1128,14 +1107,12 @@ static void HU_queueChatChar(char c)
|
|||
{
|
||||
if (msg[5] != ' ')
|
||||
{
|
||||
HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<node> \'.", false);
|
||||
free(nodenum);
|
||||
HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm<player num> \'.", false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
target = atoi((const char*) nodenum); // turn that into a number
|
||||
free(nodenum);
|
||||
target = atoi(playernum); // turn that into a number
|
||||
//CONS_Printf("%d\n", target);
|
||||
|
||||
// check for target player, if it doesn't exist then we can't send the message!
|
||||
|
@ -1147,7 +1124,7 @@ static void HU_queueChatChar(char c)
|
|||
return;
|
||||
}
|
||||
|
||||
// we need to get rid of the /pm<node>
|
||||
// we need to get rid of the /pm<player num>
|
||||
newmsg = msg+5+spc;
|
||||
strlcpy(msg, newmsg, 255);
|
||||
}
|
||||
|
@ -1349,9 +1326,19 @@ boolean HU_Responder(event_t *ev)
|
|||
chat_scrolltime = 4;
|
||||
}
|
||||
else if (c == KEY_LEFTARROW && c_input != 0 && !OLDCHAT) // i said go back
|
||||
c_input--;
|
||||
{
|
||||
if (ctrldown)
|
||||
c_input = M_JumpWordReverse(w_chat, c_input);
|
||||
else
|
||||
c_input--;
|
||||
}
|
||||
else if (c == KEY_RIGHTARROW && c_input < strlen(w_chat) && !OLDCHAT) // don't need to check for admin or w/e here since the chat won't ever contain anything if it's muted.
|
||||
c_input++;
|
||||
{
|
||||
if (ctrldown)
|
||||
c_input += M_JumpWord(&w_chat[c_input]);
|
||||
else
|
||||
c_input++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
@ -1450,7 +1437,7 @@ static void HU_drawMiniChat(void)
|
|||
|
||||
for (; i>0; i--)
|
||||
{
|
||||
const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]);
|
||||
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]);
|
||||
size_t j = 0;
|
||||
INT32 linescount = 0;
|
||||
|
||||
|
@ -1492,6 +1479,9 @@ static void HU_drawMiniChat(void)
|
|||
dy = 0;
|
||||
dx = 0;
|
||||
msglines += linescount+1;
|
||||
|
||||
if (msg)
|
||||
Z_Free(msg);
|
||||
}
|
||||
|
||||
y = chaty - charheight*(msglines+1);
|
||||
|
@ -1514,7 +1504,7 @@ static void HU_drawMiniChat(void)
|
|||
INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below...
|
||||
INT32 transflag = (timer >= 0 && timer <= 9) ? (timer*V_10TRANS) : 0; // you can make bad jokes out of this one.
|
||||
size_t j = 0;
|
||||
const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it.
|
||||
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it.
|
||||
UINT8 *colormap = NULL;
|
||||
|
||||
while(msg[j]) // iterate through msg
|
||||
|
@ -1560,6 +1550,9 @@ static void HU_drawMiniChat(void)
|
|||
}
|
||||
dy += charheight;
|
||||
dx = 0;
|
||||
|
||||
if (msg)
|
||||
Z_Free(msg);
|
||||
}
|
||||
|
||||
// decrement addy and make that shit smooth:
|
||||
|
@ -1611,7 +1604,7 @@ static void HU_drawChatLog(INT32 offset)
|
|||
{
|
||||
INT32 clrflag = 0;
|
||||
INT32 j = 0;
|
||||
const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it.
|
||||
char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it.
|
||||
UINT8 *colormap = NULL;
|
||||
while(msg[j]) // iterate through msg
|
||||
{
|
||||
|
@ -1651,6 +1644,9 @@ static void HU_drawChatLog(INT32 offset)
|
|||
}
|
||||
dy += charheight;
|
||||
dx = 0;
|
||||
|
||||
if (msg)
|
||||
Z_Free(msg);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1660,12 +1656,9 @@ static void HU_drawChatLog(INT32 offset)
|
|||
}
|
||||
chat_scrollmedown = false;
|
||||
|
||||
// getmaxscroll through a lazy hack. We do all these loops, so let's not do more loops that are gonna lag the game more. :P
|
||||
chat_maxscroll = (dy/charheight); // welcome to C, we don't know what min() and max() are.
|
||||
if (chat_maxscroll <= (UINT32)cv_chatheight.value)
|
||||
chat_maxscroll = 0;
|
||||
else
|
||||
chat_maxscroll -= cv_chatheight.value;
|
||||
// getmaxscroll through a lazy hack. We do all these loops,
|
||||
// so let's not do more loops that are gonna lag the game more. :P
|
||||
chat_maxscroll = max(dy / charheight - cv_chatheight.value, 0);
|
||||
|
||||
// if we're not bound by the time, autoscroll for next frame:
|
||||
if (atbottom)
|
||||
|
@ -1806,21 +1799,17 @@ static void HU_DrawChat(void)
|
|||
i = 0;
|
||||
for(i=0; (i<MAXPLAYERS); i++)
|
||||
{
|
||||
|
||||
// filter: (code needs optimization pls help I'm bad with C)
|
||||
if (w_chat[3])
|
||||
{
|
||||
char *nodenum;
|
||||
char playernum[3];
|
||||
UINT32 n;
|
||||
// right, that's half important: (w_chat[4] may be a space since /pm0 msg is perfectly acceptable!)
|
||||
if ( ( ((w_chat[3] != 0) && ((w_chat[3] < '0') || (w_chat[3] > '9'))) || ((w_chat[4] != 0) && (((w_chat[4] < '0') || (w_chat[4] > '9'))))) && (w_chat[4] != ' '))
|
||||
break;
|
||||
|
||||
|
||||
nodenum = (char*) malloc(3);
|
||||
strncpy(nodenum, w_chat+3, 3);
|
||||
n = atoi((const char*) nodenum); // turn that into a number
|
||||
free(nodenum);
|
||||
strncpy(playernum, w_chat+3, 3);
|
||||
n = atoi(playernum); // turn that into a number
|
||||
// special cases:
|
||||
|
||||
if ((n == 0) && !(w_chat[4] == '0'))
|
||||
|
@ -1867,7 +1856,6 @@ static void HU_DrawChat(void)
|
|||
}
|
||||
|
||||
HU_drawChatLog(typelines-1); // typelines is the # of lines we're typing. If there's more than 1 then the log should scroll up to give us more space.
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -2390,7 +2378,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
|
|||
|
||||
if (!splitscreen) // don't draw it on splitscreen,
|
||||
{
|
||||
if (!(tab[i].num == serverplayer))
|
||||
if (!(tab[i].num == serverplayer || players[tab[i].num].quittime))
|
||||
HU_drawPing(x+ 253, y, playerpingtable[tab[i].num], false, 0);
|
||||
//else
|
||||
// V_DrawSmallString(x+ 246, y+4, V_YELLOWMAP, "SERVER");
|
||||
|
@ -2589,7 +2577,7 @@ static void HU_Draw32TeamTabRankings(playersort_t *tab, INT32 whiteplayer)
|
|||
V_DrawRightAlignedThinString(x+128, y, ((players[tab[i].num].spectator || players[tab[i].num].playerstate == PST_DEAD) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count));
|
||||
if (!splitscreen)
|
||||
{
|
||||
if (!(tab[i].num == serverplayer))
|
||||
if (!(tab[i].num == serverplayer || players[tab[i].num].quittime))
|
||||
HU_drawPing(x+ 135, y+1, playerpingtable[tab[i].num], true, 0);
|
||||
//else
|
||||
//V_DrawSmallString(x+ 129, y+4, V_YELLOWMAP, "HOST");
|
||||
|
@ -2713,7 +2701,7 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer)
|
|||
V_DrawRightAlignedThinString(x+100, y, (greycheck ? V_TRANSLUCENT : 0), va("%u", tab[i].count));
|
||||
if (!splitscreen)
|
||||
{
|
||||
if (!(tab[i].num == serverplayer))
|
||||
if (!(tab[i].num == serverplayer || players[tab[i].num].quittime))
|
||||
HU_drawPing(x+ 113, y, playerpingtable[tab[i].num], false, 0);
|
||||
//else
|
||||
// V_DrawSmallString(x+ 94, y+4, V_YELLOWMAP, "SERVER");
|
||||
|
@ -2744,7 +2732,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline
|
|||
supercheck = supercheckdef;
|
||||
|
||||
strlcpy(name, tab[i].name, 7);
|
||||
if (!(tab[i].num == serverplayer))
|
||||
if (!(tab[i].num == serverplayer || players[tab[i].num].quittime))
|
||||
HU_drawPing(x+ 113, y, playerpingtable[tab[i].num], false, 0);
|
||||
//else
|
||||
// V_DrawSmallString(x+ 94, y+4, V_YELLOWMAP, "SERVER");
|
||||
|
@ -2852,7 +2840,7 @@ static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scor
|
|||
strlcpy(name, tab[i].name, 7);
|
||||
if (!splitscreen) // don't draw it on splitscreen,
|
||||
{
|
||||
if (!(tab[i].num == serverplayer))
|
||||
if (!(tab[i].num == serverplayer || players[tab[i].num].quittime))
|
||||
HU_drawPing(x+ 135, y+1, playerpingtable[tab[i].num], true, 0);
|
||||
//else
|
||||
// V_DrawSmallString(x+ 129, y+4, V_YELLOWMAP, "HOST");
|
||||
|
|
50
src/info.c
50
src/info.c
|
@ -762,7 +762,7 @@ state_t states[NUMSTATES] =
|
|||
{SPR_PLAY, SPR2_LIFE, 20, {NULL}, 0, 4, S_NULL}, // S_PLAY_ICON3
|
||||
|
||||
// Level end sign (uses player sprite)
|
||||
{SPR_PLAY, SPR2_SIGN|FF_PAPERSPRITE, -1, {NULL}, 0, 29, S_PLAY_SIGN}, // S_PLAY_SIGN
|
||||
{SPR_PLAY, SPR2_SIGN|FF_PAPERSPRITE, 2, {NULL}, 0, 29, S_PLAY_SIGN}, // S_PLAY_SIGN
|
||||
|
||||
// NiGHTS Player, transforming
|
||||
{SPR_PLAY, SPR2_TRNS|FF_ANIMATE, 7, {NULL}, 0, 4, S_PLAY_NIGHTS_TRANS2}, // S_PLAY_NIGHTS_TRANS1
|
||||
|
@ -1849,18 +1849,19 @@ state_t states[NUMSTATES] =
|
|||
{SPR_BBLS, 3, 8, {A_BubbleCheck}, 0, 0, S_BUBBLES1}, // S_BUBBLES4
|
||||
|
||||
// Level End Sign
|
||||
{SPR_SIGN, 0, -1, {A_SignPlayer}, -3, 0, S_NULL}, // S_SIGN
|
||||
{SPR_SIGN, 0, 1, {A_SignSpin}, 30, 0, S_SIGNSPIN2}, // S_SIGNSPIN1
|
||||
{SPR_SIGN, 0, 0, {A_Repeat}, 4, S_SIGNSPIN1, S_SIGNSPIN3}, // S_SIGNSPIN2
|
||||
{SPR_SIGN, 0, 0, {A_SignPlayer}, -2, 0, S_SIGNSPIN4}, // S_SIGNSPIN3
|
||||
{SPR_SIGN, 0, 1, {A_SignSpin}, 30, 0, S_SIGNSPIN5}, // S_SIGNSPIN4
|
||||
{SPR_SIGN, 0, 0, {A_Repeat}, 4, S_SIGNSPIN4, S_SIGNSPIN6}, // S_SIGNSPIN5
|
||||
{SPR_SIGN, 0, 0, {A_SignPlayer}, -3, 0, S_SIGNSPIN1}, // S_SIGNSPIN6
|
||||
{SPR_SIGN, 0, 1, {A_SignPlayer}, -1, 0, S_SIGNSLOW}, // S_SIGNPLAYER
|
||||
{SPR_SIGN, 0, 1, {A_SignSpin}, 30, 0, S_SIGNSLOW}, // S_SIGNSLOW
|
||||
{SPR_SIGN, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SIGNSTOP
|
||||
{SPR_SIGN, FF_PAPERSPRITE|2, -1, {NULL}, 0, 0, S_NULL}, // S_SIGNBOARD
|
||||
{SPR_SIGN, FF_PAPERSPRITE|1, -1, {NULL}, 0, 29, S_NULL}, // S_EGGMANSIGN
|
||||
{SPR_SIGN, 0, -1, {A_SignPlayer}, -3, 0, S_NULL}, // S_SIGN
|
||||
{SPR_SIGN, 0, 1, {A_SignSpin}, 30, 0, S_SIGNSPIN2}, // S_SIGNSPIN1
|
||||
{SPR_SIGN, 0, 0, {A_Repeat}, 4, S_SIGNSPIN1, S_SIGNSPIN3}, // S_SIGNSPIN2
|
||||
{SPR_SIGN, 0, 0, {A_SignPlayer}, -2, 0, S_SIGNSPIN4}, // S_SIGNSPIN3
|
||||
{SPR_SIGN, 0, 1, {A_SignSpin}, 30, 0, S_SIGNSPIN5}, // S_SIGNSPIN4
|
||||
{SPR_SIGN, 0, 0, {A_Repeat}, 4, S_SIGNSPIN4, S_SIGNSPIN6}, // S_SIGNSPIN5
|
||||
{SPR_SIGN, 0, 0, {A_SignPlayer}, -3, 0, S_SIGNSPIN1}, // S_SIGNSPIN6
|
||||
{SPR_SIGN, 0, 1, {A_SignPlayer}, -1, 0, S_SIGNSLOW}, // S_SIGNPLAYER
|
||||
{SPR_SIGN, 0, 1, {A_SignSpin}, 30, 0, S_SIGNSLOW}, // S_SIGNSLOW
|
||||
{SPR_SIGN, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SIGNSTOP
|
||||
{SPR_SIGN, FF_PAPERSPRITE| 2, -1, {NULL}, 0, 0, S_NULL}, // S_SIGNBOARD
|
||||
{SPR_SIGN, FF_PAPERSPRITE| 1, -1, {NULL}, 0, 29, S_NULL}, // S_EGGMANSIGN
|
||||
{SPR_SIGN, FF_PAPERSPRITE|18, -1, {NULL}, 0, 29, S_NULL}, // S_CLEARSIGN
|
||||
|
||||
// Spike Ball
|
||||
{SPR_SPIK, 0, 1, {NULL}, 0, 0, S_SPIKEBALL2}, // S_SPIKEBALL1
|
||||
|
@ -2342,12 +2343,13 @@ state_t states[NUMSTATES] =
|
|||
|
||||
// TNT barrel
|
||||
{SPR_BARR, 0, -1, {NULL}, 0, 0, S_NULL}, // S_TNTBARREL_STND1
|
||||
{SPR_BARX, 0|FF_FULLBRIGHT, 3, {A_SetObjectFlags}, MF_NOCLIP|MF_NOGRAVITY|MF_NOBLOCKMAP, 0, S_TNTBARREL_EXPL2}, // S_TNTBARREL_EXPL1
|
||||
{SPR_BARX, 1|FF_FULLBRIGHT, 2, {A_TNTExplode}, MT_TNTDUST, 0, S_TNTBARREL_EXPL3}, // S_TNTBARREL_EXPL2
|
||||
{SPR_BARX, 1|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_TNTBARREL_EXPL4}, // S_TNTBARREL_EXPL3
|
||||
{SPR_BARX, 2|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_TNTBARREL_EXPL5}, // S_TNTBARREL_EXPL4
|
||||
{SPR_BARX, 3|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_TNTBARREL_EXPL6}, // S_TNTBARREL_EXPL5
|
||||
{SPR_NULL, 0, 35, {NULL}, 0, 0, S_NULL}, // S_TNTBARREL_EXPL6
|
||||
{SPR_BARX, 0, 0, {A_RollAngle}, 0, 1, S_TNTBARREL_EXPL2}, // S_TNTBARREL_EXPL1
|
||||
{SPR_BARX, 0|FF_FULLBRIGHT, 3, {A_SetObjectFlags}, MF_NOCLIP|MF_NOGRAVITY|MF_NOBLOCKMAP, 0, S_TNTBARREL_EXPL3}, // S_TNTBARREL_EXPL2
|
||||
{SPR_BARX, 1|FF_FULLBRIGHT, 2, {A_TNTExplode}, MT_TNTDUST, 0, S_TNTBARREL_EXPL4}, // S_TNTBARREL_EXPL3
|
||||
{SPR_BARX, 1|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_TNTBARREL_EXPL5}, // S_TNTBARREL_EXPL4
|
||||
{SPR_BARX, 2|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_TNTBARREL_EXPL6}, // S_TNTBARREL_EXPL5
|
||||
{SPR_BARX, 3|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_TNTBARREL_EXPL7}, // S_TNTBARREL_EXPL6
|
||||
{SPR_NULL, 0, 35, {NULL}, 0, 0, S_NULL}, // S_TNTBARREL_EXPL7
|
||||
#ifndef ROTSPRITE
|
||||
{SPR_BARR, 1|FF_ANIMATE, -1, {NULL}, 7, 2, S_NULL}, // S_TNTBARREL_FLYING
|
||||
#else
|
||||
|
@ -2393,7 +2395,7 @@ state_t states[NUMSTATES] =
|
|||
|
||||
// Minecart
|
||||
{SPR_NULL, 0, 1, {NULL}, 0, 0, S_MINECART_IDLE}, // S_MINECART_IDLE
|
||||
{SPR_NULL, 0, 0, {A_KillSegments}, 0, 0, S_TNTBARREL_EXPL3}, // S_MINECART_DTH1
|
||||
{SPR_NULL, 0, 0, {A_KillSegments}, 0, 0, S_TNTBARREL_EXPL4}, // S_MINECART_DTH1
|
||||
{SPR_MCRT, 8|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_MINECARTEND
|
||||
{SPR_MCRT, 0|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_MINECARTSEG_FRONT
|
||||
{SPR_MCRT, 1|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_MINECARTSEG_BACK
|
||||
|
@ -5734,7 +5736,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
0, // mass
|
||||
0, // damage
|
||||
sfx_spring, // activesound
|
||||
MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING, // flags
|
||||
MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT, // flags
|
||||
S_EGGMOBILE2_POGO5 // raisestate
|
||||
},
|
||||
|
||||
|
@ -6486,10 +6488,10 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
24*FRACUNIT, // radius
|
||||
24*FRACUNIT, // height
|
||||
0, // display offset
|
||||
0, // mass
|
||||
DMG_FIRE, // mass
|
||||
1, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags
|
||||
MF_NOBLOCKMAP|MF_MISSILE|MF_PAIN|MF_NOGRAVITY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
@ -7850,7 +7852,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
MT_SPARK, // painchance
|
||||
sfx_s3kb8, // painsound
|
||||
S_EGGMANSIGN, // meleestate
|
||||
S_NULL, // missilestate
|
||||
S_CLEARSIGN, // missilestate
|
||||
S_SIGNSTOP, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_s3k64, // deathsound
|
||||
|
|
|
@ -2022,6 +2022,7 @@ typedef enum state
|
|||
S_SIGNSTOP,
|
||||
S_SIGNBOARD,
|
||||
S_EGGMANSIGN,
|
||||
S_CLEARSIGN,
|
||||
|
||||
// Spike Ball
|
||||
S_SPIKEBALL1,
|
||||
|
@ -2503,6 +2504,7 @@ typedef enum state
|
|||
S_TNTBARREL_EXPL4,
|
||||
S_TNTBARREL_EXPL5,
|
||||
S_TNTBARREL_EXPL6,
|
||||
S_TNTBARREL_EXPL7,
|
||||
S_TNTBARREL_FLYING,
|
||||
|
||||
// TNT proximity shell
|
||||
|
|
|
@ -2193,6 +2193,20 @@ static int lib_rPointInSubsector(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int lib_rPointInSubsectorOrNil(lua_State *L)
|
||||
{
|
||||
fixed_t x = luaL_checkfixed(L, 1);
|
||||
fixed_t y = luaL_checkfixed(L, 2);
|
||||
subsector_t *sub = R_PointInSubsectorOrNull(x, y);
|
||||
//HUDSAFE
|
||||
INLEVEL
|
||||
if (sub)
|
||||
LUA_PushUserdata(L, sub, META_SUBSECTOR);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// R_THINGS
|
||||
////////////
|
||||
|
||||
|
@ -3127,6 +3141,7 @@ static luaL_Reg lib[] = {
|
|||
{"R_PointToDist",lib_rPointToDist},
|
||||
{"R_PointToDist2",lib_rPointToDist2},
|
||||
{"R_PointInSubsector",lib_rPointInSubsector},
|
||||
{"R_PointInSubsectorOrNil",lib_rPointInSubsectorOrNil},
|
||||
|
||||
// r_things (sprite)
|
||||
{"R_Char2Frame",lib_rChar2Frame},
|
||||
|
|
|
@ -87,13 +87,7 @@ deny:
|
|||
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal lua command received from %s\n"), player_names[playernum]);
|
||||
if (server)
|
||||
{
|
||||
UINT8 bufn[2];
|
||||
|
||||
bufn[0] = (UINT8)playernum;
|
||||
bufn[1] = KICK_MSG_CON_FAIL;
|
||||
SendNetXCmd(XD_KICK, &bufn, 2);
|
||||
}
|
||||
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
}
|
||||
|
||||
// Wrapper for COM_AddCommand commands
|
||||
|
|
|
@ -102,7 +102,7 @@ boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8
|
|||
boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing); // Hook for P_SpawnMapThing by mobj type
|
||||
boolean LUAh_FollowMobj(player_t *player, mobj_t *mobj); // Hook for P_PlayerAfterThink Smiles mobj-following
|
||||
UINT8 LUAh_PlayerCanDamage(player_t *player, mobj_t *mobj); // Hook for P_PlayerCanDamage
|
||||
void LUAh_PlayerQuit(player_t *plr, int reason); // Hook for player quitting
|
||||
void LUAh_PlayerQuit(player_t *plr, kickreason_t reason); // Hook for player quitting
|
||||
void LUAh_IntermissionThinker(void); // Hook for Y_Ticker
|
||||
boolean LUAh_TeamSwitch(player_t *player, int newteam, boolean fromspectators, boolean tryingautobalance, boolean tryingscramble); // Hook for team switching in... uh....
|
||||
UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean forced); // Hook for spy mode
|
||||
|
|
|
@ -1439,7 +1439,7 @@ UINT8 LUAh_PlayerCanDamage(player_t *player, mobj_t *mobj)
|
|||
return shouldCollide;
|
||||
}
|
||||
|
||||
void LUAh_PlayerQuit(player_t *plr, int reason)
|
||||
void LUAh_PlayerQuit(player_t *plr, kickreason_t reason)
|
||||
{
|
||||
hook_p hookp;
|
||||
if (!gL || !(hooksAvailable[hook_PlayerQuit/8] & (1<<(hook_PlayerQuit%8))))
|
||||
|
|
|
@ -268,10 +268,14 @@ static int patch_get(lua_State *L)
|
|||
#endif
|
||||
enum patch field = luaL_checkoption(L, 2, NULL, patch_opt);
|
||||
|
||||
// patches are CURRENTLY always valid, expected to be cached with PU_STATIC
|
||||
// this may change in the future, so patch.valid still exists
|
||||
if (!patch)
|
||||
// patches are invalidated when switching renderers
|
||||
if (!patch) {
|
||||
if (field == patch_valid) {
|
||||
lua_pushboolean(L, 0);
|
||||
return 1;
|
||||
}
|
||||
return LUA_ErrInvalid(L, "patch_t");
|
||||
}
|
||||
|
||||
switch (field)
|
||||
{
|
||||
|
@ -424,7 +428,7 @@ static int libd_cachePatch(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
// v.getSpritePatch(sprite, [frame, [angle]])
|
||||
// v.getSpritePatch(sprite, [frame, [angle, [rollangle]]])
|
||||
static int libd_getSpritePatch(lua_State *L)
|
||||
{
|
||||
UINT32 i; // sprite prefix
|
||||
|
@ -475,13 +479,31 @@ static int libd_getSpritePatch(lua_State *L)
|
|||
if (angle >= ((sprframe->rotate & SRF_3DGE) ? 16 : 8)) // out of range?
|
||||
return 0;
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
if (lua_isnumber(L, 4))
|
||||
{
|
||||
// rotsprite?????
|
||||
angle_t rollangle = luaL_checkangle(L, 4);
|
||||
INT32 rot = R_GetRollAngle(rollangle);
|
||||
|
||||
if (rot) {
|
||||
if (!(sprframe->rotsprite.cached & (1<<angle)))
|
||||
R_CacheRotSprite(i, frame, NULL, sprframe, angle, sprframe->flip & (1<<angle));
|
||||
LUA_PushUserdata(L, sprframe->rotsprite.patch[angle][rot], META_PATCH);
|
||||
lua_pushboolean(L, false);
|
||||
lua_pushboolean(L, true);
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// push both the patch and it's "flip" value
|
||||
LUA_PushUserdata(L, W_CachePatchNum(sprframe->lumppat[angle], PU_PATCH), META_PATCH);
|
||||
lua_pushboolean(L, (sprframe->flip & (1<<angle)) != 0);
|
||||
return 2;
|
||||
}
|
||||
|
||||
// v.getSprite2Patch(skin, sprite, [super?,] [frame, [angle]])
|
||||
// v.getSprite2Patch(skin, sprite, [super?,] [frame, [angle, [rollangle]]])
|
||||
static int libd_getSprite2Patch(lua_State *L)
|
||||
{
|
||||
INT32 i; // skin number
|
||||
|
@ -570,6 +592,24 @@ static int libd_getSprite2Patch(lua_State *L)
|
|||
if (angle >= ((sprframe->rotate & SRF_3DGE) ? 16 : 8)) // out of range?
|
||||
return 0;
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
if (lua_isnumber(L, 4))
|
||||
{
|
||||
// rotsprite?????
|
||||
angle_t rollangle = luaL_checkangle(L, 4);
|
||||
INT32 rot = R_GetRollAngle(rollangle);
|
||||
|
||||
if (rot) {
|
||||
if (!(sprframe->rotsprite.cached & (1<<angle)))
|
||||
R_CacheRotSprite(SPR_PLAY, frame, &skins[i].sprinfo[j], sprframe, angle, sprframe->flip & (1<<angle));
|
||||
LUA_PushUserdata(L, sprframe->rotsprite.patch[angle][rot], META_PATCH);
|
||||
lua_pushboolean(L, false);
|
||||
lua_pushboolean(L, true);
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// push both the patch and it's "flip" value
|
||||
LUA_PushUserdata(L, W_CachePatchNum(sprframe->lumppat[angle], PU_PATCH), META_PATCH);
|
||||
lua_pushboolean(L, (sprframe->flip & (1<<angle)) != 0);
|
||||
|
@ -1214,7 +1254,7 @@ void LUAh_GameHUD(player_t *stplayr)
|
|||
|
||||
lua_getfield(gL, LUA_REGISTRYINDEX, "HUD");
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
lua_rawgeti(gL, -1, 2); // HUD[2] = rendering funcs
|
||||
lua_rawgeti(gL, -1, 2+hudhook_game); // HUD[2] = rendering funcs
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
|
||||
lua_rawgeti(gL, -2, 1); // HUD[1] = lib_draw
|
||||
|
@ -1248,7 +1288,7 @@ void LUAh_ScoresHUD(void)
|
|||
|
||||
lua_getfield(gL, LUA_REGISTRYINDEX, "HUD");
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
lua_rawgeti(gL, -1, 3); // HUD[3] = rendering funcs
|
||||
lua_rawgeti(gL, -1, 2+hudhook_scores); // HUD[3] = rendering funcs
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
|
||||
lua_rawgeti(gL, -2, 1); // HUD[1] = lib_draw
|
||||
|
@ -1273,7 +1313,7 @@ void LUAh_TitleHUD(void)
|
|||
|
||||
lua_getfield(gL, LUA_REGISTRYINDEX, "HUD");
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
lua_rawgeti(gL, -1, 4); // HUD[4] = rendering funcs
|
||||
lua_rawgeti(gL, -1, 2+hudhook_title); // HUD[5] = rendering funcs
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
|
||||
lua_rawgeti(gL, -2, 1); // HUD[1] = lib_draw
|
||||
|
@ -1298,7 +1338,7 @@ void LUAh_TitleCardHUD(player_t *stplayr)
|
|||
|
||||
lua_getfield(gL, LUA_REGISTRYINDEX, "HUD");
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
lua_rawgeti(gL, -1, 5); // HUD[5] = rendering funcs
|
||||
lua_rawgeti(gL, -1, 2+hudhook_titlecard); // HUD[6] = rendering funcs
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
|
||||
lua_rawgeti(gL, -2, 1); // HUD[1] = lib_draw
|
||||
|
@ -1332,7 +1372,7 @@ void LUAh_IntermissionHUD(void)
|
|||
|
||||
lua_getfield(gL, LUA_REGISTRYINDEX, "HUD");
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
lua_rawgeti(gL, -1, 4); // HUD[4] = rendering funcs
|
||||
lua_rawgeti(gL, -1, 2+hudhook_intermission); // HUD[4] = rendering funcs
|
||||
I_Assert(lua_istable(gL, -1));
|
||||
|
||||
lua_rawgeti(gL, -2, 1); // HUD[1] = lib_draw
|
||||
|
|
|
@ -157,13 +157,21 @@ static const char *const side_opt[] = {
|
|||
enum vertex_e {
|
||||
vertex_valid = 0,
|
||||
vertex_x,
|
||||
vertex_y
|
||||
vertex_y,
|
||||
vertex_floorz,
|
||||
vertex_floorzset,
|
||||
vertex_ceilingz,
|
||||
vertex_ceilingzset
|
||||
};
|
||||
|
||||
static const char *const vertex_opt[] = {
|
||||
"valid",
|
||||
"x",
|
||||
"y",
|
||||
"floorz",
|
||||
"floorzset",
|
||||
"ceilingz",
|
||||
"ceilingzset",
|
||||
NULL};
|
||||
|
||||
enum ffloor_e {
|
||||
|
@ -968,6 +976,18 @@ static int vertex_get(lua_State *L)
|
|||
case vertex_y:
|
||||
lua_pushfixed(L, vertex->y);
|
||||
return 1;
|
||||
case vertex_floorzset:
|
||||
lua_pushboolean(L, vertex->floorzset);
|
||||
return 1;
|
||||
case vertex_ceilingzset:
|
||||
lua_pushboolean(L, vertex->ceilingzset);
|
||||
return 1;
|
||||
case vertex_floorz:
|
||||
lua_pushfixed(L, vertex->floorz);
|
||||
return 1;
|
||||
case vertex_ceilingz:
|
||||
lua_pushfixed(L, vertex->ceilingz);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -2014,6 +2034,8 @@ static int mapheaderinfo_get(lua_State *L)
|
|||
lua_pushinteger(L, header->typeoflevel);
|
||||
else if (fastcmp(field,"nextlevel"))
|
||||
lua_pushinteger(L, header->nextlevel);
|
||||
else if (fastcmp(field,"keywords"))
|
||||
lua_pushstring(L, header->keywords);
|
||||
else if (fastcmp(field,"musname"))
|
||||
lua_pushstring(L, header->musname);
|
||||
else if (fastcmp(field,"mustrack"))
|
||||
|
|
|
@ -88,7 +88,8 @@ enum mobj_e {
|
|||
#ifdef ESLOPE
|
||||
mobj_standingslope,
|
||||
#endif
|
||||
mobj_colorized
|
||||
mobj_colorized,
|
||||
mobj_shadowscale
|
||||
};
|
||||
|
||||
static const char *const mobj_opt[] = {
|
||||
|
@ -156,6 +157,7 @@ static const char *const mobj_opt[] = {
|
|||
"standingslope",
|
||||
#endif
|
||||
"colorized",
|
||||
"shadowscale",
|
||||
NULL};
|
||||
|
||||
#define UNIMPLEMENTED luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", mobj_opt[field])
|
||||
|
@ -390,6 +392,9 @@ static int mobj_get(lua_State *L)
|
|||
case mobj_colorized:
|
||||
lua_pushboolean(L, mo->colorized);
|
||||
break;
|
||||
case mobj_shadowscale:
|
||||
lua_pushfixed(L, mo->shadowscale);
|
||||
break;
|
||||
default: // extra custom variables in Lua memory
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
|
||||
I_Assert(lua_istable(L, -1));
|
||||
|
@ -719,6 +724,9 @@ static int mobj_set(lua_State *L)
|
|||
case mobj_colorized:
|
||||
mo->colorized = luaL_checkboolean(L, 3);
|
||||
break;
|
||||
case mobj_shadowscale:
|
||||
mo->shadowscale = luaL_checkfixed(L, 3);
|
||||
break;
|
||||
default:
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
|
||||
I_Assert(lua_istable(L, -1));
|
||||
|
|
|
@ -120,6 +120,8 @@ static int player_get(lua_State *L)
|
|||
lua_pushfixed(L, plr->deltaviewheight);
|
||||
else if (fastcmp(field,"bob"))
|
||||
lua_pushfixed(L, plr->bob);
|
||||
else if (fastcmp(field,"viewrollangle"))
|
||||
lua_pushangle(L, plr->viewrollangle);
|
||||
else if (fastcmp(field,"aiming"))
|
||||
lua_pushangle(L, plr->aiming);
|
||||
else if (fastcmp(field,"drawangle"))
|
||||
|
@ -362,6 +364,8 @@ static int player_get(lua_State *L)
|
|||
lua_pushinteger(L, plr->bot);
|
||||
else if (fastcmp(field,"jointime"))
|
||||
lua_pushinteger(L, plr->jointime);
|
||||
else if (fastcmp(field,"quittime"))
|
||||
lua_pushinteger(L, plr->quittime);
|
||||
#ifdef HWRENDER
|
||||
else if (fastcmp(field,"fovadd"))
|
||||
lua_pushfixed(L, plr->fovadd);
|
||||
|
@ -415,6 +419,8 @@ static int player_set(lua_State *L)
|
|||
plr->deltaviewheight = luaL_checkfixed(L, 3);
|
||||
else if (fastcmp(field,"bob"))
|
||||
plr->bob = luaL_checkfixed(L, 3);
|
||||
else if (fastcmp(field,"viewrollangle"))
|
||||
plr->viewrollangle = luaL_checkangle(L, 3);
|
||||
else if (fastcmp(field,"aiming")) {
|
||||
plr->aiming = luaL_checkangle(L, 3);
|
||||
if (plr == &players[consoleplayer])
|
||||
|
@ -701,6 +707,8 @@ static int player_set(lua_State *L)
|
|||
return NOSET;
|
||||
else if (fastcmp(field,"jointime"))
|
||||
plr->jointime = (tic_t)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"quittime"))
|
||||
plr->quittime = (tic_t)luaL_checkinteger(L, 3);
|
||||
#ifdef HWRENDER
|
||||
else if (fastcmp(field,"fovadd"))
|
||||
plr->fovadd = luaL_checkfixed(L, 3);
|
||||
|
|
|
@ -102,6 +102,9 @@ int LUA_PushGlobals(lua_State *L, const char *word)
|
|||
} else if (fastcmp(word,"circuitmap")) {
|
||||
lua_pushboolean(L, circuitmap);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"stoppedclock")) {
|
||||
lua_pushboolean(L, stoppedclock);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"netgame")) {
|
||||
lua_pushboolean(L, netgame);
|
||||
return 1;
|
||||
|
@ -274,12 +277,6 @@ int LUA_PushGlobals(lua_State *L, const char *word)
|
|||
return 0;
|
||||
LUA_PushUserdata(L, &players[serverplayer], META_PLAYER);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"admin")) { // BACKWARDS COMPATIBILITY HACK: This was replaced with IsPlayerAdmin(), but some 2.1 Lua scripts still use the admin variable. It now points to the first admin player in the array.
|
||||
LUA_Deprecated(L, "admin", "IsPlayerAdmin(player)");
|
||||
if (!playeringame[adminplayers[0]] || IsPlayerAdmin(serverplayer))
|
||||
return 0;
|
||||
LUA_PushUserdata(L, &players[adminplayers[0]], META_PLAYER);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"emeralds")) {
|
||||
lua_pushinteger(L, emeralds);
|
||||
return 1;
|
||||
|
|
107
src/m_anigif.c
107
src/m_anigif.c
|
@ -19,6 +19,7 @@
|
|||
#include "v_video.h"
|
||||
#include "i_video.h"
|
||||
#include "m_misc.h"
|
||||
#include "st_stuff.h" // st_palette
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h"
|
||||
|
@ -29,11 +30,17 @@
|
|||
|
||||
consvar_t cv_gif_optimize = {"gif_optimize", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_gif_downscale = {"gif_downscale", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_gif_localcolortable = {"gif_localcolortable", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
#ifdef HAVE_ANIGIF
|
||||
static boolean gif_optimize = false; // So nobody can do something dumb
|
||||
static boolean gif_downscale = false; // like changing cvars mid output
|
||||
static RGBA_t *gif_palette = NULL;
|
||||
|
||||
// Palette handling
|
||||
static boolean gif_localcolortable = false;
|
||||
static boolean gif_colorprofile = false;
|
||||
static RGBA_t *gif_headerpalette = NULL;
|
||||
static RGBA_t *gif_framepalette = NULL;
|
||||
|
||||
static FILE *gif_out = NULL;
|
||||
static INT32 gif_frames = 0;
|
||||
|
@ -393,16 +400,47 @@ const UINT8 gifhead_nsid[19] = {0x21,0xFF,0x0B, // extension block + size
|
|||
0x4E,0x45,0x54,0x53,0x43,0x41,0x50,0x45,0x32,0x2E,0x30, // NETSCAPE2.0
|
||||
0x03,0x01,0xFF,0xFF,0x00}; // sub-block, repetitions
|
||||
|
||||
|
||||
//
|
||||
// GIF_getpalette
|
||||
// determine the palette for the current frame.
|
||||
//
|
||||
static RGBA_t *GIF_getpalette(size_t palnum)
|
||||
{
|
||||
// In hardware mode, always returns the local palette
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
return pLocalPalette;
|
||||
else
|
||||
#endif
|
||||
return (gif_colorprofile ? &pLocalPalette[palnum*256] : &pMasterPalette[palnum*256]);
|
||||
}
|
||||
|
||||
//
|
||||
// GIF_palwrite
|
||||
// writes the gif palette.
|
||||
// used both for the header and local color tables.
|
||||
//
|
||||
static UINT8 *GIF_palwrite(UINT8 *p, RGBA_t *pal)
|
||||
{
|
||||
INT32 i;
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
WRITEUINT8(p, pal[i].s.red);
|
||||
WRITEUINT8(p, pal[i].s.green);
|
||||
WRITEUINT8(p, pal[i].s.blue);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
//
|
||||
// GIF_headwrite
|
||||
// writes the gif header to the currently open output file.
|
||||
// NOTE that this code does not accomodate for palette changes.
|
||||
//
|
||||
static void GIF_headwrite(void)
|
||||
{
|
||||
UINT8 *gifhead = Z_Malloc(800, PU_STATIC, NULL);
|
||||
UINT8 *p = gifhead;
|
||||
INT32 i;
|
||||
UINT16 rwidth, rheight;
|
||||
|
||||
if (!gif_out)
|
||||
|
@ -423,24 +461,17 @@ static void GIF_headwrite(void)
|
|||
rwidth = vid.width;
|
||||
rheight = vid.height;
|
||||
}
|
||||
|
||||
WRITEUINT16(p, rwidth);
|
||||
WRITEUINT16(p, rheight);
|
||||
|
||||
// colors, aspect, etc
|
||||
WRITEUINT8(p, 0xF7);
|
||||
WRITEUINT8(p, 0xF7); // (0xF7 = 1111 0111)
|
||||
WRITEUINT8(p, 0x00);
|
||||
WRITEUINT8(p, 0x00);
|
||||
|
||||
// write color table
|
||||
{
|
||||
RGBA_t *pal = gif_palette;
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
WRITEUINT8(p, pal[i].s.red);
|
||||
WRITEUINT8(p, pal[i].s.green);
|
||||
WRITEUINT8(p, pal[i].s.blue);
|
||||
}
|
||||
}
|
||||
p = GIF_palwrite(p, gif_headerpalette);
|
||||
|
||||
// write extension block
|
||||
WRITEMEM(p, gifhead_nsid, sizeof(gifhead_nsid));
|
||||
|
@ -468,7 +499,7 @@ static void hwrconvert(void)
|
|||
INT32 x, y;
|
||||
size_t i = 0;
|
||||
|
||||
InitColorLUT(gif_palette);
|
||||
InitColorLUT(gif_framepalette);
|
||||
|
||||
for (y = 0; y < vid.height; y++)
|
||||
{
|
||||
|
@ -494,6 +525,7 @@ static void GIF_framewrite(void)
|
|||
UINT8 *p;
|
||||
UINT8 *movie_screen = screens[2];
|
||||
INT32 blitx, blity, blitw, blith;
|
||||
boolean palchanged;
|
||||
|
||||
if (!gifframe_data)
|
||||
gifframe_data = Z_Malloc(gifframe_size, PU_STATIC, NULL);
|
||||
|
@ -502,8 +534,18 @@ static void GIF_framewrite(void)
|
|||
if (!gif_out)
|
||||
return;
|
||||
|
||||
// Lactozilla: Compare the header's palette with the current frame's palette and see if it changed.
|
||||
if (gif_localcolortable)
|
||||
{
|
||||
gif_framepalette = GIF_getpalette(max(st_palette, 0));
|
||||
palchanged = memcmp(gif_headerpalette, gif_framepalette, sizeof(RGBA_t) * 256);
|
||||
}
|
||||
else
|
||||
palchanged = false;
|
||||
|
||||
// Compare image data (for optimizing GIF)
|
||||
if (gif_optimize && gif_frames > 0)
|
||||
// If the palette has changed, the entire frame is considered to be different.
|
||||
if (gif_optimize && gif_frames > 0 && (!palchanged))
|
||||
{
|
||||
// before blit movie_screen points to last frame, cur_screen points to this frame
|
||||
UINT8 *cur_screen = screens[0];
|
||||
|
@ -566,7 +608,20 @@ static void GIF_framewrite(void)
|
|||
WRITEUINT16(p, (UINT16)(blity / scrbuf_downscaleamt));
|
||||
WRITEUINT16(p, (UINT16)(blitw / scrbuf_downscaleamt));
|
||||
WRITEUINT16(p, (UINT16)(blith / scrbuf_downscaleamt));
|
||||
WRITEUINT8(p, 0); // no local table of colors
|
||||
|
||||
if (!gif_localcolortable)
|
||||
WRITEUINT8(p, 0); // no local table of colors
|
||||
else
|
||||
{
|
||||
if (palchanged)
|
||||
{
|
||||
// The palettes are different, so write the Local Color Table!
|
||||
WRITEUINT8(p, 0x87); // (0x87 = 1000 0111)
|
||||
p = GIF_palwrite(p, gif_framepalette);
|
||||
}
|
||||
else
|
||||
WRITEUINT8(p, 0); // They are equal, no Local Color Table needed.
|
||||
}
|
||||
|
||||
scrbuf_pos = movie_screen + blitx + (blity * vid.width);
|
||||
scrbuf_writeend = scrbuf_pos + (blitw - 1) + ((blith - 1) * vid.width);
|
||||
|
@ -624,29 +679,15 @@ static void GIF_framewrite(void)
|
|||
//
|
||||
INT32 GIF_open(const char *filename)
|
||||
{
|
||||
#if 0
|
||||
if (rendermode != render_soft)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("GIFs cannot be taken in non-software modes!\n"));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
gif_out = fopen(filename, "wb");
|
||||
if (!gif_out)
|
||||
return 0;
|
||||
|
||||
gif_optimize = (!!cv_gif_optimize.value);
|
||||
gif_downscale = (!!cv_gif_downscale.value);
|
||||
|
||||
// GIF color table
|
||||
// In hardware mode, uses the master palette
|
||||
gif_palette = ((cv_screenshot_colorprofile.value
|
||||
#ifdef HWRENDER
|
||||
&& (rendermode == render_soft)
|
||||
#endif
|
||||
) ? pLocalPalette
|
||||
: pMasterPalette);
|
||||
gif_localcolortable = (!!cv_gif_localcolortable.value);
|
||||
gif_colorprofile = (!!cv_screenshot_colorprofile.value);
|
||||
gif_headerpalette = GIF_getpalette(0);
|
||||
|
||||
GIF_headwrite();
|
||||
gif_frames = 0;
|
||||
|
|
|
@ -27,6 +27,6 @@ void GIF_frame(void);
|
|||
INT32 GIF_close(void);
|
||||
#endif
|
||||
|
||||
extern consvar_t cv_gif_optimize, cv_gif_downscale;
|
||||
extern consvar_t cv_gif_optimize, cv_gif_downscale, cv_gif_localcolortable;
|
||||
|
||||
#endif
|
||||
|
|
21
src/m_argv.c
21
src/m_argv.c
|
@ -92,36 +92,21 @@ const char *M_GetNextParm(void)
|
|||
void M_PushSpecialParameters(void)
|
||||
{
|
||||
INT32 i;
|
||||
char s[256];
|
||||
boolean onetime = false;
|
||||
|
||||
for (i = 1; i < myargc; i++)
|
||||
{
|
||||
if (myargv[i][0] == '+')
|
||||
{
|
||||
strcpy(s, &myargv[i][1]);
|
||||
COM_BufAddText(&myargv[i][1]);
|
||||
i++;
|
||||
|
||||
// get the parameters of the command too
|
||||
for (; i < myargc && myargv[i][0] != '+' && myargv[i][0] != '-'; i++)
|
||||
{
|
||||
strcat(s, " ");
|
||||
if (!onetime)
|
||||
{
|
||||
strcat(s, "\"");
|
||||
onetime = true;
|
||||
}
|
||||
strcat(s, myargv[i]);
|
||||
COM_BufAddText(va(" \"%s\"", myargv[i]));
|
||||
}
|
||||
if (onetime)
|
||||
{
|
||||
strcat(s, "\"");
|
||||
onetime = false;
|
||||
}
|
||||
strcat(s, "\n");
|
||||
|
||||
// push it
|
||||
COM_BufAddText(s);
|
||||
COM_BufAddText("\n");
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -452,7 +452,7 @@ void Command_RTeleport_f(void)
|
|||
else
|
||||
inty = 0;
|
||||
|
||||
ss = R_IsPointInSubsector(p->mo->x + intx*FRACUNIT, p->mo->y + inty*FRACUNIT);
|
||||
ss = R_PointInSubsectorOrNull(p->mo->x + intx*FRACUNIT, p->mo->y + inty*FRACUNIT);
|
||||
if (!ss || ss->sector->ceilingheight - ss->sector->floorheight < p->mo->height)
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("Not a valid location.\n"));
|
||||
|
@ -530,7 +530,7 @@ void Command_Teleport_f(void)
|
|||
inty = mt->y<<FRACBITS;
|
||||
offset = mt->z<<FRACBITS;
|
||||
|
||||
ss = R_IsPointInSubsector(intx, inty);
|
||||
ss = R_PointInSubsectorOrNull(intx, inty);
|
||||
if (!ss || ss->sector->ceilingheight - ss->sector->floorheight < p->mo->height)
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("Spawnpoint not in a valid location.\n"));
|
||||
|
@ -597,7 +597,7 @@ void Command_Teleport_f(void)
|
|||
return;
|
||||
}
|
||||
|
||||
ss = R_IsPointInSubsector(mo2->x, mo2->y);
|
||||
ss = R_PointInSubsectorOrNull(mo2->x, mo2->y);
|
||||
if (!ss || ss->sector->ceilingheight - ss->sector->floorheight < p->mo->height)
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("Starpost not in a valid location.\n"));
|
||||
|
@ -653,7 +653,7 @@ void Command_Teleport_f(void)
|
|||
}
|
||||
}
|
||||
|
||||
ss = R_IsPointInSubsector(intx, inty);
|
||||
ss = R_PointInSubsectorOrNull(intx, inty);
|
||||
if (!ss || ss->sector->ceilingheight - ss->sector->floorheight < p->mo->height)
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("Not a valid location.\n"));
|
||||
|
|
259
src/m_menu.c
259
src/m_menu.c
|
@ -231,6 +231,8 @@ static void M_Credits(INT32 choice);
|
|||
static void M_SoundTest(INT32 choice);
|
||||
static void M_PandorasBox(INT32 choice);
|
||||
static void M_EmblemHints(INT32 choice);
|
||||
static void M_HandleEmblemHints(INT32 choice);
|
||||
UINT32 hintpage = 1;
|
||||
static void M_HandleChecklist(INT32 choice);
|
||||
menu_t SR_MainDef, SR_UnlockChecklistDef;
|
||||
|
||||
|
@ -323,6 +325,7 @@ menu_t OP_DataOptionsDef, OP_ScreenshotOptionsDef, OP_EraseDataDef;
|
|||
menu_t OP_ServerOptionsDef;
|
||||
menu_t OP_MonitorToggleDef;
|
||||
static void M_ScreenshotOptions(INT32 choice);
|
||||
static void M_SetupScreenshotMenu(void);
|
||||
static void M_EraseData(INT32 choice);
|
||||
|
||||
static void M_Addons(INT32 choice);
|
||||
|
@ -364,7 +367,6 @@ static void M_DrawMonitorToggles(void);
|
|||
static void M_OGL_DrawFogMenu(void);
|
||||
#endif
|
||||
#ifndef NONET
|
||||
static void M_DrawScreenshotMenu(void);
|
||||
static void M_DrawConnectMenu(void);
|
||||
static void M_DrawMPMainMenu(void);
|
||||
static void M_DrawRoomMenu(void);
|
||||
|
@ -727,8 +729,9 @@ static menuitem_t SR_SoundTestMenu[] =
|
|||
|
||||
static menuitem_t SR_EmblemHintMenu[] =
|
||||
{
|
||||
{IT_STRING|IT_CVAR, NULL, "Emblem Radar", &cv_itemfinder, 10},
|
||||
{IT_WHITESTRING|IT_SUBMENU, NULL, "Back", &SPauseDef, 20}
|
||||
{IT_STRING | IT_ARROWS, NULL, "Page", M_HandleEmblemHints, 10},
|
||||
{IT_STRING|IT_CVAR, NULL, "Emblem Radar", &cv_itemfinder, 20},
|
||||
{IT_WHITESTRING|IT_SUBMENU, NULL, "Back", &SPauseDef, 30}
|
||||
};
|
||||
|
||||
// --------------------------------
|
||||
|
@ -1397,7 +1400,7 @@ static menuitem_t OP_OpenGLOptionsMenu[] =
|
|||
{IT_STRING|IT_CVAR, NULL, "Model lighting", &cv_grmodellighting, 32},
|
||||
|
||||
{IT_HEADER, NULL, "General", NULL, 51},
|
||||
{IT_STRING|IT_CVAR, NULL, "Field of view", &cv_grfov, 63},
|
||||
{IT_STRING|IT_CVAR, NULL, "Field of view", &cv_fov, 63},
|
||||
{IT_STRING|IT_CVAR, NULL, "Quality", &cv_scr_depth, 73},
|
||||
{IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 83},
|
||||
{IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode,93},
|
||||
|
@ -1446,8 +1449,9 @@ static menuitem_t OP_SoundOptionsMenu[] =
|
|||
{IT_HEADER, NULL, "Miscellaneous", NULL, 102},
|
||||
{IT_STRING | IT_CVAR, NULL, "Closed Captioning", &cv_closedcaptioning, 114},
|
||||
{IT_STRING | IT_CVAR, NULL, "Reset Music Upon Dying", &cv_resetmusic, 124},
|
||||
{IT_STRING | IT_CVAR, NULL, "Default 1-Up sound", &cv_1upsound, 134},
|
||||
|
||||
{IT_STRING | IT_SUBMENU, NULL, "Advanced Settings...", &OP_SoundAdvancedDef, 144},
|
||||
{IT_STRING | IT_SUBMENU, NULL, "Advanced Settings...", &OP_SoundAdvancedDef, 154},
|
||||
};
|
||||
|
||||
#ifdef HAVE_OPENMPT
|
||||
|
@ -1513,6 +1517,7 @@ static menuitem_t OP_ScreenshotOptionsMenu[] =
|
|||
|
||||
{IT_STRING|IT_CVAR, NULL, "Region Optimizing", &cv_gif_optimize, 95},
|
||||
{IT_STRING|IT_CVAR, NULL, "Downscaling", &cv_gif_downscale, 100},
|
||||
{IT_STRING|IT_CVAR, NULL, "Local Color Table", &cv_gif_localcolortable, 105},
|
||||
|
||||
{IT_STRING|IT_CVAR, NULL, "Memory Level", &cv_zlib_memorya, 95},
|
||||
{IT_STRING|IT_CVAR, NULL, "Compression Level", &cv_zlib_levela, 100},
|
||||
|
@ -1523,13 +1528,14 @@ static menuitem_t OP_ScreenshotOptionsMenu[] =
|
|||
enum
|
||||
{
|
||||
op_screenshot_colorprofile = 1,
|
||||
op_screenshot_storagelocation = 3,
|
||||
op_screenshot_folder = 4,
|
||||
op_movie_folder = 11,
|
||||
op_screenshot_capture = 12,
|
||||
op_screenshot_gif_start = 13,
|
||||
op_screenshot_gif_end = 14,
|
||||
op_screenshot_apng_start = 15,
|
||||
op_screenshot_apng_end = 18,
|
||||
op_screenshot_gif_end = 15,
|
||||
op_screenshot_apng_start = 16,
|
||||
op_screenshot_apng_end = 19,
|
||||
};
|
||||
|
||||
static menuitem_t OP_EraseDataMenu[] =
|
||||
|
@ -1583,32 +1589,33 @@ static menuitem_t OP_ServerOptionsMenu[] =
|
|||
{IT_STRING | IT_CVAR, NULL, "Players required for exit", &cv_playersforexit, 96},
|
||||
{IT_STRING | IT_CVAR, NULL, "Starposts", &cv_coopstarposts, 101},
|
||||
{IT_STRING | IT_CVAR, NULL, "Life sharing", &cv_cooplives, 106},
|
||||
{IT_STRING | IT_CVAR, NULL, "Post-goal free roaming", &cv_exitmove, 111},
|
||||
|
||||
{IT_HEADER, NULL, "Race, Competition", NULL, 115},
|
||||
{IT_STRING | IT_CVAR, NULL, "Level completion countdown", &cv_countdowntime, 121},
|
||||
{IT_STRING | IT_CVAR, NULL, "Item Monitors", &cv_competitionboxes, 126},
|
||||
{IT_HEADER, NULL, "Race, Competition", NULL, 120},
|
||||
{IT_STRING | IT_CVAR, NULL, "Level completion countdown", &cv_countdowntime, 126},
|
||||
{IT_STRING | IT_CVAR, NULL, "Item Monitors", &cv_competitionboxes, 131},
|
||||
|
||||
{IT_HEADER, NULL, "Ringslinger (Match, CTF, Tag, H&S)", NULL, 135},
|
||||
{IT_STRING | IT_CVAR, NULL, "Time Limit", &cv_timelimit, 141},
|
||||
{IT_STRING | IT_CVAR, NULL, "Score Limit", &cv_pointlimit, 146},
|
||||
{IT_STRING | IT_CVAR, NULL, "Overtime on Tie", &cv_overtime, 151},
|
||||
{IT_STRING | IT_CVAR, NULL, "Player respawn delay", &cv_respawntime, 156},
|
||||
{IT_HEADER, NULL, "Ringslinger (Match, CTF, Tag, H&S)", NULL, 140},
|
||||
{IT_STRING | IT_CVAR, NULL, "Time Limit", &cv_timelimit, 146},
|
||||
{IT_STRING | IT_CVAR, NULL, "Score Limit", &cv_pointlimit, 151},
|
||||
{IT_STRING | IT_CVAR, NULL, "Overtime on Tie", &cv_overtime, 156},
|
||||
{IT_STRING | IT_CVAR, NULL, "Player respawn delay", &cv_respawntime, 161},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Item Monitors", &cv_matchboxes, 166},
|
||||
{IT_STRING | IT_CVAR, NULL, "Weapon Rings", &cv_specialrings, 171},
|
||||
{IT_STRING | IT_CVAR, NULL, "Power Stones", &cv_powerstones, 176},
|
||||
{IT_STRING | IT_CVAR, NULL, "Item Monitors", &cv_matchboxes, 171},
|
||||
{IT_STRING | IT_CVAR, NULL, "Weapon Rings", &cv_specialrings, 176},
|
||||
{IT_STRING | IT_CVAR, NULL, "Power Stones", &cv_powerstones, 181},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Flag respawn delay", &cv_flagtime, 186},
|
||||
{IT_STRING | IT_CVAR, NULL, "Hiding time", &cv_hidetime, 191},
|
||||
{IT_STRING | IT_CVAR, NULL, "Flag respawn delay", &cv_flagtime, 191},
|
||||
{IT_STRING | IT_CVAR, NULL, "Hiding time", &cv_hidetime, 196},
|
||||
|
||||
{IT_HEADER, NULL, "Teams", NULL, 200},
|
||||
{IT_STRING | IT_CVAR, NULL, "Autobalance sizes", &cv_autobalance, 206},
|
||||
{IT_STRING | IT_CVAR, NULL, "Scramble on Map Change", &cv_scrambleonchange, 211},
|
||||
{IT_HEADER, NULL, "Teams", NULL, 205},
|
||||
{IT_STRING | IT_CVAR, NULL, "Autobalance sizes", &cv_autobalance, 211},
|
||||
{IT_STRING | IT_CVAR, NULL, "Scramble on Map Change", &cv_scrambleonchange, 216},
|
||||
|
||||
#ifndef NONET
|
||||
{IT_HEADER, NULL, "Advanced", NULL, 220},
|
||||
{IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 226},
|
||||
{IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 240},
|
||||
{IT_HEADER, NULL, "Advanced", NULL, 225},
|
||||
{IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 231},
|
||||
{IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 245},
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -3026,7 +3033,8 @@ static void M_ChangeCvar(INT32 choice)
|
|||
|| !(currentMenu->menuitems[itemOn].status & IT_CV_INTEGERSTEP))
|
||||
{
|
||||
char s[20];
|
||||
sprintf(s,"%f",FIXED_TO_FLOAT(cv->value)+(choice)*(1.0f/16.0f));
|
||||
float n = FIXED_TO_FLOAT(cv->value)+(choice)*(1.0f/16.0f);
|
||||
sprintf(s,"%ld%s",(long)n,M_Ftrim(n));
|
||||
CV_Set(cv,s);
|
||||
}
|
||||
else
|
||||
|
@ -3756,6 +3764,12 @@ void M_SetupNextMenu(menu_t *menudef)
|
|||
hidetitlemap = false;
|
||||
}
|
||||
|
||||
// Guess I'll put this here, idk
|
||||
boolean M_MouseNeeded(void)
|
||||
{
|
||||
return (currentMenu == &MessageDef && currentMenu->prevMenu == &OP_ChangeControlsDef);
|
||||
}
|
||||
|
||||
//
|
||||
// M_Ticker
|
||||
//
|
||||
|
@ -3777,6 +3791,9 @@ void M_Ticker(void)
|
|||
if (--vidm_testingmode == 0)
|
||||
setmodeneeded = vidm_previousmode + 1;
|
||||
}
|
||||
|
||||
if (currentMenu == &OP_ScreenshotOptionsDef)
|
||||
M_SetupScreenshotMenu();
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -5594,7 +5611,8 @@ static void M_DrawNightsAttackMountains(void)
|
|||
static INT32 bgscrollx;
|
||||
INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
|
||||
patch_t *background = W_CachePatchName(curbgname, PU_PATCH);
|
||||
INT32 x = FixedInt(bgscrollx) % SHORT(background->width);
|
||||
INT16 w = SHORT(background->width);
|
||||
INT32 x = FixedInt(-bgscrollx) % w;
|
||||
INT32 y = BASEVIDHEIGHT - SHORT(background->height)*2;
|
||||
|
||||
if (vid.height != BASEVIDHEIGHT * dupz)
|
||||
|
@ -5602,11 +5620,13 @@ static void M_DrawNightsAttackMountains(void)
|
|||
V_DrawFill(0, y+50, vid.width, BASEVIDHEIGHT, V_SNAPTOLEFT|31);
|
||||
|
||||
V_DrawScaledPatch(x, y, V_SNAPTOLEFT, background);
|
||||
x += SHORT(background->width);
|
||||
x += w;
|
||||
if (x < BASEVIDWIDTH)
|
||||
V_DrawScaledPatch(x, y, V_SNAPTOLEFT, background);
|
||||
|
||||
bgscrollx -= (FRACUNIT/2);
|
||||
bgscrollx += (FRACUNIT/2);
|
||||
if (bgscrollx > w<<FRACBITS)
|
||||
bgscrollx &= 0xFFFF;
|
||||
}
|
||||
|
||||
// NiGHTS Attack foreground.
|
||||
|
@ -7223,18 +7243,33 @@ finishchecklist:
|
|||
}
|
||||
|
||||
#define NUMHINTS 5
|
||||
|
||||
static void M_EmblemHints(INT32 choice)
|
||||
{
|
||||
INT32 i;
|
||||
UINT32 local = 0;
|
||||
emblem_t *emblem;
|
||||
for (i = 0; i < numemblems; i++)
|
||||
{
|
||||
emblem = &emblemlocations[i];
|
||||
if (emblem->level != gamemap || emblem->type > ET_SKIN)
|
||||
continue;
|
||||
if (++local > NUMHINTS*2)
|
||||
break;
|
||||
}
|
||||
|
||||
(void)choice;
|
||||
SR_EmblemHintMenu[0].status = (M_SecretUnlocked(SECRET_ITEMFINDER)) ? (IT_CVAR|IT_STRING) : (IT_SECRET);
|
||||
SR_EmblemHintMenu[0].status = (local > NUMHINTS*2) ? (IT_STRING | IT_ARROWS) : (IT_DISABLED);
|
||||
SR_EmblemHintMenu[1].status = (M_SecretUnlocked(SECRET_ITEMFINDER)) ? (IT_CVAR|IT_STRING) : (IT_SECRET);
|
||||
hintpage = 1;
|
||||
M_SetupNextMenu(&SR_EmblemHintDef);
|
||||
itemOn = 1; // always start on back.
|
||||
itemOn = 2; // always start on back.
|
||||
}
|
||||
|
||||
static void M_DrawEmblemHints(void)
|
||||
{
|
||||
INT32 i, j = 0, x, y;
|
||||
UINT32 collected = 0, local = 0;
|
||||
INT32 i, j = 0, x, y, left_hints = NUMHINTS, pageflag = 0;
|
||||
UINT32 collected = 0, totalemblems = 0, local = 0;
|
||||
emblem_t *emblem;
|
||||
const char *hint;
|
||||
|
||||
|
@ -7243,13 +7278,35 @@ static void M_DrawEmblemHints(void)
|
|||
emblem = &emblemlocations[i];
|
||||
if (emblem->level != gamemap || emblem->type > ET_SKIN)
|
||||
continue;
|
||||
if (++local >= NUMHINTS*2)
|
||||
break;
|
||||
|
||||
local++;
|
||||
}
|
||||
|
||||
x = (local > NUMHINTS ? 4 : 12);
|
||||
y = 8;
|
||||
|
||||
if (local > NUMHINTS){
|
||||
if (local > ((hintpage-1)*NUMHINTS*2) && local < ((hintpage)*NUMHINTS*2)){
|
||||
if (NUMHINTS % 2 == 1)
|
||||
left_hints = (local - ((hintpage-1)*NUMHINTS*2) + 1) / 2;
|
||||
else
|
||||
left_hints = (local - ((hintpage-1)*NUMHINTS*2)) / 2;
|
||||
}else{
|
||||
left_hints = NUMHINTS;
|
||||
}
|
||||
}
|
||||
|
||||
if (local > NUMHINTS*2){
|
||||
if (itemOn == 0){
|
||||
pageflag = V_YELLOWMAP;
|
||||
}
|
||||
V_DrawString(currentMenu->x + 40, currentMenu->y + 10, pageflag, va("%d of %d",hintpage, local/(NUMHINTS*2) + 1));
|
||||
}
|
||||
|
||||
// If there are more than 1 page's but less than 2 pages' worth of emblems on the last possible page,
|
||||
// put half (rounded up) of the hints on the left, and half (rounded down) on the right
|
||||
|
||||
|
||||
if (!local)
|
||||
V_DrawCenteredString(160, 48, V_YELLOWMAP, "No hidden emblems on this map.");
|
||||
else for (i = 0; i < numemblems; i++)
|
||||
|
@ -7258,42 +7315,80 @@ static void M_DrawEmblemHints(void)
|
|||
if (emblem->level != gamemap || emblem->type > ET_SKIN)
|
||||
continue;
|
||||
|
||||
if (emblem->collected)
|
||||
{
|
||||
collected = V_GREENMAP;
|
||||
V_DrawMappedPatch(x, y+4, 0, W_CachePatchName(M_GetEmblemPatch(emblem, false), PU_PATCH),
|
||||
R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_CACHE));
|
||||
}
|
||||
else
|
||||
{
|
||||
collected = 0;
|
||||
V_DrawScaledPatch(x, y+4, 0, W_CachePatchName("NEEDIT", PU_PATCH));
|
||||
}
|
||||
totalemblems++;
|
||||
|
||||
if (emblem->hint[0])
|
||||
hint = emblem->hint;
|
||||
else
|
||||
hint = M_GetText("No hint available for this emblem.");
|
||||
hint = V_WordWrap(40, BASEVIDWIDTH-12, 0, hint);
|
||||
if (local > NUMHINTS)
|
||||
V_DrawThinString(x+28, y, V_RETURN8|V_ALLOWLOWERCASE|collected, hint);
|
||||
else
|
||||
V_DrawString(x+28, y, V_RETURN8|V_ALLOWLOWERCASE|collected, hint);
|
||||
if (totalemblems >= ((hintpage-1)*(NUMHINTS*2) + 1) && totalemblems < (hintpage*NUMHINTS*2)+1){
|
||||
|
||||
y += 28;
|
||||
if (emblem->collected)
|
||||
{
|
||||
collected = V_GREENMAP;
|
||||
V_DrawMappedPatch(x, y+4, 0, W_CachePatchName(M_GetEmblemPatch(emblem, false), PU_PATCH),
|
||||
R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_CACHE));
|
||||
}
|
||||
else
|
||||
{
|
||||
collected = 0;
|
||||
V_DrawScaledPatch(x, y+4, 0, W_CachePatchName("NEEDIT", PU_PATCH));
|
||||
}
|
||||
|
||||
if (++j == NUMHINTS)
|
||||
{
|
||||
x = 4+(BASEVIDWIDTH/2);
|
||||
y = 8;
|
||||
if (emblem->hint[0])
|
||||
hint = emblem->hint;
|
||||
else
|
||||
hint = M_GetText("No hint available for this emblem.");
|
||||
hint = V_WordWrap(40, BASEVIDWIDTH-12, 0, hint);
|
||||
//always draw tiny if we have more than NUMHINTS*2, visually more appealing
|
||||
if (local > NUMHINTS)
|
||||
V_DrawThinString(x+28, y, V_RETURN8|V_ALLOWLOWERCASE|collected, hint);
|
||||
else
|
||||
V_DrawString(x+28, y, V_RETURN8|V_ALLOWLOWERCASE|collected, hint);
|
||||
|
||||
y += 28;
|
||||
|
||||
// If there are more than 1 page's but less than 2 pages' worth of emblems on the last possible page,
|
||||
// put half (rounded up) of the hints on the left, and half (rounded down) on the right
|
||||
|
||||
if (++j == left_hints)
|
||||
{
|
||||
x = 4+(BASEVIDWIDTH/2);
|
||||
y = 8;
|
||||
}
|
||||
else if (j >= NUMHINTS*2)
|
||||
break;
|
||||
}
|
||||
else if (j >= NUMHINTS*2)
|
||||
break;
|
||||
}
|
||||
|
||||
M_DrawGenericMenu();
|
||||
}
|
||||
|
||||
|
||||
static void M_HandleEmblemHints(INT32 choice)
|
||||
{
|
||||
INT32 i;
|
||||
emblem_t *emblem;
|
||||
UINT32 stageemblems = 0;
|
||||
|
||||
for (i = 0; i < numemblems; i++)
|
||||
{
|
||||
emblem = &emblemlocations[i];
|
||||
if (emblem->level != gamemap || emblem->type > ET_SKIN)
|
||||
continue;
|
||||
|
||||
stageemblems++;
|
||||
}
|
||||
|
||||
|
||||
if (choice == 0){
|
||||
if (hintpage > 1){
|
||||
hintpage--;
|
||||
}
|
||||
}else{
|
||||
if (hintpage < ((stageemblems-1)/(NUMHINTS*2) + 1)){
|
||||
hintpage++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*static void M_DrawSkyRoom(void)
|
||||
{
|
||||
INT32 i, y = 0;
|
||||
|
@ -10626,8 +10721,8 @@ static void M_ServerOptions(INT32 choice)
|
|||
OP_ServerOptionsMenu[ 2].status = IT_GRAYEDOUT; // Max players
|
||||
OP_ServerOptionsMenu[ 3].status = IT_GRAYEDOUT; // Allow add-on downloading
|
||||
OP_ServerOptionsMenu[ 4].status = IT_GRAYEDOUT; // Allow players to join
|
||||
OP_ServerOptionsMenu[34].status = IT_GRAYEDOUT; // Master server
|
||||
OP_ServerOptionsMenu[35].status = IT_GRAYEDOUT; // Attempts to resynchronise
|
||||
OP_ServerOptionsMenu[35].status = IT_GRAYEDOUT; // Master server
|
||||
OP_ServerOptionsMenu[36].status = IT_GRAYEDOUT; // Attempts to resynchronise
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -10635,10 +10730,10 @@ static void M_ServerOptions(INT32 choice)
|
|||
OP_ServerOptionsMenu[ 2].status = IT_STRING | IT_CVAR;
|
||||
OP_ServerOptionsMenu[ 3].status = IT_STRING | IT_CVAR;
|
||||
OP_ServerOptionsMenu[ 4].status = IT_STRING | IT_CVAR;
|
||||
OP_ServerOptionsMenu[34].status = (netgame
|
||||
OP_ServerOptionsMenu[35].status = (netgame
|
||||
? IT_GRAYEDOUT
|
||||
: (IT_STRING | IT_CVAR | IT_CV_STRING));
|
||||
OP_ServerOptionsMenu[35].status = IT_STRING | IT_CVAR;
|
||||
OP_ServerOptionsMenu[36].status = IT_STRING | IT_CVAR;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -10830,7 +10925,6 @@ static void M_HandleConnectIP(INT32 choice)
|
|||
default: // otherwise do nothing.
|
||||
break;
|
||||
}
|
||||
break; // don't check for typed keys
|
||||
}
|
||||
|
||||
if (l >= 28-1)
|
||||
|
@ -11334,9 +11428,27 @@ static void M_ScreenshotOptions(INT32 choice)
|
|||
Screenshot_option_Onchange();
|
||||
Moviemode_mode_Onchange();
|
||||
|
||||
M_SetupScreenshotMenu();
|
||||
M_SetupNextMenu(&OP_ScreenshotOptionsDef);
|
||||
}
|
||||
|
||||
static void M_SetupScreenshotMenu(void)
|
||||
{
|
||||
menuitem_t *item = &OP_ScreenshotOptionsMenu[op_screenshot_colorprofile];
|
||||
|
||||
#ifdef HWRENDER
|
||||
// Hide some options based on render mode
|
||||
if (rendermode == render_opengl)
|
||||
{
|
||||
item->status = IT_GRAYEDOUT;
|
||||
if ((currentMenu == &OP_ScreenshotOptionsDef) && (itemOn == op_screenshot_colorprofile)) // Can't select that
|
||||
itemOn = op_screenshot_storagelocation;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
item->status = (IT_STRING | IT_CVAR);
|
||||
}
|
||||
|
||||
// =============
|
||||
// JOYSTICK MENU
|
||||
// =============
|
||||
|
@ -12279,6 +12391,15 @@ static void M_HandleVideoMode(INT32 ch)
|
|||
static void M_DrawScreenshotMenu(void)
|
||||
{
|
||||
M_DrawGenericScrollMenu();
|
||||
#ifdef HWRENDER
|
||||
if ((rendermode == render_opengl) && (itemOn < 7)) // where it starts to go offscreen; change this number if you change the layout of the screenshot menu
|
||||
{
|
||||
INT32 y = currentMenu->y+currentMenu->menuitems[op_screenshot_colorprofile].alphaKey*2;
|
||||
if (itemOn == 6)
|
||||
y -= 10;
|
||||
V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, y, V_REDMAP, "Yes");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// ===============
|
||||
|
|
|
@ -322,6 +322,9 @@ typedef struct menu_s
|
|||
void M_SetupNextMenu(menu_t *menudef);
|
||||
void M_ClearMenus(boolean callexitmenufunc);
|
||||
|
||||
// Maybe this goes here????? Who knows.
|
||||
boolean M_MouseNeeded(void);
|
||||
|
||||
extern menu_t *currentMenu;
|
||||
|
||||
extern menu_t MainDef;
|
||||
|
|
73
src/m_misc.c
73
src/m_misc.c
|
@ -1594,16 +1594,19 @@ boolean M_ScreenshotResponder(event_t *ev)
|
|||
// M_StartupLocale.
|
||||
// Sets up gettext to translate SRB2's strings.
|
||||
#ifdef GETTEXT
|
||||
#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)
|
||||
#define GETTEXTDOMAIN1 "/usr/share/locale"
|
||||
#define GETTEXTDOMAIN2 "/usr/local/share/locale"
|
||||
#elif defined (_WIN32)
|
||||
#define GETTEXTDOMAIN1 "."
|
||||
#endif
|
||||
#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)
|
||||
#define GETTEXTDOMAIN1 "/usr/share/locale"
|
||||
#define GETTEXTDOMAIN2 "/usr/local/share/locale"
|
||||
#elif defined (_WIN32)
|
||||
#define GETTEXTDOMAIN1 "."
|
||||
#endif
|
||||
#endif // GETTEXT
|
||||
|
||||
void M_StartupLocale(void)
|
||||
{
|
||||
#ifdef GETTEXT
|
||||
char *textdomhandle = NULL;
|
||||
#endif //GETTEXT
|
||||
|
||||
CONS_Printf("M_StartupLocale...\n");
|
||||
|
||||
|
@ -1612,6 +1615,7 @@ void M_StartupLocale(void)
|
|||
// Do not set numeric locale as that affects atof
|
||||
setlocale(LC_NUMERIC, "C");
|
||||
|
||||
#ifdef GETTEXT
|
||||
// FIXME: global name define anywhere?
|
||||
#ifdef GETTEXTDOMAIN1
|
||||
textdomhandle = bindtextdomain("srb2", GETTEXTDOMAIN1);
|
||||
|
@ -1632,8 +1636,8 @@ void M_StartupLocale(void)
|
|||
textdomain("srb2");
|
||||
else
|
||||
CONS_Printf("Could not find locale text domain!\n");
|
||||
#endif //GETTEXT
|
||||
}
|
||||
#endif
|
||||
|
||||
// ==========================================================================
|
||||
// MISC STRING FUNCTIONS
|
||||
|
@ -2571,3 +2575,58 @@ void M_MkdirEach(const char *path, int start, int mode)
|
|||
{
|
||||
M_MkdirEachUntil(path, start, -1, mode);
|
||||
}
|
||||
|
||||
int M_JumpWord(const char *line)
|
||||
{
|
||||
int c;
|
||||
|
||||
c = line[0];
|
||||
|
||||
if (isspace(c))
|
||||
return strspn(line, " ");
|
||||
else if (ispunct(c))
|
||||
return strspn(line, PUNCTUATION);
|
||||
else
|
||||
{
|
||||
if (isspace(line[1]))
|
||||
return 1 + strspn(&line[1], " ");
|
||||
else
|
||||
return strcspn(line, " "PUNCTUATION);
|
||||
}
|
||||
}
|
||||
|
||||
int M_JumpWordReverse(const char *line, int offset)
|
||||
{
|
||||
int (*is)(int);
|
||||
int c;
|
||||
c = line[--offset];
|
||||
if (isspace(c))
|
||||
is = isspace;
|
||||
else if (ispunct(c))
|
||||
is = ispunct;
|
||||
else
|
||||
is = isalnum;
|
||||
c = (*is)(line[offset]);
|
||||
while (offset > 0 &&
|
||||
(*is)(line[offset - 1]) == c)
|
||||
offset--;
|
||||
return offset;
|
||||
}
|
||||
|
||||
const char * M_Ftrim (double f)
|
||||
{
|
||||
static char dig[9];/* "0." + 6 digits (6 is printf's default) */
|
||||
int i;
|
||||
/* I know I said it's the default, but just in case... */
|
||||
sprintf(dig, "%.6f", fabs(modf(f, &f)));
|
||||
/* trim trailing zeroes */
|
||||
for (i = strlen(dig)-1; dig[i] == '0'; --i)
|
||||
;
|
||||
if (dig[i] == '.')/* :NOTHING: */
|
||||
return "";
|
||||
else
|
||||
{
|
||||
dig[i + 1] = '\0';
|
||||
return &dig[1];/* skip the 0 */
|
||||
}
|
||||
}
|
||||
|
|
14
src/m_misc.h
14
src/m_misc.h
|
@ -101,6 +101,20 @@ boolean M_IsPathAbsolute (const char *path);
|
|||
void M_MkdirEach (const char *path, int start, int mode);
|
||||
void M_MkdirEachUntil (const char *path, int start, int end, int mode);
|
||||
|
||||
/* Return offset to the first word in a string. */
|
||||
/* E.g. cursor += M_JumpWord(line + cursor); */
|
||||
int M_JumpWord (const char *s);
|
||||
|
||||
/* Return index of the last word behind offset bytes in a string. */
|
||||
/* E.g. cursor = M_JumpWordReverse(line, cursor); */
|
||||
int M_JumpWordReverse (const char *line, int offset);
|
||||
|
||||
/*
|
||||
Return dot and then the fractional part of a float, without
|
||||
trailing zeros, or "" if the fractional part is zero.
|
||||
*/
|
||||
const char * M_Ftrim (double);
|
||||
|
||||
// counting bits, for weapon ammo code, usually
|
||||
FUNCMATH UINT8 M_CountBits(UINT32 num, UINT8 size);
|
||||
|
||||
|
|
110
src/mserv.c
110
src/mserv.c
|
@ -323,13 +323,9 @@ static INT32 GetServersList(void)
|
|||
//
|
||||
// MS_Connect()
|
||||
//
|
||||
static INT32 MS_Connect(const char *ip_addr, const char *str_port, INT32 async)
|
||||
#ifndef NONET
|
||||
static INT32 MS_SubConnect(const char *ip_addr, const char *str_port, INT32 async, struct sockaddr *bindaddr, socklen_t bindaddrlen)
|
||||
{
|
||||
#ifdef NONET
|
||||
(void)ip_addr;
|
||||
(void)str_port;
|
||||
(void)async;
|
||||
#else
|
||||
struct my_addrinfo *ai, *runp, hints;
|
||||
int gaie;
|
||||
|
||||
|
@ -356,50 +352,100 @@ static INT32 MS_Connect(const char *ip_addr, const char *str_port, INT32 async)
|
|||
socket_fd = socket(runp->ai_family, runp->ai_socktype, runp->ai_protocol);
|
||||
if (socket_fd != (SOCKET_TYPE)ERRSOCKET)
|
||||
{
|
||||
if (async) // do asynchronous connection
|
||||
if (!bindaddr || bind(socket_fd, bindaddr, bindaddrlen) == 0)
|
||||
{
|
||||
if (async) // do asynchronous connection
|
||||
{
|
||||
#ifdef FIONBIO
|
||||
#ifdef WATTCP
|
||||
char res = 1;
|
||||
char res = 1;
|
||||
#else
|
||||
unsigned long res = 1;
|
||||
unsigned long res = 1;
|
||||
#endif
|
||||
|
||||
ioctl(socket_fd, FIONBIO, &res);
|
||||
ioctl(socket_fd, FIONBIO, &res);
|
||||
#endif
|
||||
|
||||
if (connect(socket_fd, runp->ai_addr, (socklen_t)runp->ai_addrlen) == ERRSOCKET)
|
||||
{
|
||||
#ifdef _WIN32 // humm, on win32/win64 it doesn't work with EINPROGRESS (stupid windows)
|
||||
if (WSAGetLastError() != WSAEWOULDBLOCK)
|
||||
#else
|
||||
if (errno != EINPROGRESS)
|
||||
#endif
|
||||
if (connect(socket_fd, runp->ai_addr, (socklen_t)runp->ai_addrlen) == ERRSOCKET)
|
||||
{
|
||||
con_state = MSCS_FAILED;
|
||||
CloseConnection();
|
||||
I_freeaddrinfo(ai);
|
||||
return MS_CONNECT_ERROR;
|
||||
#ifdef _WIN32 // humm, on win32/win64 it doesn't work with EINPROGRESS (stupid windows)
|
||||
if (WSAGetLastError() != WSAEWOULDBLOCK)
|
||||
#else
|
||||
if (errno != EINPROGRESS)
|
||||
#endif
|
||||
{
|
||||
con_state = MSCS_FAILED;
|
||||
CloseConnection();
|
||||
I_freeaddrinfo(ai);
|
||||
return MS_CONNECT_ERROR;
|
||||
}
|
||||
}
|
||||
con_state = MSCS_WAITING;
|
||||
FD_ZERO(&wset);
|
||||
FD_SET(socket_fd, &wset);
|
||||
select_timeout.tv_sec = 0, select_timeout.tv_usec = 0;
|
||||
I_freeaddrinfo(ai);
|
||||
return 0;
|
||||
}
|
||||
else if (connect(socket_fd, runp->ai_addr, (socklen_t)runp->ai_addrlen) != ERRSOCKET)
|
||||
{
|
||||
I_freeaddrinfo(ai);
|
||||
return 0;
|
||||
}
|
||||
con_state = MSCS_WAITING;
|
||||
FD_ZERO(&wset);
|
||||
FD_SET(socket_fd, &wset);
|
||||
select_timeout.tv_sec = 0, select_timeout.tv_usec = 0;
|
||||
I_freeaddrinfo(ai);
|
||||
return 0;
|
||||
}
|
||||
else if (connect(socket_fd, runp->ai_addr, (socklen_t)runp->ai_addrlen) != ERRSOCKET)
|
||||
close(socket_fd);
|
||||
}
|
||||
runp = runp->ai_next;
|
||||
}
|
||||
I_freeaddrinfo(ai);
|
||||
return MS_CONNECT_ERROR;
|
||||
}
|
||||
#endif/*NONET xd*/
|
||||
|
||||
static INT32 MS_Connect(const char *ip_addr, const char *str_port, INT32 async)
|
||||
{
|
||||
#ifdef NONET
|
||||
(void)ip_addr;
|
||||
(void)str_port;
|
||||
(void)async;
|
||||
return MS_CONNECT_ERROR;
|
||||
#else
|
||||
const char *lhost;
|
||||
struct my_addrinfo hints;
|
||||
struct my_addrinfo *ai, *aip;
|
||||
int c;
|
||||
if (M_CheckParm("-bindaddr") && ( lhost = M_GetNextParm() ))
|
||||
{
|
||||
memset (&hints, 0x00, sizeof(hints));
|
||||
#ifdef AI_ADDRCONFIG
|
||||
hints.ai_flags = AI_ADDRCONFIG;
|
||||
#endif
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
if (( c = I_getaddrinfo(lhost, 0, &hints, &ai) ) != 0)
|
||||
{
|
||||
CONS_Printf(
|
||||
"mserv.c: bind to %s: %s\n",
|
||||
lhost,
|
||||
gai_strerror(c));
|
||||
return MS_GETHOSTBYNAME_ERROR;
|
||||
}
|
||||
for (aip = ai; aip; aip = aip->ai_next)
|
||||
{
|
||||
c = MS_SubConnect(ip_addr, str_port, async, aip->ai_addr, aip->ai_addrlen);
|
||||
if (c == 0)
|
||||
{
|
||||
I_freeaddrinfo(ai);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
runp = runp->ai_next;
|
||||
I_freeaddrinfo(ai);
|
||||
return c;
|
||||
}
|
||||
I_freeaddrinfo(ai);
|
||||
#endif
|
||||
return MS_CONNECT_ERROR;
|
||||
else
|
||||
return MS_SubConnect(ip_addr, str_port, async, 0, 0);
|
||||
#endif/*NONET xd*/
|
||||
}
|
||||
|
||||
#define NUM_LIST_SERVER MAXSERVERLIST
|
||||
|
|
|
@ -747,6 +747,9 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed
|
|||
if (player->bot)
|
||||
continue; // ignore bots
|
||||
|
||||
if (player->quittime)
|
||||
continue; // Ignore uncontrolled bodies
|
||||
|
||||
if (dist > 0
|
||||
&& P_AproxDistance(P_AproxDistance(player->mo->x - actor->x, player->mo->y - actor->y), player->mo->z - actor->z) > dist)
|
||||
continue; // Too far away
|
||||
|
@ -5178,6 +5181,8 @@ void A_SignPlayer(mobj_t *actor)
|
|||
|
||||
if (signcolor)
|
||||
;
|
||||
else if (!skin->sprites[SPR2_SIGN].numframes)
|
||||
signcolor = facecolor;
|
||||
else if ((actor->target->player->skincolor == skin->prefcolor) && (skin->prefoppositecolor)) // Set it as the skin's preferred oppositecolor?
|
||||
signcolor = skin->prefoppositecolor;
|
||||
else if (actor->target->player->skincolor) // Set the sign to be an appropriate background color for this player's skincolor.
|
||||
|
@ -5188,33 +5193,25 @@ void A_SignPlayer(mobj_t *actor)
|
|||
else if (locvar1 != -3) // set to a defined skin
|
||||
{
|
||||
// I turned this function into a fucking mess. I'm so sorry. -Lach
|
||||
if (locvar1 == -2) // next skin
|
||||
if (locvar1 == -2) // random skin
|
||||
{
|
||||
#define skincheck(num) (player ? !R_SkinUsable(player-players, num) : skins[num].availability > 0)
|
||||
player_t *player = actor->target ? actor->target->player : NULL;
|
||||
UINT8 skinnum;
|
||||
#define skincheck(num) (player ? !R_SkinUsable(player-players, num) : skins[num].availability > 0)
|
||||
if (ov->skin == NULL) // pick a random skin to start with!
|
||||
UINT8 skincount = 0;
|
||||
for (skinnum = 0; skinnum < numskins; skinnum++)
|
||||
if (!skincheck(skinnum))
|
||||
skincount++;
|
||||
skinnum = P_RandomKey(skincount);
|
||||
for (skincount = 0; skincount < numskins; skincount++)
|
||||
{
|
||||
UINT8 skincount = 0;
|
||||
for (skincount = 0; skincount < numskins; skincount++)
|
||||
if (!skincheck(skincount))
|
||||
skincount++;
|
||||
skinnum = P_RandomKey(skincount);
|
||||
for (skincount = 0; skincount < numskins; skincount++)
|
||||
{
|
||||
if (skincount > skinnum)
|
||||
break;
|
||||
if (skincheck(skincount))
|
||||
skinnum++;
|
||||
}
|
||||
if (skincount > skinnum)
|
||||
break;
|
||||
if (skincheck(skincount))
|
||||
skinnum++;
|
||||
}
|
||||
else // otherwise, advance 1 skin
|
||||
{
|
||||
skinnum = (skin_t*)ov->skin-skins;
|
||||
while ((skinnum = (skinnum + 1) % numskins) && skincheck(skinnum));
|
||||
}
|
||||
#undef skincheck
|
||||
skin = &skins[skinnum];
|
||||
#undef skincheck
|
||||
}
|
||||
else // specific skin
|
||||
skin = &skins[locvar1];
|
||||
|
@ -5222,22 +5219,37 @@ void A_SignPlayer(mobj_t *actor)
|
|||
facecolor = skin->prefcolor;
|
||||
if (signcolor)
|
||||
;
|
||||
else if (!skin->sprites[SPR2_SIGN].numframes)
|
||||
signcolor = facecolor;
|
||||
else if (skin->prefoppositecolor)
|
||||
signcolor = skin->prefoppositecolor;
|
||||
else if (facecolor)
|
||||
signcolor = Color_Opposite[facecolor - 1][0];
|
||||
}
|
||||
|
||||
if (skin && skin->sprites[SPR2_SIGN].numframes) // player face
|
||||
if (skin)
|
||||
{
|
||||
ov->color = facecolor;
|
||||
ov->skin = skin;
|
||||
P_SetMobjState(ov, actor->info->seestate); // S_PLAY_SIGN
|
||||
if (skin->sprites[SPR2_SIGN].numframes) // player face
|
||||
{
|
||||
ov->color = facecolor;
|
||||
ov->skin = skin;
|
||||
if ((statenum_t)(ov->state-states) != actor->info->seestate)
|
||||
P_SetMobjState(ov, actor->info->seestate); // S_PLAY_SIGN
|
||||
}
|
||||
else // CLEAR! sign
|
||||
{
|
||||
ov->color = SKINCOLOR_NONE;
|
||||
ov->skin = NULL; // needs to be NULL in the case of SF_HIRES characters
|
||||
if ((statenum_t)(ov->state-states) != actor->info->missilestate)
|
||||
P_SetMobjState(ov, actor->info->missilestate); // S_CLEARSIGN
|
||||
}
|
||||
}
|
||||
else // Eggman face
|
||||
{
|
||||
ov->color = SKINCOLOR_NONE;
|
||||
P_SetMobjState(ov, actor->info->meleestate); // S_EGGMANSIGN
|
||||
ov->skin = NULL;
|
||||
if ((statenum_t)(ov->state-states) != actor->info->meleestate)
|
||||
P_SetMobjState(ov, actor->info->meleestate); // S_EGGMANSIGN
|
||||
if (!signcolor)
|
||||
signcolor = SKINCOLOR_CARBON;
|
||||
}
|
||||
|
|
206
src/p_inter.c
206
src/p_inter.c
|
@ -433,7 +433,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
|| special->state == &states[S_FANG_BOUNCE4]
|
||||
|| special->state == &states[S_FANG_PINCHBOUNCE3]
|
||||
|| special->state == &states[S_FANG_PINCHBOUNCE4])
|
||||
&& P_MobjFlip(special)*((special->z + special->height/2) - (toucher->z - toucher->height/2)) > (special->height/4))
|
||||
&& P_MobjFlip(special)*((special->z + special->height/2) - (toucher->z + toucher->height/2)) > (toucher->height/2))
|
||||
{
|
||||
P_DamageMobj(toucher, special, special, 1, 0);
|
||||
P_SetTarget(&special->tracer, toucher);
|
||||
|
@ -1428,98 +1428,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
// Misc touchables //
|
||||
// *************** //
|
||||
case MT_STARPOST:
|
||||
if (player->bot)
|
||||
return;
|
||||
// In circuit, player must have touched all previous starposts
|
||||
if (circuitmap
|
||||
&& special->health - player->starpostnum > 1)
|
||||
{
|
||||
// blatant reuse of a variable that's normally unused in circuit
|
||||
if (!player->tossdelay)
|
||||
S_StartSound(toucher, sfx_lose);
|
||||
player->tossdelay = 3;
|
||||
return;
|
||||
}
|
||||
|
||||
// We could technically have 91.1 Star Posts. 90 is cleaner.
|
||||
if (special->health > 90)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Bad Starpost Number!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (player->starpostnum >= special->health)
|
||||
return; // Already hit this post
|
||||
|
||||
if (cv_coopstarposts.value && G_GametypeUsesCoopStarposts() && (netgame || multiplayer))
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i])
|
||||
{
|
||||
if (players[i].bot) // ignore dumb, stupid tails
|
||||
continue;
|
||||
|
||||
players[i].starposttime = leveltime;
|
||||
players[i].starpostx = player->mo->x>>FRACBITS;
|
||||
players[i].starposty = player->mo->y>>FRACBITS;
|
||||
players[i].starpostz = special->z>>FRACBITS;
|
||||
players[i].starpostangle = special->angle;
|
||||
players[i].starpostscale = player->mo->destscale;
|
||||
if (special->flags2 & MF2_OBJECTFLIP)
|
||||
{
|
||||
players[i].starpostscale *= -1;
|
||||
players[i].starpostz += special->height>>FRACBITS;
|
||||
}
|
||||
players[i].starpostnum = special->health;
|
||||
|
||||
if (cv_coopstarposts.value == 2 && (players[i].playerstate == PST_DEAD || players[i].spectator) && P_GetLives(&players[i]))
|
||||
P_SpectatorJoinGame(&players[i]); //players[i].playerstate = PST_REBORN;
|
||||
}
|
||||
}
|
||||
S_StartSound(NULL, special->info->painsound);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Save the player's time and position.
|
||||
player->starposttime = leveltime;
|
||||
player->starpostx = toucher->x>>FRACBITS;
|
||||
player->starposty = toucher->y>>FRACBITS;
|
||||
player->starpostz = special->z>>FRACBITS;
|
||||
player->starpostangle = special->angle;
|
||||
player->starpostscale = player->mo->destscale;
|
||||
if (special->flags2 & MF2_OBJECTFLIP)
|
||||
{
|
||||
player->starpostscale *= -1;
|
||||
player->starpostz += special->height>>FRACBITS;
|
||||
}
|
||||
player->starpostnum = special->health;
|
||||
S_StartSound(toucher, special->info->painsound);
|
||||
}
|
||||
|
||||
P_ClearStarPost(special->health);
|
||||
|
||||
// Find all starposts in the level with this value - INCLUDING this one!
|
||||
if (!(netgame && circuitmap && player != &players[consoleplayer]))
|
||||
{
|
||||
thinker_t *th;
|
||||
mobj_t *mo2;
|
||||
|
||||
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
|
||||
{
|
||||
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
|
||||
continue;
|
||||
|
||||
mo2 = (mobj_t *)th;
|
||||
|
||||
if (mo2->type != MT_STARPOST)
|
||||
continue;
|
||||
if (mo2->health != special->health)
|
||||
continue;
|
||||
|
||||
P_SetMobjState(mo2, mo2->info->painstate);
|
||||
}
|
||||
}
|
||||
P_TouchStarPost(special, player, special->spawnpoint && (special->spawnpoint->options & MTF_OBJECTSPECIAL));
|
||||
return;
|
||||
|
||||
case MT_FAKEMOBILE:
|
||||
|
@ -1869,6 +1778,113 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
|
||||
S_StartSound(toucher, special->info->deathsound); // was NULL, but changed to player so you could hear others pick up rings
|
||||
P_KillMobj(special, NULL, toucher, 0);
|
||||
special->shadowscale = 0;
|
||||
}
|
||||
|
||||
/** Saves a player's level progress at a star post
|
||||
*
|
||||
* \param post The star post to trigger
|
||||
* \param player The player that should receive the checkpoint
|
||||
* \param snaptopost If true, the respawn point will use the star post's position, otherwise player x/y and star post z
|
||||
*/
|
||||
void P_TouchStarPost(mobj_t *post, player_t *player, boolean snaptopost)
|
||||
{
|
||||
size_t i;
|
||||
mobj_t *toucher = player->mo;
|
||||
mobj_t *checkbase = snaptopost ? post : toucher;
|
||||
|
||||
if (player->bot)
|
||||
return;
|
||||
// In circuit, player must have touched all previous starposts
|
||||
if (circuitmap
|
||||
&& post->health - player->starpostnum > 1)
|
||||
{
|
||||
// blatant reuse of a variable that's normally unused in circuit
|
||||
if (!player->tossdelay)
|
||||
S_StartSound(toucher, sfx_lose);
|
||||
player->tossdelay = 3;
|
||||
return;
|
||||
}
|
||||
|
||||
// With the parameter + angle setup, we can go up to 1365 star posts. Who needs that many?
|
||||
if (post->health > 1365)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Bad Starpost Number!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (player->starpostnum >= post->health)
|
||||
return; // Already hit this post
|
||||
|
||||
if (cv_coopstarposts.value && G_GametypeUsesCoopStarposts() && (netgame || multiplayer))
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i])
|
||||
{
|
||||
if (players[i].bot) // ignore dumb, stupid tails
|
||||
continue;
|
||||
|
||||
players[i].starposttime = leveltime;
|
||||
players[i].starpostx = checkbase->x>>FRACBITS;
|
||||
players[i].starposty = checkbase->y>>FRACBITS;
|
||||
players[i].starpostz = post->z>>FRACBITS;
|
||||
players[i].starpostangle = post->angle;
|
||||
players[i].starpostscale = player->mo->destscale;
|
||||
if (post->flags2 & MF2_OBJECTFLIP)
|
||||
{
|
||||
players[i].starpostscale *= -1;
|
||||
players[i].starpostz += post->height>>FRACBITS;
|
||||
}
|
||||
players[i].starpostnum = post->health;
|
||||
|
||||
if (cv_coopstarposts.value == 2 && (players[i].playerstate == PST_DEAD || players[i].spectator) && P_GetLives(&players[i]))
|
||||
P_SpectatorJoinGame(&players[i]); //players[i].playerstate = PST_REBORN;
|
||||
}
|
||||
}
|
||||
S_StartSound(NULL, post->info->painsound);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Save the player's time and position.
|
||||
player->starposttime = leveltime;
|
||||
player->starpostx = checkbase->x>>FRACBITS;
|
||||
player->starposty = checkbase->y>>FRACBITS;
|
||||
player->starpostz = post->z>>FRACBITS;
|
||||
player->starpostangle = post->angle;
|
||||
player->starpostscale = player->mo->destscale;
|
||||
if (post->flags2 & MF2_OBJECTFLIP)
|
||||
{
|
||||
player->starpostscale *= -1;
|
||||
player->starpostz += post->height>>FRACBITS;
|
||||
}
|
||||
player->starpostnum = post->health;
|
||||
S_StartSound(toucher, post->info->painsound);
|
||||
}
|
||||
|
||||
P_ClearStarPost(post->health);
|
||||
|
||||
// Find all starposts in the level with this value - INCLUDING this one!
|
||||
if (!(netgame && circuitmap && player != &players[consoleplayer]))
|
||||
{
|
||||
thinker_t *th;
|
||||
mobj_t *mo2;
|
||||
|
||||
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
|
||||
{
|
||||
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
|
||||
continue;
|
||||
|
||||
mo2 = (mobj_t *)th;
|
||||
|
||||
if (mo2->type != MT_STARPOST)
|
||||
continue;
|
||||
if (mo2->health != post->health)
|
||||
continue;
|
||||
|
||||
P_SetMobjState(mo2, mo2->info->painstate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Prints death messages relating to a dying or hit player.
|
||||
|
@ -2256,9 +2272,9 @@ void P_CheckSurvivors(void)
|
|||
{
|
||||
if (players[i].spectator)
|
||||
spectators++;
|
||||
else if (players[i].pflags & PF_TAGIT)
|
||||
else if ((players[i].pflags & PF_TAGIT) && players[i].quittime < 30 * TICRATE)
|
||||
taggers++;
|
||||
else if (!(players[i].pflags & PF_GAMETYPEOVER))
|
||||
else if (!(players[i].pflags & PF_GAMETYPEOVER) && players[i].quittime < 30 * TICRATE)
|
||||
{
|
||||
survivorarray[survivors] = i;
|
||||
survivors++;
|
||||
|
|
|
@ -486,6 +486,7 @@ void P_PlayerWeaponPanelOrAmmoBurst(player_t *player);
|
|||
void P_PlayerEmeraldBurst(player_t *player, boolean toss);
|
||||
|
||||
void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck);
|
||||
void P_TouchStarPost(mobj_t *starpost, player_t *player, boolean snaptopost);
|
||||
void P_PlayerFlagBurst(player_t *player, boolean toss);
|
||||
void P_CheckTimeLimit(void);
|
||||
void P_CheckPointLimit(void);
|
||||
|
|
|
@ -643,7 +643,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
|
||||
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
|
||||
|
||||
if (delta1 >= delta2 && (rover->flags & FF_INTANGABLEFLATS) != FF_PLATFORM) // thing is below FOF
|
||||
if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF
|
||||
{
|
||||
if (bottomheight < opentop) {
|
||||
opentop = bottomheight;
|
||||
|
@ -656,7 +656,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
highceiling = bottomheight;
|
||||
}
|
||||
|
||||
if (delta1 < delta2 && (rover->flags & FF_INTANGABLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF
|
||||
if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF
|
||||
{
|
||||
if (topheight > openbottom) {
|
||||
openbottom = topheight;
|
||||
|
@ -689,7 +689,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
|
||||
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
|
||||
|
||||
if (delta1 >= delta2 && (rover->flags & FF_INTANGABLEFLATS) != FF_PLATFORM) // thing is below FOF
|
||||
if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF
|
||||
{
|
||||
if (bottomheight < opentop) {
|
||||
opentop = bottomheight;
|
||||
|
@ -702,7 +702,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
highceiling = bottomheight;
|
||||
}
|
||||
|
||||
if (delta1 < delta2 && (rover->flags & FF_INTANGABLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF
|
||||
if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF
|
||||
{
|
||||
if (topheight > openbottom) {
|
||||
openbottom = topheight;
|
||||
|
|
81
src/p_mobj.c
81
src/p_mobj.c
|
@ -2350,6 +2350,7 @@ static void P_RingZMovement(mobj_t *mo)
|
|||
if (mo->eflags & MFE_APPLYPMOMZ && !P_IsObjectOnGround(mo))
|
||||
{
|
||||
mo->momz += mo->pmomz;
|
||||
mo->pmomz = 0;
|
||||
mo->eflags &= ~MFE_APPLYPMOMZ;
|
||||
}
|
||||
mo->z += mo->momz;
|
||||
|
@ -2419,6 +2420,7 @@ static boolean P_ZMovement(mobj_t *mo)
|
|||
if (mo->eflags & MFE_APPLYPMOMZ && !P_IsObjectOnGround(mo))
|
||||
{
|
||||
mo->momz += mo->pmomz;
|
||||
mo->pmomz = 0;
|
||||
mo->eflags &= ~MFE_APPLYPMOMZ;
|
||||
}
|
||||
mo->z += mo->momz;
|
||||
|
@ -2907,6 +2909,7 @@ static void P_PlayerZMovement(mobj_t *mo)
|
|||
if (mo->eflags & MFE_APPLYPMOMZ && !P_IsObjectOnGround(mo))
|
||||
{
|
||||
mo->momz += mo->pmomz;
|
||||
mo->pmomz = 0;
|
||||
mo->eflags &= ~MFE_APPLYPMOMZ;
|
||||
}
|
||||
|
||||
|
@ -3157,6 +3160,7 @@ static boolean P_SceneryZMovement(mobj_t *mo)
|
|||
if (mo->eflags & MFE_APPLYPMOMZ && !P_IsObjectOnGround(mo))
|
||||
{
|
||||
mo->momz += mo->pmomz;
|
||||
mo->pmomz = 0;
|
||||
mo->eflags &= ~MFE_APPLYPMOMZ;
|
||||
}
|
||||
mo->z += mo->momz;
|
||||
|
@ -3396,7 +3400,7 @@ void P_MobjCheckWater(mobj_t *mobj)
|
|||
if (!((p->powers[pw_super]) || (p->powers[pw_invulnerability])))
|
||||
{
|
||||
boolean electric = !!(p->powers[pw_shield] & SH_PROTECTELECTRIC);
|
||||
if (electric || ((p->powers[pw_shield] & SH_PROTECTFIRE) && !(p->powers[pw_shield] & SH_PROTECTWATER)))
|
||||
if (electric || ((p->powers[pw_shield] & SH_PROTECTFIRE) && !(p->powers[pw_shield] & SH_PROTECTWATER) && !(mobj->eflags & MFE_TOUCHLAVA)))
|
||||
{ // Water removes electric and non-water fire shields...
|
||||
P_FlashPal(p,
|
||||
electric
|
||||
|
@ -3902,11 +3906,15 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
|
|||
mobj->z += mobj->momz;
|
||||
P_SetThingPosition(mobj);
|
||||
P_CheckPosition(mobj, mobj->x, mobj->y);
|
||||
mobj->floorz = tmfloorz;
|
||||
mobj->ceilingz = tmceilingz;
|
||||
goto animonly;
|
||||
}
|
||||
else if (mobj->player->powers[pw_carry] == CR_MACESPIN)
|
||||
{
|
||||
P_CheckPosition(mobj, mobj->x, mobj->y);
|
||||
mobj->floorz = tmfloorz;
|
||||
mobj->ceilingz = tmceilingz;
|
||||
goto animonly;
|
||||
}
|
||||
}
|
||||
|
@ -10453,6 +10461,61 @@ void P_SceneryThinker(mobj_t *mobj)
|
|||
// GAME SPAWN FUNCTIONS
|
||||
//
|
||||
|
||||
static fixed_t P_DefaultMobjShadowScale (mobj_t *thing)
|
||||
{
|
||||
switch (thing->type)
|
||||
{
|
||||
case MT_PLAYER:
|
||||
case MT_ROLLOUTROCK:
|
||||
|
||||
case MT_EGGMOBILE4_MACE:
|
||||
case MT_SMALLMACE:
|
||||
case MT_BIGMACE:
|
||||
|
||||
case MT_SMALLGRABCHAIN:
|
||||
case MT_BIGGRABCHAIN:
|
||||
|
||||
case MT_YELLOWSPRINGBALL:
|
||||
case MT_REDSPRINGBALL:
|
||||
|
||||
return FRACUNIT;
|
||||
|
||||
case MT_RING:
|
||||
case MT_FLINGRING:
|
||||
|
||||
case MT_BLUESPHERE:
|
||||
case MT_FLINGBLUESPHERE:
|
||||
case MT_BOMBSPHERE:
|
||||
|
||||
case MT_REDTEAMRING:
|
||||
case MT_BLUETEAMRING:
|
||||
case MT_REDFLAG:
|
||||
case MT_BLUEFLAG:
|
||||
|
||||
case MT_EMBLEM:
|
||||
|
||||
case MT_TOKEN:
|
||||
case MT_EMERALD1:
|
||||
case MT_EMERALD2:
|
||||
case MT_EMERALD3:
|
||||
case MT_EMERALD4:
|
||||
case MT_EMERALD5:
|
||||
case MT_EMERALD6:
|
||||
case MT_EMERALD7:
|
||||
case MT_EMERHUNT:
|
||||
case MT_FLINGEMERALD:
|
||||
|
||||
return 2*FRACUNIT/3;
|
||||
|
||||
default:
|
||||
|
||||
if (thing->flags & (MF_ENEMY|MF_BOSS))
|
||||
return FRACUNIT;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_SpawnMobj
|
||||
//
|
||||
|
@ -10553,6 +10616,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
else
|
||||
mobj->z = z;
|
||||
|
||||
// Set shadowscale here, before spawn hook so that Lua can change it
|
||||
mobj->shadowscale = P_DefaultMobjShadowScale(mobj);
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
// DANGER! This can cause P_SpawnMobj to return NULL!
|
||||
// Avoid using P_RemoveMobj on the newly created mobj in "MobjSpawn" Lua hooks!
|
||||
|
@ -11094,7 +11160,7 @@ void P_SpawnPrecipitation(void)
|
|||
x = basex + ((M_RandomKey(MAPBLOCKUNITS<<3)<<FRACBITS)>>3);
|
||||
y = basey + ((M_RandomKey(MAPBLOCKUNITS<<3)<<FRACBITS)>>3);
|
||||
|
||||
precipsector = R_IsPointInSubsector(x, y);
|
||||
precipsector = R_PointInSubsectorOrNull(x, y);
|
||||
|
||||
// No sector? Stop wasting time,
|
||||
// move on to the next entry in the blockmap
|
||||
|
@ -12911,7 +12977,16 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
|
|||
thinker_t* th;
|
||||
mobj_t* mo2;
|
||||
boolean foundanother = false;
|
||||
mobj->health = (mthing->angle/360) + 1;
|
||||
|
||||
if (mthing->extrainfo)
|
||||
// Allow thing Parameter to define star post num too!
|
||||
// For starposts above param 15 (the 16th), add 360 to the angle like before and start parameter from 1 (NOT 0)!
|
||||
// So the 16th starpost is angle=0 param=15, the 17th would be angle=360 param=1.
|
||||
// This seems more intuitive for mappers to use until UDMF is ready, since most SP maps won't have over 16 consecutive star posts.
|
||||
mobj->health = mthing->extrainfo + (mthing->angle/360)*15 + 1;
|
||||
else
|
||||
// Old behavior if Parameter is 0; add 360 to the angle for each consecutive star post.
|
||||
mobj->health = (mthing->angle/360) + 1;
|
||||
|
||||
// See if other starposts exist in this level that have the same value.
|
||||
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
|
||||
|
|
|
@ -375,6 +375,7 @@ typedef struct mobj_s
|
|||
#endif
|
||||
|
||||
boolean colorized; // Whether the mobj uses the rainbow colormap
|
||||
fixed_t shadowscale; // If this object casts a shadow, and the size relative to radius
|
||||
|
||||
// WARNING: New fields must be added separately to savegame and Lua.
|
||||
} mobj_t;
|
||||
|
|
|
@ -1001,15 +1001,35 @@ static void Polyobj_pushThing(polyobj_t *po, line_t *line, mobj_t *mo)
|
|||
//
|
||||
static void Polyobj_slideThing(mobj_t *mo, fixed_t dx, fixed_t dy)
|
||||
{
|
||||
if (mo->player) { // Do something similar to conveyor movement. -Red
|
||||
mo->player->cmomx += dx;
|
||||
mo->player->cmomy += dy;
|
||||
if (mo->player) { // Finally this doesn't suck eggs -fickle
|
||||
fixed_t cdx, cdy;
|
||||
|
||||
dx = FixedMul(dx, CARRYFACTOR);
|
||||
dy = FixedMul(dy, CARRYFACTOR);
|
||||
cdx = FixedMul(dx, FRACUNIT-CARRYFACTOR);
|
||||
cdy = FixedMul(dy, FRACUNIT-CARRYFACTOR);
|
||||
|
||||
mo->player->cmomx -= dx;
|
||||
mo->player->cmomy -= dy;
|
||||
if (mo->player->onconveyor == 1)
|
||||
{
|
||||
mo->momx += cdx;
|
||||
mo->momy += cdy;
|
||||
|
||||
// Multiple slides in the same tic, somehow
|
||||
mo->player->cmomx += cdx;
|
||||
mo->player->cmomy += cdy;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mo->player->onconveyor == 3)
|
||||
{
|
||||
mo->momx += cdx - mo->player->cmomx;
|
||||
mo->momy += cdy - mo->player->cmomy;
|
||||
}
|
||||
|
||||
mo->player->cmomx = cdx;
|
||||
mo->player->cmomy = cdy;
|
||||
}
|
||||
|
||||
dx = FixedMul(dx, FRACUNIT - mo->friction);
|
||||
dy = FixedMul(dy, FRACUNIT - mo->friction);
|
||||
|
||||
if (mo->player->pflags & PF_SPINNING && (mo->player->rmomx || mo->player->rmomy) && !(mo->player->pflags & PF_STARTDASH)) {
|
||||
#define SPINMULT 5184 // Consider this a substitute for properly calculating FRACUNIT-friction. I'm tired. -Red
|
||||
|
@ -1282,7 +1302,8 @@ static void Polyobj_rotateThings(polyobj_t *po, vertex_t origin, angle_t delta,
|
|||
{
|
||||
static INT32 pomovecount = 10000;
|
||||
INT32 x, y;
|
||||
angle_t deltafine = delta >> ANGLETOFINESHIFT;
|
||||
angle_t deltafine = (((po->angle + delta) >> ANGLETOFINESHIFT) - (po->angle >> ANGLETOFINESHIFT)) & FINEMASK;
|
||||
// This fineshift trickery replaces the old delta>>ANGLETOFINESHIFT; doing it this way avoids loss of precision causing objects to slide off -fickle
|
||||
|
||||
pomovecount++;
|
||||
|
||||
|
@ -1334,19 +1355,10 @@ static void Polyobj_rotateThings(polyobj_t *po, vertex_t origin, angle_t delta,
|
|||
oldxoff = mo->x-origin.x;
|
||||
oldyoff = mo->y-origin.y;
|
||||
|
||||
if (mo->player) // Hack to fix players sliding off of spinning polys -Red
|
||||
{
|
||||
fixed_t temp;
|
||||
newxoff = FixedMul(oldxoff, c)-FixedMul(oldyoff, s) - oldxoff;
|
||||
newyoff = FixedMul(oldyoff, c)+FixedMul(oldxoff, s) - oldyoff;
|
||||
|
||||
temp = FixedMul(oldxoff, c)-FixedMul(oldyoff, s);
|
||||
oldyoff = FixedMul(oldyoff, c)+FixedMul(oldxoff, s);
|
||||
oldxoff = temp;
|
||||
}
|
||||
|
||||
newxoff = FixedMul(oldxoff, c)-FixedMul(oldyoff, s);
|
||||
newyoff = FixedMul(oldyoff, c)+FixedMul(oldxoff, s);
|
||||
|
||||
Polyobj_slideThing(mo, newxoff-oldxoff, newyoff-oldyoff);
|
||||
Polyobj_slideThing(mo, newxoff, newyoff);
|
||||
|
||||
if (turnthings == 2 || (turnthings == 1 && !mo->player)) {
|
||||
mo->angle += delta;
|
||||
|
|
|
@ -116,6 +116,7 @@ static void P_NetArchivePlayers(void)
|
|||
|
||||
WRITEANGLE(save_p, players[i].aiming);
|
||||
WRITEANGLE(save_p, players[i].drawangle);
|
||||
WRITEANGLE(save_p, players[i].viewrollangle);
|
||||
WRITEANGLE(save_p, players[i].awayviewaiming);
|
||||
WRITEINT32(save_p, players[i].awayviewtics);
|
||||
WRITEINT16(save_p, players[i].rings);
|
||||
|
@ -255,6 +256,7 @@ static void P_NetArchivePlayers(void)
|
|||
WRITEINT32(save_p, players[i].onconveyor);
|
||||
|
||||
WRITEUINT32(save_p, players[i].jointime);
|
||||
WRITEUINT32(save_p, players[i].quittime);
|
||||
|
||||
WRITEUINT16(save_p, flags);
|
||||
|
||||
|
@ -325,6 +327,7 @@ static void P_NetUnArchivePlayers(void)
|
|||
|
||||
players[i].aiming = READANGLE(save_p);
|
||||
players[i].drawangle = READANGLE(save_p);
|
||||
players[i].viewrollangle = READANGLE(save_p);
|
||||
players[i].awayviewaiming = READANGLE(save_p);
|
||||
players[i].awayviewtics = READINT32(save_p);
|
||||
players[i].rings = READINT16(save_p);
|
||||
|
@ -446,6 +449,7 @@ static void P_NetUnArchivePlayers(void)
|
|||
players[i].onconveyor = READINT32(save_p);
|
||||
|
||||
players[i].jointime = READUINT32(save_p);
|
||||
players[i].quittime = READUINT32(save_p);
|
||||
|
||||
flags = READUINT16(save_p);
|
||||
|
||||
|
@ -607,7 +611,7 @@ static void P_NetArchiveColormaps(void)
|
|||
|
||||
WRITEUINT8(save_p, exc->fadestart);
|
||||
WRITEUINT8(save_p, exc->fadeend);
|
||||
WRITEUINT8(save_p, exc->fog);
|
||||
WRITEUINT8(save_p, exc->flags);
|
||||
|
||||
WRITEINT32(save_p, exc->rgba);
|
||||
WRITEINT32(save_p, exc->fadergba);
|
||||
|
@ -637,7 +641,7 @@ static void P_NetUnArchiveColormaps(void)
|
|||
|
||||
for (exc = net_colormaps; i < num_net_colormaps; i++, exc = exc_next)
|
||||
{
|
||||
UINT8 fadestart, fadeend, fog;
|
||||
UINT8 fadestart, fadeend, flags;
|
||||
INT32 rgba, fadergba;
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
char lumpname[9];
|
||||
|
@ -645,7 +649,7 @@ static void P_NetUnArchiveColormaps(void)
|
|||
|
||||
fadestart = READUINT8(save_p);
|
||||
fadeend = READUINT8(save_p);
|
||||
fog = READUINT8(save_p);
|
||||
flags = READUINT8(save_p);
|
||||
|
||||
rgba = READINT32(save_p);
|
||||
fadergba = READINT32(save_p);
|
||||
|
@ -677,7 +681,7 @@ static void P_NetUnArchiveColormaps(void)
|
|||
|
||||
exc->fadestart = fadestart;
|
||||
exc->fadeend = fadeend;
|
||||
exc->fog = fog;
|
||||
exc->flags = flags;
|
||||
|
||||
exc->rgba = rgba;
|
||||
exc->fadergba = fadergba;
|
||||
|
@ -687,7 +691,7 @@ static void P_NetUnArchiveColormaps(void)
|
|||
exc->lumpname[0] = 0;
|
||||
#endif
|
||||
|
||||
existing_exc = R_GetColormapFromListByValues(rgba, fadergba, fadestart, fadeend, fog);
|
||||
existing_exc = R_GetColormapFromListByValues(rgba, fadergba, fadestart, fadeend, flags);
|
||||
|
||||
if (existing_exc)
|
||||
exc->colormap = existing_exc->colormap;
|
||||
|
@ -1253,6 +1257,7 @@ typedef enum
|
|||
#endif
|
||||
MD2_COLORIZED = 1<<12,
|
||||
MD2_ROLLANGLE = 1<<13,
|
||||
MD2_SHADOWSCALE = 1<<14,
|
||||
} mobj_diff2_t;
|
||||
|
||||
typedef enum
|
||||
|
@ -1474,6 +1479,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
|||
diff2 |= MD2_COLORIZED;
|
||||
if (mobj->rollangle)
|
||||
diff2 |= MD2_ROLLANGLE;
|
||||
if (mobj->shadowscale)
|
||||
diff2 |= MD2_SHADOWSCALE;
|
||||
if (diff2 != 0)
|
||||
diff |= MD_MORE;
|
||||
|
||||
|
@ -1640,6 +1647,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
|||
WRITEUINT8(save_p, mobj->colorized);
|
||||
if (diff2 & MD2_ROLLANGLE)
|
||||
WRITEANGLE(save_p, mobj->rollangle);
|
||||
if (diff2 & MD2_SHADOWSCALE)
|
||||
WRITEFIXED(save_p, mobj->shadowscale);
|
||||
|
||||
WRITEUINT32(save_p, mobj->mobjnum);
|
||||
}
|
||||
|
@ -2719,6 +2728,8 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
|
|||
mobj->colorized = READUINT8(save_p);
|
||||
if (diff2 & MD2_ROLLANGLE)
|
||||
mobj->rollangle = READANGLE(save_p);
|
||||
if (diff2 & MD2_SHADOWSCALE)
|
||||
mobj->shadowscale = READFIXED(save_p);
|
||||
|
||||
if (diff & MD_REDFLAG)
|
||||
{
|
||||
|
|
|
@ -222,6 +222,7 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
|
|||
mapheaderinfo[num]->typeoflevel = 0;
|
||||
mapheaderinfo[num]->nextlevel = (INT16)(i + 1);
|
||||
mapheaderinfo[num]->startrings = 0;
|
||||
mapheaderinfo[num]->keywords[0] = '\0';
|
||||
snprintf(mapheaderinfo[num]->musname, 7, "%sM", G_BuildMapName(i));
|
||||
mapheaderinfo[num]->musname[6] = 0;
|
||||
mapheaderinfo[num]->mustrack = 0;
|
||||
|
@ -410,7 +411,7 @@ levelflat refers to an array of level flats,
|
|||
or NULL if we want to allocate it now.
|
||||
*/
|
||||
static INT32
|
||||
Ploadflat (levelflat_t *levelflat, const char *flatname)
|
||||
Ploadflat (levelflat_t *levelflat, const char *flatname, boolean resize)
|
||||
{
|
||||
#ifndef NO_PNG_LUMPS
|
||||
UINT8 buffer[8];
|
||||
|
@ -421,31 +422,26 @@ Ploadflat (levelflat_t *levelflat, const char *flatname)
|
|||
|
||||
size_t i;
|
||||
|
||||
if (levelflat)
|
||||
// Scan through the already found flats, return if it matches.
|
||||
for (i = 0; i < numlevelflats; i++)
|
||||
{
|
||||
// Scan through the already found flats, return if it matches.
|
||||
for (i = 0; i < numlevelflats; i++)
|
||||
{
|
||||
if (strnicmp(levelflat[i].name, flatname, 8) == 0)
|
||||
return i;
|
||||
}
|
||||
if (strnicmp(levelflat[i].name, flatname, 8) == 0)
|
||||
return i;
|
||||
}
|
||||
|
||||
#ifndef ZDEBUG
|
||||
CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name);
|
||||
#endif
|
||||
|
||||
if (numlevelflats >= MAXLEVELFLATS)
|
||||
I_Error("Too many flats in level\n");
|
||||
|
||||
if (levelflat)
|
||||
levelflat += numlevelflats;
|
||||
else
|
||||
if (resize)
|
||||
{
|
||||
// allocate new flat memory
|
||||
levelflats = Z_Realloc(levelflats, (numlevelflats + 1) * sizeof(*levelflats), PU_LEVEL, NULL);
|
||||
levelflat = levelflats + numlevelflats;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (numlevelflats >= MAXLEVELFLATS)
|
||||
I_Error("Too many flats in level\n");
|
||||
|
||||
levelflat += numlevelflats;
|
||||
}
|
||||
|
||||
// Store the name.
|
||||
strlcpy(levelflat->name, flatname, sizeof (levelflat->name));
|
||||
|
@ -500,6 +496,10 @@ flatfound:
|
|||
levelflat->u.flat.baselumpnum = LUMPERROR;
|
||||
}
|
||||
|
||||
#ifndef ZDEBUG
|
||||
CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name);
|
||||
#endif
|
||||
|
||||
return ( numlevelflats++ );
|
||||
}
|
||||
|
||||
|
@ -507,7 +507,7 @@ flatfound:
|
|||
// allocate an id for it, and set the levelflat (to speedup search)
|
||||
INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat)
|
||||
{
|
||||
return Ploadflat(levelflat, flatname);
|
||||
return Ploadflat(levelflat, flatname, false);
|
||||
}
|
||||
|
||||
// help function for Lua and $$$.sav reading
|
||||
|
@ -516,7 +516,7 @@ INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat)
|
|||
//
|
||||
INT32 P_AddLevelFlatRuntime(const char *flatname)
|
||||
{
|
||||
return Ploadflat(levelflats, flatname);
|
||||
return Ploadflat(levelflats, flatname, true);
|
||||
}
|
||||
|
||||
// help function for $$$.sav checking
|
||||
|
@ -846,6 +846,8 @@ static void P_LoadVertices(UINT8 *data)
|
|||
{
|
||||
v->x = SHORT(mv->x)<<FRACBITS;
|
||||
v->y = SHORT(mv->y)<<FRACBITS;
|
||||
v->floorzset = v->ceilingzset = false;
|
||||
v->floorz = v->ceilingz = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1370,6 +1372,16 @@ static void ParseTextmapVertexParameter(UINT32 i, char *param, char *val)
|
|||
vertexes[i].x = FLOAT_TO_FIXED(atof(val));
|
||||
else if (fastcmp(param, "y"))
|
||||
vertexes[i].y = FLOAT_TO_FIXED(atof(val));
|
||||
else if (fastcmp(param, "zfloor"))
|
||||
{
|
||||
vertexes[i].floorz = FLOAT_TO_FIXED(atof(val));
|
||||
vertexes[i].floorzset = true;
|
||||
}
|
||||
else if (fastcmp(param, "zceiling"))
|
||||
{
|
||||
vertexes[i].ceilingz = FLOAT_TO_FIXED(atof(val));
|
||||
vertexes[i].ceilingzset = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void ParseTextmapSectorParameter(UINT32 i, char *param, char *val)
|
||||
|
@ -1577,6 +1589,8 @@ static void P_LoadTextmap(void)
|
|||
{
|
||||
// Defaults.
|
||||
vt->x = vt->y = INT32_MAX;
|
||||
vt->floorzset = vt->ceilingzset = false;
|
||||
vt->floorz = vt->ceilingz = 0;
|
||||
|
||||
TextmapParse(vertexesPos[i], i, ParseTextmapVertexParameter);
|
||||
|
||||
|
@ -3086,7 +3100,7 @@ static void P_InitTagGametype(void)
|
|||
//Also, you'd never have to loop through all 32 players slots to find anything ever again.
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i] && !players[i].spectator)
|
||||
if (playeringame[i] && !(players[i].spectator && players[i].quittime))
|
||||
{
|
||||
playersactive[realnumplayers] = i; //stores the player's node in the array.
|
||||
realnumplayers++;
|
||||
|
@ -3108,7 +3122,7 @@ static void P_InitTagGametype(void)
|
|||
if (players[playersactive[i]].mo)
|
||||
P_RemoveMobj(players[playersactive[i]].mo);
|
||||
|
||||
G_SpawnPlayer(playersactive[i], false); //respawn the lucky player in his dedicated spawn location.
|
||||
G_SpawnPlayer(playersactive[i]); //respawn the lucky player in his dedicated spawn location.
|
||||
}
|
||||
|
||||
static void P_SetupCamera(void)
|
||||
|
@ -3286,7 +3300,7 @@ static void P_InitPlayers(void)
|
|||
G_DoReborn(i);
|
||||
else // gametype is GT_COOP or GT_RACE
|
||||
{
|
||||
G_SpawnPlayer(i, players[i].starposttime);
|
||||
G_SpawnPlayer(i);
|
||||
if (players[i].starposttime)
|
||||
P_ClearStarPost(players[i].starpostnum);
|
||||
}
|
||||
|
@ -3571,11 +3585,11 @@ boolean P_LoadLevel(boolean fromnetsave)
|
|||
return false;
|
||||
|
||||
// init gravity, tag lists,
|
||||
// anything that P_ResetDynamicSlopes/P_LoadThings needs to know
|
||||
// anything that P_SpawnSlopes/P_LoadThings needs to know
|
||||
P_InitSpecials();
|
||||
|
||||
#ifdef ESLOPE
|
||||
P_ResetDynamicSlopes(fromnetsave);
|
||||
P_SpawnSlopes(fromnetsave);
|
||||
#endif
|
||||
|
||||
P_SpawnMapThings(!fromnetsave);
|
||||
|
@ -3674,8 +3688,7 @@ boolean P_LoadLevel(boolean fromnetsave)
|
|||
return true;
|
||||
|
||||
// If so...
|
||||
if ((!(mapheaderinfo[gamemap-1]->levelflags & LF_NOTITLECARD)) && (*mapheaderinfo[gamemap-1]->lvlttl != '\0'))
|
||||
G_PreLevelTitleCard();
|
||||
G_PreLevelTitleCard();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -458,8 +458,8 @@ static pslope_t *MakeViaMapthings(INT16 tag1, INT16 tag2, INT16 tag3, UINT8 flag
|
|||
return ret;
|
||||
}
|
||||
|
||||
/// Create vertex based slopes.
|
||||
static void line_SpawnViaVertexes(const int linenum, const boolean spawnthinker)
|
||||
/// Create vertex based slopes using tagged mapthings.
|
||||
static void line_SpawnViaMapthingVertexes(const int linenum, const boolean spawnthinker)
|
||||
{
|
||||
line_t *line = lines + linenum;
|
||||
side_t *side;
|
||||
|
@ -507,6 +507,55 @@ static void line_SpawnViaVertexes(const int linenum, const boolean spawnthinker)
|
|||
side->sector->hasslope = true;
|
||||
}
|
||||
|
||||
/// Spawn textmap vertex slopes.
|
||||
static void SpawnVertexSlopes(void)
|
||||
{
|
||||
line_t *l1, *l2;
|
||||
sector_t* sc;
|
||||
vertex_t *v1, *v2, *v3;
|
||||
size_t i;
|
||||
for (i = 0, sc = sectors; i < numsectors; i++, sc++)
|
||||
{
|
||||
// The vertex slopes only work for 3-vertex sectors (and thus 3-sided sectors).
|
||||
if (sc->linecount != 3)
|
||||
continue;
|
||||
|
||||
l1 = sc->lines[0];
|
||||
l2 = sc->lines[1];
|
||||
|
||||
// Determine the vertexes.
|
||||
v1 = l1->v1;
|
||||
v2 = l1->v2;
|
||||
if ((l2->v1 != v1) && (l2->v1 != v2))
|
||||
v3 = l2->v1;
|
||||
else
|
||||
v3 = l2->v2;
|
||||
|
||||
if (v1->floorzset || v2->floorzset || v3->floorzset)
|
||||
{
|
||||
vector3_t vtx[3] = {
|
||||
{v1->x, v1->y, v1->floorzset ? v1->floorz : sc->floorheight},
|
||||
{v2->x, v2->y, v2->floorzset ? v2->floorz : sc->floorheight},
|
||||
{v3->x, v3->y, v3->floorzset ? v3->floorz : sc->floorheight}};
|
||||
pslope_t *slop = Slope_Add(0);
|
||||
sc->f_slope = slop;
|
||||
sc->hasslope = true;
|
||||
ReconfigureViaVertexes(slop, vtx[0], vtx[1], vtx[2]);
|
||||
}
|
||||
|
||||
if (v1->ceilingzset || v2->ceilingzset || v3->ceilingzset)
|
||||
{
|
||||
vector3_t vtx[3] = {
|
||||
{v1->x, v1->y, v1->ceilingzset ? v1->ceilingz : sc->ceilingheight},
|
||||
{v2->x, v2->y, v2->ceilingzset ? v2->ceilingz : sc->ceilingheight},
|
||||
{v3->x, v3->y, v3->ceilingzset ? v3->ceilingz : sc->ceilingheight}};
|
||||
pslope_t *slop = Slope_Add(0);
|
||||
sc->c_slope = slop;
|
||||
sc->hasslope = true;
|
||||
ReconfigureViaVertexes(slop, vtx[0], vtx[1], vtx[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_CopySectorSlope
|
||||
|
@ -551,12 +600,16 @@ pslope_t *P_SlopeById(UINT16 id)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/// Reset slopes and read them from special lines.
|
||||
void P_ResetDynamicSlopes(const boolean fromsave) {
|
||||
/// Initializes and reads the slopes from the map data.
|
||||
void P_SpawnSlopes(const boolean fromsave) {
|
||||
size_t i;
|
||||
|
||||
slopelist = NULL;
|
||||
slopecount = 0;
|
||||
|
||||
/// Generates vertex slopes.
|
||||
SpawnVertexSlopes();
|
||||
|
||||
/// Generates line special-defined slopes.
|
||||
for (i = 0; i < numlines; i++)
|
||||
{
|
||||
|
@ -577,7 +630,7 @@ void P_ResetDynamicSlopes(const boolean fromsave) {
|
|||
case 705:
|
||||
case 714:
|
||||
case 715:
|
||||
line_SpawnViaVertexes(i, !fromsave);
|
||||
line_SpawnViaMapthingVertexes(i, !fromsave);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -23,7 +23,7 @@ extern UINT16 slopecount;
|
|||
void P_LinkSlopeThinkers (void);
|
||||
|
||||
void P_CalculateSlopeNormal(pslope_t *slope);
|
||||
void P_ResetDynamicSlopes(const boolean fromsave);
|
||||
void P_SpawnSlopes(const boolean fromsave);
|
||||
|
||||
//
|
||||
// P_CopySectorSlope
|
||||
|
|
35
src/p_spec.c
35
src/p_spec.c
|
@ -3529,7 +3529,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
false, // subtract FadeA (no flag for this, just pass negative alpha)
|
||||
false, // subtract FadeStart (we ran out of flags)
|
||||
false, // subtract FadeEnd (we ran out of flags)
|
||||
false, // ignore Fog (we ran out of flags)
|
||||
false, // ignore Flags (we ran out of flags)
|
||||
line->flags & ML_DONTPEGBOTTOM,
|
||||
(line->flags & ML_DONTPEGBOTTOM) ? (sides[line->sidenum[0]].textureoffset >> FRACBITS) : 0,
|
||||
(line->flags & ML_DONTPEGBOTTOM) ? (sides[line->sidenum[0]].rowoffset >> FRACBITS) : 0,
|
||||
|
@ -3896,7 +3896,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
false, // subtract FadeA (no flag for this, just pass negative alpha)
|
||||
false, // subtract FadeStart (we ran out of flags)
|
||||
false, // subtract FadeEnd (we ran out of flags)
|
||||
false, // ignore Fog (we ran out of flags)
|
||||
false, // ignore Flags (we ran out of flags)
|
||||
line->flags & ML_DONTPEGBOTTOM,
|
||||
(line->flags & ML_DONTPEGBOTTOM) ? (sides[line->sidenum[0]].textureoffset >> FRACBITS) : 0,
|
||||
(line->flags & ML_DONTPEGBOTTOM) ? (sides[line->sidenum[0]].rowoffset >> FRACBITS) : 0,
|
||||
|
@ -4455,10 +4455,18 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
|
|||
case 6: // Death Pit (Camera Mod)
|
||||
case 7: // Death Pit (No Camera Mod)
|
||||
if (roversector || P_MobjReadyToTrigger(player->mo, sector))
|
||||
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_DEATHPIT);
|
||||
{
|
||||
if (player->quittime)
|
||||
G_MovePlayerToSpawnOrStarpost(player - players);
|
||||
else
|
||||
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_DEATHPIT);
|
||||
}
|
||||
break;
|
||||
case 8: // Instant Kill
|
||||
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_INSTAKILL);
|
||||
if (player->quittime)
|
||||
G_MovePlayerToSpawnOrStarpost(player - players);
|
||||
else
|
||||
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_INSTAKILL);
|
||||
break;
|
||||
case 9: // Ring Drainer (Floor Touch)
|
||||
case 10: // Ring Drainer (No Floor Touch)
|
||||
|
@ -4713,7 +4721,7 @@ DoneSection2:
|
|||
if (!post)
|
||||
break;
|
||||
|
||||
P_TouchSpecialThing(post, player->mo, false);
|
||||
P_TouchStarPost(post, player, false);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -6382,7 +6390,7 @@ static void P_RunLevelLoadExecutors(void)
|
|||
}
|
||||
|
||||
/** Before things are loaded, initialises certain stuff in case they're needed
|
||||
* by P_ResetDynamicSlopes or P_LoadThings. This was split off from
|
||||
* by P_SpawnSlopes or P_LoadThings. This was split off from
|
||||
* P_SpawnSpecials, in case you couldn't tell.
|
||||
*
|
||||
* \sa P_SpawnSpecials, P_InitTagLists
|
||||
|
@ -6960,7 +6968,7 @@ void P_SpawnSpecials(boolean fromnetsave)
|
|||
break;
|
||||
|
||||
case 146: // Intangible floor/ceiling with solid sides (fences/hoops maybe?)
|
||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERSIDES|FF_ALLSIDES|FF_INTANGABLEFLATS, secthinkers);
|
||||
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERSIDES|FF_ALLSIDES|FF_INTANGIBLEFLATS, secthinkers);
|
||||
break;
|
||||
|
||||
case 150: // Air bobbing platform
|
||||
|
@ -7102,10 +7110,9 @@ void P_SpawnSpecials(boolean fromnetsave)
|
|||
case 202: // Fog
|
||||
ffloorflags = FF_EXISTS|FF_RENDERALL|FF_FOG|FF_BOTHPLANES|FF_INVERTPLANES|FF_ALLSIDES|FF_INVERTSIDES|FF_CUTEXTRA|FF_EXTRA|FF_DOUBLESHADOW|FF_CUTSPRITES;
|
||||
sec = sides[*lines[i].sidenum].sector - sectors;
|
||||
// SoM: Because it's fog, check for an extra colormap and set
|
||||
// the fog flag...
|
||||
// SoM: Because it's fog, check for an extra colormap and set the fog flag...
|
||||
if (sectors[sec].extra_colormap)
|
||||
sectors[sec].extra_colormap->fog = 1;
|
||||
sectors[sec].extra_colormap->flags = CMF_FOG;
|
||||
P_AddFakeFloorsByLine(i, ffloorflags, secthinkers);
|
||||
break;
|
||||
|
||||
|
@ -8499,7 +8506,7 @@ void T_FadeColormap(fadecolormap_t *d)
|
|||
extracolormap_t *exc;
|
||||
INT32 duration = d->ticbased ? d->duration : 256;
|
||||
fixed_t factor = min(FixedDiv(duration - d->timer, duration), 1*FRACUNIT);
|
||||
INT16 cr, cg, cb, ca, fadestart, fadeend, fog;
|
||||
INT16 cr, cg, cb, ca, fadestart, fadeend, flags;
|
||||
INT32 rgba, fadergba;
|
||||
|
||||
// NULL failsafes (or intentionally set to signify default)
|
||||
|
@ -8548,7 +8555,7 @@ void T_FadeColormap(fadecolormap_t *d)
|
|||
|
||||
fadestart = APPLYFADE(d->dest_exc->fadestart, d->source_exc->fadestart, d->sector->extra_colormap->fadestart);
|
||||
fadeend = APPLYFADE(d->dest_exc->fadeend, d->source_exc->fadeend, d->sector->extra_colormap->fadeend);
|
||||
fog = abs(factor) > FRACUNIT/2 ? d->dest_exc->fog : d->source_exc->fog; // set new fog flag halfway through fade
|
||||
flags = abs(factor) > FRACUNIT/2 ? d->dest_exc->flags : d->source_exc->flags; // set new flags halfway through fade
|
||||
|
||||
#undef APPLYFADE
|
||||
|
||||
|
@ -8556,12 +8563,12 @@ void T_FadeColormap(fadecolormap_t *d)
|
|||
// setup new colormap
|
||||
//////////////////
|
||||
|
||||
if (!(d->sector->extra_colormap = R_GetColormapFromListByValues(rgba, fadergba, fadestart, fadeend, fog)))
|
||||
if (!(d->sector->extra_colormap = R_GetColormapFromListByValues(rgba, fadergba, fadestart, fadeend, flags)))
|
||||
{
|
||||
exc = R_CreateDefaultColormap(false);
|
||||
exc->fadestart = fadestart;
|
||||
exc->fadeend = fadeend;
|
||||
exc->fog = (boolean)fog;
|
||||
exc->flags = flags;
|
||||
exc->rgba = rgba;
|
||||
exc->fadergba = fadergba;
|
||||
exc->colormap = R_CreateLightTable(exc);
|
||||
|
|
18
src/p_tick.c
18
src/p_tick.c
|
@ -590,10 +590,24 @@ void P_Ticker(boolean run)
|
|||
{
|
||||
INT32 i;
|
||||
|
||||
//Increment jointime even if paused.
|
||||
// Increment jointime and quittime even if paused
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i])
|
||||
++players[i].jointime;
|
||||
{
|
||||
players[i].jointime++;
|
||||
|
||||
if (players[i].quittime)
|
||||
{
|
||||
players[i].quittime++;
|
||||
|
||||
if (players[i].quittime == 30 * TICRATE && G_TagGametype())
|
||||
P_CheckSurvivors();
|
||||
|
||||
if (server && players[i].quittime >= (tic_t)FixedMul(cv_rejointimeout.value, 60 * TICRATE)
|
||||
&& !(players[i].quittime % TICRATE))
|
||||
SendKick(i, KICK_MSG_PLAYER_QUIT);
|
||||
}
|
||||
}
|
||||
|
||||
if (objectplacing)
|
||||
{
|
||||
|
|
91
src/p_user.c
91
src/p_user.c
|
@ -1466,6 +1466,13 @@ void P_PlayLivesJingle(player_t *player)
|
|||
S_StartSound(NULL, sfx_oneup);
|
||||
else if (mariomode)
|
||||
S_StartSound(NULL, sfx_marioa);
|
||||
else if (cv_1upsound.value)
|
||||
{
|
||||
if (S_sfx[sfx_oneup].lumpnum != LUMPERROR)
|
||||
S_StartSound(NULL, sfx_oneup);
|
||||
else
|
||||
S_StartSound(NULL, sfx_chchng);/* at least play something! */
|
||||
}
|
||||
else
|
||||
{
|
||||
P_PlayJingle(player, JT_1UP);
|
||||
|
@ -2373,6 +2380,8 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (player->charability == CA_GLIDEANDCLIMB && (player->mo->state-states == S_PLAY_GLIDE_LANDING))
|
||||
;
|
||||
else if (player->charability2 == CA2_GUNSLINGER && player->panim == PA_ABILITY2)
|
||||
;
|
||||
else if (player->panim != PA_IDLE && player->panim != PA_WALK && player->panim != PA_RUN && player->panim != PA_DASH)
|
||||
|
@ -3153,7 +3162,7 @@ static void P_DoClimbing(player_t *player)
|
|||
platx = P_ReturnThrustX(player->mo, player->mo->angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale));
|
||||
platy = P_ReturnThrustY(player->mo, player->mo->angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale));
|
||||
|
||||
glidesector = R_IsPointInSubsector(player->mo->x + platx, player->mo->y + platy);
|
||||
glidesector = R_PointInSubsectorOrNull(player->mo->x + platx, player->mo->y + platy);
|
||||
|
||||
{
|
||||
boolean floorclimb = false;
|
||||
|
@ -4530,16 +4539,14 @@ void P_DoJump(player_t *player, boolean soundandstate)
|
|||
player->mo->z--;
|
||||
if (player->mo->pmomz < 0)
|
||||
player->mo->momz += player->mo->pmomz; // Add the platform's momentum to your jump.
|
||||
else
|
||||
player->mo->pmomz = 0;
|
||||
player->mo->pmomz = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
player->mo->z++;
|
||||
if (player->mo->pmomz > 0)
|
||||
player->mo->momz += player->mo->pmomz; // Add the platform's momentum to your jump.
|
||||
else
|
||||
player->mo->pmomz = 0;
|
||||
player->mo->pmomz = 0;
|
||||
}
|
||||
player->mo->eflags &= ~MFE_APPLYPMOMZ;
|
||||
|
||||
|
@ -5496,10 +5503,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
|
|||
; // Can't do anything if you're a fish out of water!
|
||||
else if (player->powers[pw_tailsfly]) // If currently flying, give an ascend boost.
|
||||
{
|
||||
if (!player->fly1)
|
||||
player->fly1 = 20;
|
||||
else
|
||||
player->fly1 = 2;
|
||||
player->fly1 = 20;
|
||||
|
||||
if (player->charability == CA_SWIM)
|
||||
player->fly1 /= 2;
|
||||
|
@ -7432,6 +7436,8 @@ static void P_NiGHTSMovement(player_t *player)
|
|||
else // AngleFixed(R_PointToAngle2()) results in slight inaccuracy! Don't use it unless movement is on both axises.
|
||||
newangle = (INT16)FixedInt(AngleFixed(R_PointToAngle2(0,0, cmd->sidemove*FRACUNIT, cmd->forwardmove*FRACUNIT)));
|
||||
|
||||
newangle -= player->viewrollangle / ANG1;
|
||||
|
||||
if (newangle < 0 && moved)
|
||||
newangle = (INT16)(360+newangle);
|
||||
}
|
||||
|
@ -8480,7 +8486,11 @@ static void P_MovePlayer(player_t *player)
|
|||
// Descend
|
||||
if (cmd->buttons & BT_USE && !(player->pflags & PF_STASIS) && !player->exiting && !(player->mo->eflags & MFE_GOOWATER))
|
||||
if (P_MobjFlip(player->mo)*player->mo->momz > -FixedMul(5*actionspd, player->mo->scale))
|
||||
{
|
||||
if (player->fly1 > 2)
|
||||
player->fly1 = 2;
|
||||
P_SetObjectMomZ(player->mo, -actionspd/2, true);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
|
@ -8672,7 +8682,7 @@ static void P_MovePlayer(player_t *player)
|
|||
}
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode != render_soft && rendermode != render_none && cv_grfovchange.value)
|
||||
if (rendermode != render_soft && rendermode != render_none && cv_fovchange.value)
|
||||
{
|
||||
fixed_t speed;
|
||||
const fixed_t runnyspeed = 20*FRACUNIT;
|
||||
|
@ -9185,7 +9195,7 @@ mobj_t *P_LookForFocusTarget(player_t *player, mobj_t *exclude, SINT8 direction,
|
|||
case MT_TNTBARREL:
|
||||
if (lockonflags & LOCK_INTERESTS)
|
||||
break;
|
||||
/*fallthru*/
|
||||
/*FALLTHRU*/
|
||||
case MT_PLAYER: // Don't chase other players!
|
||||
case MT_DETON:
|
||||
continue; // Don't be STUPID, Sonic!
|
||||
|
@ -9203,7 +9213,7 @@ mobj_t *P_LookForFocusTarget(player_t *player, mobj_t *exclude, SINT8 direction,
|
|||
case MT_EGGSTATUE:
|
||||
if (tutorialmode)
|
||||
break; // Always focus egg statue in the tutorial
|
||||
/*fallthru*/
|
||||
/*FALLTHRU*/
|
||||
default:
|
||||
|
||||
if ((lockonflags & LOCK_BOSS) && ((mo->flags & (MF_BOSS|MF_SHOOTABLE)) == (MF_BOSS|MF_SHOOTABLE))) // allows if it has the flags desired XOR it has the invert aimable flag
|
||||
|
@ -9279,6 +9289,7 @@ mobj_t *P_LookForFocusTarget(player_t *player, mobj_t *exclude, SINT8 direction,
|
|||
// If nonenemies is true, includes monitors and springs!
|
||||
// If bullet is true, you can look up and the distance is further,
|
||||
// but your total angle span you can look is limited to compensate. (Also, allows monitors.)
|
||||
// If you modify this, please also modify P_HomingAttack.
|
||||
//
|
||||
mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet)
|
||||
{
|
||||
|
@ -9374,15 +9385,18 @@ boolean P_HomingAttack(mobj_t *source, mobj_t *enemy) // Home in on your target
|
|||
if (!enemy)
|
||||
return false;
|
||||
|
||||
if (!enemy->health)
|
||||
if (enemy->flags & MF_NOCLIPTHING)
|
||||
return false;
|
||||
|
||||
if (enemy->health <= 0) // dead
|
||||
return false;
|
||||
|
||||
if (!((enemy->flags & (MF_ENEMY|MF_BOSS|MF_MONITOR) && (enemy->flags & MF_SHOOTABLE)) || (enemy->flags & MF_SPRING)) == !(enemy->flags2 & MF2_INVERTAIMABLE)) // allows if it has the flags desired XOR it has the invert aimable flag
|
||||
return false;
|
||||
|
||||
if (enemy->flags2 & MF2_FRET)
|
||||
return false;
|
||||
|
||||
if (!(enemy->flags & (MF_SHOOTABLE|MF_SPRING)) == !(enemy->flags2 & MF2_INVERTAIMABLE)) // allows if it has the flags desired XOR it has the invert aimable flag
|
||||
return false;
|
||||
|
||||
// change angle
|
||||
source->angle = R_PointToAngle2(source->x, source->y, enemy->x, enemy->y);
|
||||
if (source->player)
|
||||
|
@ -10105,13 +10119,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
{
|
||||
dist = camdist;
|
||||
|
||||
// x1.5 dist for splitscreen
|
||||
if (splitscreen)
|
||||
{
|
||||
dist = FixedMul(dist, 3*FRACUNIT/2);
|
||||
camheight = FixedMul(camheight, 3*FRACUNIT/2);
|
||||
}
|
||||
|
||||
if (sign) // signpost camera has specific placement
|
||||
{
|
||||
camheight = mo->scale << 7;
|
||||
|
@ -10231,7 +10238,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
}
|
||||
|
||||
// move camera down to move under lower ceilings
|
||||
newsubsec = R_IsPointInSubsector(((mo->x>>FRACBITS) + (thiscam->x>>FRACBITS))<<(FRACBITS-1), ((mo->y>>FRACBITS) + (thiscam->y>>FRACBITS))<<(FRACBITS-1));
|
||||
newsubsec = R_PointInSubsectorOrNull(((mo->x>>FRACBITS) + (thiscam->x>>FRACBITS))<<(FRACBITS-1), ((mo->y>>FRACBITS) + (thiscam->y>>FRACBITS))<<(FRACBITS-1));
|
||||
|
||||
if (!newsubsec)
|
||||
newsubsec = thiscam->subsector;
|
||||
|
@ -10511,13 +10518,17 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
if (!(multiplayer || netgame) && !splitscreen)
|
||||
{
|
||||
fixed_t vx = thiscam->x, vy = thiscam->y;
|
||||
fixed_t vz = thiscam->z + thiscam->height / 2;
|
||||
if (player->awayviewtics && player->awayviewmobj != NULL && !P_MobjWasRemoved(player->awayviewmobj)) // Camera must obviously exist
|
||||
{
|
||||
vx = player->awayviewmobj->x;
|
||||
vy = player->awayviewmobj->y;
|
||||
vz = player->awayviewmobj->z + player->awayviewmobj->height / 2;
|
||||
}
|
||||
|
||||
if (P_AproxDistance(vx - mo->x, vy - mo->y) < FixedMul(48*FRACUNIT, mo->scale))
|
||||
/* check z distance too for orbital camera */
|
||||
if (P_AproxDistance(P_AproxDistance(vx - mo->x, vy - mo->y),
|
||||
vz - ( mo->z + mo->height / 2 )) < FixedMul(48*FRACUNIT, mo->scale))
|
||||
mo->flags2 |= MF2_SHADOW;
|
||||
else
|
||||
mo->flags2 &= ~MF2_SHADOW;
|
||||
|
@ -11035,10 +11046,21 @@ static void P_MinecartThink(player_t *player)
|
|||
|
||||
if (angdiff + minecart->angle != player->mo->angle && (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG))
|
||||
{
|
||||
angle_t *ang = NULL;
|
||||
|
||||
if (player == &players[consoleplayer])
|
||||
localangle = player->mo->angle;
|
||||
ang = &localangle;
|
||||
else if (player == &players[secondarydisplayplayer])
|
||||
localangle2 = player->mo->angle;
|
||||
ang = &localangle2;
|
||||
|
||||
if (ang)
|
||||
{
|
||||
angdiff = *ang - minecart->angle;
|
||||
if (angdiff < ANGLE_180 && angdiff > MINECARTCONEMAX)
|
||||
*ang = minecart->angle + MINECARTCONEMAX;
|
||||
else if (angdiff > ANGLE_180 && angdiff < InvAngle(MINECARTCONEMAX))
|
||||
*ang = minecart->angle - MINECARTCONEMAX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11748,6 +11770,8 @@ void P_PlayerThink(player_t *player)
|
|||
{
|
||||
if (!playeringame[i] || players[i].spectator || players[i].bot)
|
||||
continue;
|
||||
if (players[i].quittime > 30 * TICRATE)
|
||||
continue;
|
||||
if (players[i].lives <= 0)
|
||||
continue;
|
||||
|
||||
|
@ -12152,7 +12176,9 @@ void P_PlayerThink(player_t *player)
|
|||
|
||||
#ifdef POLYOBJECTS
|
||||
if (player->onconveyor == 1)
|
||||
player->cmomy = player->cmomx = 0;
|
||||
player->onconveyor = 3;
|
||||
else if (player->onconveyor == 3)
|
||||
player->cmomy = player->cmomx = 0;
|
||||
#endif
|
||||
|
||||
P_DoSuperStuff(player);
|
||||
|
@ -12200,6 +12226,11 @@ void P_PlayerThink(player_t *player)
|
|||
player->pflags &= ~PF_USEDOWN;
|
||||
}
|
||||
|
||||
// IF PLAYER NOT HERE THEN FLASH END IF
|
||||
if (player->quittime && player->powers[pw_flashing] < flashingtics - 1
|
||||
&& !(G_TagGametype() && !(player->pflags & PF_TAGIT)) && !player->gotflag)
|
||||
player->powers[pw_flashing] = flashingtics - 1;
|
||||
|
||||
// Counters, time dependent power ups.
|
||||
// Time Bonus & Ring Bonus count settings
|
||||
|
||||
|
@ -12243,12 +12274,12 @@ void P_PlayerThink(player_t *player)
|
|||
else
|
||||
player->powers[pw_underwater] = 0;
|
||||
}
|
||||
else if (player->powers[pw_underwater] && !(maptol & TOL_NIGHTS) && !((netgame || multiplayer) && player->spectator)) // underwater timer
|
||||
else if (player->powers[pw_underwater] && !(maptol & TOL_NIGHTS) && !((netgame || multiplayer) && (player->spectator || player->quittime))) // underwater timer
|
||||
player->powers[pw_underwater]--;
|
||||
|
||||
if (player->powers[pw_spacetime] && (player->pflags & PF_GODMODE || (player->powers[pw_shield] & SH_PROTECTWATER)))
|
||||
player->powers[pw_spacetime] = 0;
|
||||
else if (player->powers[pw_spacetime] && !(maptol & TOL_NIGHTS) && !((netgame || multiplayer) && player->spectator)) // underwater timer
|
||||
else if (player->powers[pw_spacetime] && !(maptol & TOL_NIGHTS) && !((netgame || multiplayer) && (player->spectator || player->quittime))) // underwater timer
|
||||
player->powers[pw_spacetime]--;
|
||||
|
||||
if (player->powers[pw_gravityboots] && player->powers[pw_gravityboots] < UINT16_MAX)
|
||||
|
|
556
src/r_data.c
556
src/r_data.c
|
@ -699,254 +699,29 @@ void R_FlushTextureCache(void)
|
|||
int R_CountTexturesInTEXTURESLump(UINT16 wadNum, UINT16 lumpNum);
|
||||
void R_ParseTEXTURESLump(UINT16 wadNum, UINT16 lumpNum, INT32 *index);
|
||||
|
||||
//
|
||||
// R_LoadTextures
|
||||
// Initializes the texture list with the textures from the world map.
|
||||
//
|
||||
#define TX_START "TX_START"
|
||||
#define TX_END "TX_END"
|
||||
void R_LoadTextures(void)
|
||||
#ifdef WALLFLATS
|
||||
static INT32
|
||||
Rloadflats (INT32 i, INT32 w)
|
||||
{
|
||||
INT32 i, w;
|
||||
UINT16 j;
|
||||
UINT16 texstart, texend, texturesLumpPos;
|
||||
patch_t *patchlump;
|
||||
texpatch_t *patch;
|
||||
UINT16 texstart, texend;
|
||||
texture_t *texture;
|
||||
texpatch_t *patch;
|
||||
|
||||
// Free previous memory before numtextures change.
|
||||
if (numtextures)
|
||||
// Yes
|
||||
if (wadfiles[w]->type == RET_PK3)
|
||||
{
|
||||
for (i = 0; i < numtextures; i++)
|
||||
{
|
||||
Z_Free(textures[i]);
|
||||
Z_Free(texturecache[i]);
|
||||
}
|
||||
Z_Free(texturetranslation);
|
||||
Z_Free(textures);
|
||||
Z_Free(texflats);
|
||||
texstart = W_CheckNumForFolderStartPK3("flats/", (UINT16)w, 0);
|
||||
texend = W_CheckNumForFolderEndPK3("flats/", (UINT16)w, texstart);
|
||||
}
|
||||
else
|
||||
{
|
||||
texstart = W_CheckNumForNamePwad("F_START", (UINT16)w, 0);
|
||||
texend = W_CheckNumForNamePwad("F_END", (UINT16)w, texstart);
|
||||
}
|
||||
|
||||
// Load patches and textures.
|
||||
|
||||
// Get the number of textures to check.
|
||||
// NOTE: Make SURE the system does not process
|
||||
// the markers.
|
||||
// This system will allocate memory for all duplicate/patched textures even if it never uses them,
|
||||
// but the alternative is to spend a ton of time checking and re-checking all previous entries just to skip any potentially patched textures.
|
||||
for (w = 0, numtextures = 0; w < numwadfiles; w++)
|
||||
if (!( texstart == INT16_MAX || texend == INT16_MAX ))
|
||||
{
|
||||
// Count the textures from TEXTURES lumps
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
||||
while (texturesLumpPos != INT16_MAX)
|
||||
{
|
||||
numtextures += R_CountTexturesInTEXTURESLump((UINT16)w, (UINT16)texturesLumpPos);
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1);
|
||||
}
|
||||
|
||||
// Count single-patch textures
|
||||
if (wadfiles[w]->type == RET_PK3)
|
||||
{
|
||||
texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0);
|
||||
texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart);
|
||||
}
|
||||
else
|
||||
{
|
||||
texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0);
|
||||
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
|
||||
}
|
||||
|
||||
if (texstart == INT16_MAX || texend == INT16_MAX)
|
||||
#ifdef WALLFLATS
|
||||
goto countflats;
|
||||
#else
|
||||
continue;
|
||||
#endif
|
||||
|
||||
texstart++; // Do not count the first marker
|
||||
|
||||
// PK3s have subfolders, so we can't just make a simple sum
|
||||
if (wadfiles[w]->type == RET_PK3)
|
||||
{
|
||||
for (j = texstart; j < texend; j++)
|
||||
{
|
||||
if (!W_IsLumpFolder((UINT16)w, j)) // Check if lump is a folder; if not, then count it
|
||||
numtextures++;
|
||||
}
|
||||
}
|
||||
else // Add all the textures between TX_START and TX_END
|
||||
{
|
||||
numtextures += (UINT32)(texend - texstart);
|
||||
}
|
||||
|
||||
#ifdef WALLFLATS
|
||||
countflats:
|
||||
// Count flats
|
||||
if (wadfiles[w]->type == RET_PK3)
|
||||
{
|
||||
texstart = W_CheckNumForFolderStartPK3("flats/", (UINT16)w, 0);
|
||||
texend = W_CheckNumForFolderEndPK3("flats/", (UINT16)w, texstart);
|
||||
}
|
||||
else
|
||||
{
|
||||
texstart = W_CheckNumForNamePwad("F_START", (UINT16)w, 0);
|
||||
texend = W_CheckNumForNamePwad("F_END", (UINT16)w, texstart);
|
||||
}
|
||||
|
||||
if (texstart == INT16_MAX || texend == INT16_MAX)
|
||||
continue;
|
||||
|
||||
texstart++; // Do not count the first marker
|
||||
|
||||
// PK3s have subfolders, so we can't just make a simple sum
|
||||
if (wadfiles[w]->type == RET_PK3)
|
||||
{
|
||||
for (j = texstart; j < texend; j++)
|
||||
{
|
||||
if (!W_IsLumpFolder((UINT16)w, j)) // Check if lump is a folder; if not, then count it
|
||||
numtextures++;
|
||||
}
|
||||
}
|
||||
else // Add all the textures between F_START and F_END
|
||||
{
|
||||
numtextures += (UINT32)(texend - texstart);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// If no textures found by this point, bomb out
|
||||
if (!numtextures)
|
||||
I_Error("No textures detected in any WADs!\n");
|
||||
|
||||
// Allocate memory and initialize to 0 for all the textures we are initialising.
|
||||
// There are actually 5 buffers allocated in one for convenience.
|
||||
textures = Z_Calloc((numtextures * sizeof(void *)) * 5, PU_STATIC, NULL);
|
||||
texflats = Z_Calloc((numtextures * sizeof(*texflats)), PU_STATIC, NULL);
|
||||
|
||||
// Allocate texture column offset table.
|
||||
texturecolumnofs = (void *)((UINT8 *)textures + (numtextures * sizeof(void *)));
|
||||
// Allocate texture referencing cache.
|
||||
texturecache = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 2));
|
||||
// Allocate texture width table.
|
||||
texturewidth = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 3));
|
||||
// Allocate texture height table.
|
||||
textureheight = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 4));
|
||||
// Create translation table for global animation.
|
||||
texturetranslation = Z_Malloc((numtextures + 1) * sizeof(*texturetranslation), PU_STATIC, NULL);
|
||||
|
||||
for (i = 0; i < numtextures; i++)
|
||||
texturetranslation[i] = i;
|
||||
|
||||
for (i = 0, w = 0; w < numwadfiles; w++)
|
||||
{
|
||||
// Get the lump numbers for the markers in the WAD, if they exist.
|
||||
if (wadfiles[w]->type == RET_PK3)
|
||||
{
|
||||
texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0);
|
||||
texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart);
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
||||
while (texturesLumpPos != INT16_MAX)
|
||||
{
|
||||
R_ParseTEXTURESLump(w, texturesLumpPos, &i);
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0);
|
||||
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
||||
if (texturesLumpPos != INT16_MAX)
|
||||
R_ParseTEXTURESLump(w, texturesLumpPos, &i);
|
||||
}
|
||||
|
||||
if (texstart == INT16_MAX || texend == INT16_MAX)
|
||||
#ifdef WALLFLATS
|
||||
goto checkflats;
|
||||
#else
|
||||
continue;
|
||||
#endif
|
||||
|
||||
texstart++; // Do not count the first marker
|
||||
|
||||
// Work through each lump between the markers in the WAD.
|
||||
for (j = 0; j < (texend - texstart); j++)
|
||||
{
|
||||
UINT16 wadnum = (UINT16)w;
|
||||
lumpnum_t lumpnum = texstart + j;
|
||||
#ifndef NO_PNG_LUMPS
|
||||
size_t lumplength;
|
||||
#endif
|
||||
|
||||
if (wadfiles[w]->type == RET_PK3)
|
||||
{
|
||||
if (W_IsLumpFolder(wadnum, lumpnum)) // Check if lump is a folder
|
||||
continue; // If it is then SKIP IT
|
||||
}
|
||||
|
||||
patchlump = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
|
||||
#ifndef NO_PNG_LUMPS
|
||||
lumplength = W_LumpLengthPwad(wadnum, lumpnum);
|
||||
#endif
|
||||
|
||||
//CONS_Printf("\n\"%s\" is a single patch, dimensions %d x %d",W_CheckNameForNumPwad((UINT16)w,texstart+j),patchlump->width, patchlump->height);
|
||||
texture = textures[i] = Z_Calloc(sizeof(texture_t) + sizeof(texpatch_t), PU_STATIC, NULL);
|
||||
|
||||
// Set texture properties.
|
||||
M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name));
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
if (R_IsLumpPNG((UINT8 *)patchlump, lumplength))
|
||||
{
|
||||
INT16 width, height;
|
||||
R_PNGDimensions((UINT8 *)patchlump, &width, &height, lumplength);
|
||||
texture->width = width;
|
||||
texture->height = height;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
texture->width = SHORT(patchlump->width);
|
||||
texture->height = SHORT(patchlump->height);
|
||||
}
|
||||
|
||||
texture->type = TEXTURETYPE_SINGLEPATCH;
|
||||
texture->patchcount = 1;
|
||||
texture->holes = false;
|
||||
texture->flip = 0;
|
||||
|
||||
// Allocate information for the texture's patches.
|
||||
patch = &texture->patches[0];
|
||||
|
||||
patch->originx = patch->originy = 0;
|
||||
patch->wad = (UINT16)w;
|
||||
patch->lump = texstart + j;
|
||||
patch->flip = 0;
|
||||
|
||||
Z_Unlock(patchlump);
|
||||
|
||||
texturewidth[i] = texture->width;
|
||||
textureheight[i] = texture->height << FRACBITS;
|
||||
i++;
|
||||
}
|
||||
|
||||
#ifdef WALLFLATS
|
||||
checkflats:
|
||||
// Yes
|
||||
if (wadfiles[w]->type == RET_PK3)
|
||||
{
|
||||
texstart = W_CheckNumForFolderStartPK3("flats/", (UINT16)w, 0);
|
||||
texend = W_CheckNumForFolderEndPK3("flats/", (UINT16)w, texstart);
|
||||
}
|
||||
else
|
||||
{
|
||||
texstart = W_CheckNumForNamePwad("F_START", (UINT16)w, 0);
|
||||
texend = W_CheckNumForNamePwad("F_END", (UINT16)w, texstart);
|
||||
}
|
||||
|
||||
if (texstart == INT16_MAX || texend == INT16_MAX)
|
||||
continue;
|
||||
|
||||
texstart++; // Do not count the first marker
|
||||
|
||||
// Work through each lump between the markers in the WAD.
|
||||
|
@ -1029,7 +804,248 @@ checkflats:
|
|||
textureheight[i] = texture->height << FRACBITS;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
#endif/*WALLFLATS*/
|
||||
|
||||
#define TX_START "TX_START"
|
||||
#define TX_END "TX_END"
|
||||
|
||||
static INT32
|
||||
Rloadtextures (INT32 i, INT32 w)
|
||||
{
|
||||
UINT16 j;
|
||||
UINT16 texstart, texend, texturesLumpPos;
|
||||
texture_t *texture;
|
||||
patch_t *patchlump;
|
||||
texpatch_t *patch;
|
||||
|
||||
// Get the lump numbers for the markers in the WAD, if they exist.
|
||||
if (wadfiles[w]->type == RET_PK3)
|
||||
{
|
||||
texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0);
|
||||
texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart);
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
||||
while (texturesLumpPos != INT16_MAX)
|
||||
{
|
||||
R_ParseTEXTURESLump(w, texturesLumpPos, &i);
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0);
|
||||
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
||||
if (texturesLumpPos != INT16_MAX)
|
||||
R_ParseTEXTURESLump(w, texturesLumpPos, &i);
|
||||
}
|
||||
|
||||
if (!( texstart == INT16_MAX || texend == INT16_MAX ))
|
||||
{
|
||||
texstart++; // Do not count the first marker
|
||||
|
||||
// Work through each lump between the markers in the WAD.
|
||||
for (j = 0; j < (texend - texstart); j++)
|
||||
{
|
||||
UINT16 wadnum = (UINT16)w;
|
||||
lumpnum_t lumpnum = texstart + j;
|
||||
#ifndef NO_PNG_LUMPS
|
||||
size_t lumplength;
|
||||
#endif
|
||||
|
||||
if (wadfiles[w]->type == RET_PK3)
|
||||
{
|
||||
if (W_IsLumpFolder(wadnum, lumpnum)) // Check if lump is a folder
|
||||
continue; // If it is then SKIP IT
|
||||
}
|
||||
|
||||
patchlump = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
|
||||
#ifndef NO_PNG_LUMPS
|
||||
lumplength = W_LumpLengthPwad(wadnum, lumpnum);
|
||||
#endif
|
||||
|
||||
//CONS_Printf("\n\"%s\" is a single patch, dimensions %d x %d",W_CheckNameForNumPwad((UINT16)w,texstart+j),patchlump->width, patchlump->height);
|
||||
texture = textures[i] = Z_Calloc(sizeof(texture_t) + sizeof(texpatch_t), PU_STATIC, NULL);
|
||||
|
||||
// Set texture properties.
|
||||
M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name));
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
if (R_IsLumpPNG((UINT8 *)patchlump, lumplength))
|
||||
{
|
||||
INT16 width, height;
|
||||
R_PNGDimensions((UINT8 *)patchlump, &width, &height, lumplength);
|
||||
texture->width = width;
|
||||
texture->height = height;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
texture->width = SHORT(patchlump->width);
|
||||
texture->height = SHORT(patchlump->height);
|
||||
}
|
||||
|
||||
texture->type = TEXTURETYPE_SINGLEPATCH;
|
||||
texture->patchcount = 1;
|
||||
texture->holes = false;
|
||||
texture->flip = 0;
|
||||
|
||||
// Allocate information for the texture's patches.
|
||||
patch = &texture->patches[0];
|
||||
|
||||
patch->originx = patch->originy = 0;
|
||||
patch->wad = (UINT16)w;
|
||||
patch->lump = texstart + j;
|
||||
patch->flip = 0;
|
||||
|
||||
Z_Unlock(patchlump);
|
||||
|
||||
texturewidth[i] = texture->width;
|
||||
textureheight[i] = texture->height << FRACBITS;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
//
|
||||
// R_LoadTextures
|
||||
// Initializes the texture list with the textures from the world map.
|
||||
//
|
||||
void R_LoadTextures(void)
|
||||
{
|
||||
INT32 i, w;
|
||||
UINT16 j;
|
||||
UINT16 texstart, texend, texturesLumpPos;
|
||||
|
||||
// Free previous memory before numtextures change.
|
||||
if (numtextures)
|
||||
{
|
||||
for (i = 0; i < numtextures; i++)
|
||||
{
|
||||
Z_Free(textures[i]);
|
||||
Z_Free(texturecache[i]);
|
||||
}
|
||||
Z_Free(texturetranslation);
|
||||
Z_Free(textures);
|
||||
Z_Free(texflats);
|
||||
}
|
||||
|
||||
// Load patches and textures.
|
||||
|
||||
// Get the number of textures to check.
|
||||
// NOTE: Make SURE the system does not process
|
||||
// the markers.
|
||||
// This system will allocate memory for all duplicate/patched textures even if it never uses them,
|
||||
// but the alternative is to spend a ton of time checking and re-checking all previous entries just to skip any potentially patched textures.
|
||||
for (w = 0, numtextures = 0; w < numwadfiles; w++)
|
||||
{
|
||||
#ifdef WALLFLATS
|
||||
// Count flats
|
||||
if (wadfiles[w]->type == RET_PK3)
|
||||
{
|
||||
texstart = W_CheckNumForFolderStartPK3("flats/", (UINT16)w, 0);
|
||||
texend = W_CheckNumForFolderEndPK3("flats/", (UINT16)w, texstart);
|
||||
}
|
||||
else
|
||||
{
|
||||
texstart = W_CheckNumForNamePwad("F_START", (UINT16)w, 0);
|
||||
texend = W_CheckNumForNamePwad("F_END", (UINT16)w, texstart);
|
||||
}
|
||||
|
||||
if (!( texstart == INT16_MAX || texend == INT16_MAX ))
|
||||
{
|
||||
texstart++; // Do not count the first marker
|
||||
|
||||
// PK3s have subfolders, so we can't just make a simple sum
|
||||
if (wadfiles[w]->type == RET_PK3)
|
||||
{
|
||||
for (j = texstart; j < texend; j++)
|
||||
{
|
||||
if (!W_IsLumpFolder((UINT16)w, j)) // Check if lump is a folder; if not, then count it
|
||||
numtextures++;
|
||||
}
|
||||
}
|
||||
else // Add all the textures between F_START and F_END
|
||||
{
|
||||
numtextures += (UINT32)(texend - texstart);
|
||||
}
|
||||
}
|
||||
#endif/*WALLFLATS*/
|
||||
|
||||
// Count the textures from TEXTURES lumps
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
|
||||
while (texturesLumpPos != INT16_MAX)
|
||||
{
|
||||
numtextures += R_CountTexturesInTEXTURESLump((UINT16)w, (UINT16)texturesLumpPos);
|
||||
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1);
|
||||
}
|
||||
|
||||
// Count single-patch textures
|
||||
if (wadfiles[w]->type == RET_PK3)
|
||||
{
|
||||
texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0);
|
||||
texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart);
|
||||
}
|
||||
else
|
||||
{
|
||||
texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0);
|
||||
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
|
||||
}
|
||||
|
||||
if (texstart == INT16_MAX || texend == INT16_MAX)
|
||||
continue;
|
||||
|
||||
texstart++; // Do not count the first marker
|
||||
|
||||
// PK3s have subfolders, so we can't just make a simple sum
|
||||
if (wadfiles[w]->type == RET_PK3)
|
||||
{
|
||||
for (j = texstart; j < texend; j++)
|
||||
{
|
||||
if (!W_IsLumpFolder((UINT16)w, j)) // Check if lump is a folder; if not, then count it
|
||||
numtextures++;
|
||||
}
|
||||
}
|
||||
else // Add all the textures between TX_START and TX_END
|
||||
{
|
||||
numtextures += (UINT32)(texend - texstart);
|
||||
}
|
||||
}
|
||||
|
||||
// If no textures found by this point, bomb out
|
||||
if (!numtextures)
|
||||
I_Error("No textures detected in any WADs!\n");
|
||||
|
||||
// Allocate memory and initialize to 0 for all the textures we are initialising.
|
||||
// There are actually 5 buffers allocated in one for convenience.
|
||||
textures = Z_Calloc((numtextures * sizeof(void *)) * 5, PU_STATIC, NULL);
|
||||
texflats = Z_Calloc((numtextures * sizeof(*texflats)), PU_STATIC, NULL);
|
||||
|
||||
// Allocate texture column offset table.
|
||||
texturecolumnofs = (void *)((UINT8 *)textures + (numtextures * sizeof(void *)));
|
||||
// Allocate texture referencing cache.
|
||||
texturecache = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 2));
|
||||
// Allocate texture width table.
|
||||
texturewidth = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 3));
|
||||
// Allocate texture height table.
|
||||
textureheight = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 4));
|
||||
// Create translation table for global animation.
|
||||
texturetranslation = Z_Malloc((numtextures + 1) * sizeof(*texturetranslation), PU_STATIC, NULL);
|
||||
|
||||
for (i = 0; i < numtextures; i++)
|
||||
texturetranslation[i] = i;
|
||||
|
||||
for (i = 0, w = 0; w < numwadfiles; w++)
|
||||
{
|
||||
#ifdef WALLFLATS
|
||||
i = Rloadflats(i, w);
|
||||
#endif
|
||||
i = Rloadtextures(i, w);
|
||||
}
|
||||
|
||||
#ifdef HWRENDER
|
||||
|
@ -1783,7 +1799,7 @@ extracolormap_t *R_CreateDefaultColormap(boolean lighttable)
|
|||
extracolormap_t *exc = Z_Calloc(sizeof (*exc), PU_LEVEL, NULL);
|
||||
exc->fadestart = 0;
|
||||
exc->fadeend = 31;
|
||||
exc->fog = 0;
|
||||
exc->flags = 0;
|
||||
exc->rgba = 0;
|
||||
exc->fadergba = 0x19000000;
|
||||
exc->colormap = lighttable ? R_CreateLightTable(exc) : NULL;
|
||||
|
@ -1887,17 +1903,17 @@ void R_AddColormapToList(extracolormap_t *extra_colormap)
|
|||
//
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
boolean R_CheckDefaultColormapByValues(boolean checkrgba, boolean checkfadergba, boolean checkparams,
|
||||
INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog, lumpnum_t lump)
|
||||
INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 flags, lumpnum_t lump)
|
||||
#else
|
||||
boolean R_CheckDefaultColormapByValues(boolean checkrgba, boolean checkfadergba, boolean checkparams,
|
||||
INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog)
|
||||
INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 flags)
|
||||
#endif
|
||||
{
|
||||
return (
|
||||
(!checkparams ? true :
|
||||
(fadestart == 0
|
||||
&& fadeend == 31
|
||||
&& !fog)
|
||||
&& !flags)
|
||||
)
|
||||
&& (!checkrgba ? true : rgba == 0)
|
||||
&& (!checkfadergba ? true : fadergba == 0x19000000)
|
||||
|
@ -1914,9 +1930,9 @@ boolean R_CheckDefaultColormap(extracolormap_t *extra_colormap, boolean checkrgb
|
|||
return true;
|
||||
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
return R_CheckDefaultColormapByValues(checkrgba, checkfadergba, checkparams, extra_colormap->rgba, extra_colormap->fadergba, extra_colormap->fadestart, extra_colormap->fadeend, extra_colormap->fog, extra_colormap->lump);
|
||||
return R_CheckDefaultColormapByValues(checkrgba, checkfadergba, checkparams, extra_colormap->rgba, extra_colormap->fadergba, extra_colormap->fadestart, extra_colormap->fadeend, extra_colormap->flags, extra_colormap->lump);
|
||||
#else
|
||||
return R_CheckDefaultColormapByValues(checkrgba, checkfadergba, checkparams, extra_colormap->rgba, extra_colormap->fadergba, extra_colormap->fadestart, extra_colormap->fadeend, extra_colormap->fog);
|
||||
return R_CheckDefaultColormapByValues(checkrgba, checkfadergba, checkparams, extra_colormap->rgba, extra_colormap->fadergba, extra_colormap->fadestart, extra_colormap->fadeend, extra_colormap->flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1936,7 +1952,7 @@ boolean R_CheckEqualColormaps(extracolormap_t *exc_a, extracolormap_t *exc_b, bo
|
|||
(!checkparams ? true :
|
||||
(exc_a->fadestart == exc_b->fadestart
|
||||
&& exc_a->fadeend == exc_b->fadeend
|
||||
&& exc_a->fog == exc_b->fog)
|
||||
&& exc_a->flags == exc_b->flags)
|
||||
)
|
||||
&& (!checkrgba ? true : exc_a->rgba == exc_b->rgba)
|
||||
&& (!checkfadergba ? true : exc_a->fadergba == exc_b->fadergba)
|
||||
|
@ -1952,9 +1968,9 @@ boolean R_CheckEqualColormaps(extracolormap_t *exc_a, extracolormap_t *exc_b, bo
|
|||
// NOTE: Returns NULL if no match is found
|
||||
//
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
extracolormap_t *R_GetColormapFromListByValues(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog, lumpnum_t lump)
|
||||
extracolormap_t *R_GetColormapFromListByValues(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 flags, lumpnum_t lump)
|
||||
#else
|
||||
extracolormap_t *R_GetColormapFromListByValues(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog)
|
||||
extracolormap_t *R_GetColormapFromListByValues(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 flags)
|
||||
#endif
|
||||
{
|
||||
extracolormap_t *exc;
|
||||
|
@ -1966,7 +1982,7 @@ extracolormap_t *R_GetColormapFromListByValues(INT32 rgba, INT32 fadergba, UINT8
|
|||
&& fadergba == exc->fadergba
|
||||
&& fadestart == exc->fadestart
|
||||
&& fadeend == exc->fadeend
|
||||
&& fog == exc->fog
|
||||
&& flags == exc->flags
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
&& (lump != LUMPERROR && lump == exc->lump)
|
||||
#endif
|
||||
|
@ -1985,9 +2001,9 @@ extracolormap_t *R_GetColormapFromListByValues(INT32 rgba, INT32 fadergba, UINT8
|
|||
extracolormap_t *R_GetColormapFromList(extracolormap_t *extra_colormap)
|
||||
{
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
return R_GetColormapFromListByValues(extra_colormap->rgba, extra_colormap->fadergba, extra_colormap->fadestart, extra_colormap->fadeend, extra_colormap->fog, extra_colormap->lump);
|
||||
return R_GetColormapFromListByValues(extra_colormap->rgba, extra_colormap->fadergba, extra_colormap->fadestart, extra_colormap->fadeend, extra_colormap->flags, extra_colormap->lump);
|
||||
#else
|
||||
return R_GetColormapFromListByValues(extra_colormap->rgba, extra_colormap->fadergba, extra_colormap->fadestart, extra_colormap->fadeend, extra_colormap->fog);
|
||||
return R_GetColormapFromListByValues(extra_colormap->rgba, extra_colormap->fadergba, extra_colormap->fadestart, extra_colormap->fadeend, extra_colormap->flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -2019,7 +2035,7 @@ extracolormap_t *R_ColormapForName(char *name)
|
|||
// is no real way to tell how GL should handle a colormap lump anyway..
|
||||
exc->fadestart = 0;
|
||||
exc->fadeend = 31;
|
||||
exc->fog = 0;
|
||||
exc->flags = 0;
|
||||
exc->rgba = 0;
|
||||
exc->fadergba = 0x19000000;
|
||||
|
||||
|
@ -2176,7 +2192,7 @@ extracolormap_t *R_CreateColormap(char *p1, char *p2, char *p3)
|
|||
// default values
|
||||
UINT8 cr = 0, cg = 0, cb = 0, ca = 0, cfr = 0, cfg = 0, cfb = 0, cfa = 25;
|
||||
UINT32 fadestart = 0, fadeend = 31;
|
||||
UINT8 fog = 0;
|
||||
UINT8 flags = 0;
|
||||
INT32 rgba = 0, fadergba = 0x19000000;
|
||||
|
||||
#define HEX2INT(x) (UINT32)(x >= '0' && x <= '9' ? x - '0' : x >= 'a' && x <= 'f' ? x - 'a' + 10 : x >= 'A' && x <= 'F' ? x - 'A' + 10 : 0)
|
||||
|
@ -2225,12 +2241,12 @@ extracolormap_t *R_CreateColormap(char *p1, char *p2, char *p3)
|
|||
|
||||
#define NUMFROMCHAR(c) (c >= '0' && c <= '9' ? c - '0' : 0)
|
||||
|
||||
// Get parameters like fadestart, fadeend, and the fogflag
|
||||
// Get parameters like fadestart, fadeend, and flags
|
||||
if (p2[0] == '#')
|
||||
{
|
||||
if (p2[1])
|
||||
{
|
||||
fog = NUMFROMCHAR(p2[1]);
|
||||
flags = NUMFROMCHAR(p2[1]);
|
||||
if (p2[2] && p2[3])
|
||||
{
|
||||
fadestart = NUMFROMCHAR(p2[3]) + (NUMFROMCHAR(p2[2]) * 10);
|
||||
|
@ -2297,18 +2313,18 @@ extracolormap_t *R_CreateColormap(char *p1, char *p2, char *p3)
|
|||
|
||||
// Did we just make a default colormap?
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
if (R_CheckDefaultColormapByValues(true, true, true, rgba, fadergba, fadestart, fadeend, fog, LUMPERROR))
|
||||
if (R_CheckDefaultColormapByValues(true, true, true, rgba, fadergba, fadestart, fadeend, flags, LUMPERROR))
|
||||
return NULL;
|
||||
#else
|
||||
if (R_CheckDefaultColormapByValues(true, true, true, rgba, fadergba, fadestart, fadeend, fog))
|
||||
if (R_CheckDefaultColormapByValues(true, true, true, rgba, fadergba, fadestart, fadeend, flags))
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
// Look for existing colormaps
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
exc = R_GetColormapFromListByValues(rgba, fadergba, fadestart, fadeend, fog, LUMPERROR);
|
||||
exc = R_GetColormapFromListByValues(rgba, fadergba, fadestart, fadeend, flags, LUMPERROR);
|
||||
#else
|
||||
exc = R_GetColormapFromListByValues(rgba, fadergba, fadestart, fadeend, fog);
|
||||
exc = R_GetColormapFromListByValues(rgba, fadergba, fadestart, fadeend, flags);
|
||||
#endif
|
||||
if (exc)
|
||||
return exc;
|
||||
|
@ -2320,7 +2336,7 @@ extracolormap_t *R_CreateColormap(char *p1, char *p2, char *p3)
|
|||
|
||||
extra_colormap->fadestart = (UINT16)fadestart;
|
||||
extra_colormap->fadeend = (UINT16)fadeend;
|
||||
extra_colormap->fog = fog;
|
||||
extra_colormap->flags = flags;
|
||||
|
||||
extra_colormap->rgba = rgba;
|
||||
extra_colormap->fadergba = fadergba;
|
||||
|
@ -2347,7 +2363,7 @@ extracolormap_t *R_CreateColormap(char *p1, char *p2, char *p3)
|
|||
extracolormap_t *R_AddColormaps(extracolormap_t *exc_augend, extracolormap_t *exc_addend,
|
||||
boolean subR, boolean subG, boolean subB, boolean subA,
|
||||
boolean subFadeR, boolean subFadeG, boolean subFadeB, boolean subFadeA,
|
||||
boolean subFadeStart, boolean subFadeEnd, boolean ignoreFog,
|
||||
boolean subFadeStart, boolean subFadeEnd, boolean ignoreFlags,
|
||||
boolean useAltAlpha, INT16 altAlpha, INT16 altFadeAlpha,
|
||||
boolean lighttable)
|
||||
{
|
||||
|
@ -2435,8 +2451,8 @@ extracolormap_t *R_AddColormaps(extracolormap_t *exc_augend, extracolormap_t *ex
|
|||
// HACK: fadeend defaults to 31, so don't add anything in this case
|
||||
, 31), 0);
|
||||
|
||||
if (!ignoreFog) // overwrite fog with new value
|
||||
exc_augend->fog = exc_addend->fog;
|
||||
if (!ignoreFlags) // overwrite flags with new value
|
||||
exc_augend->flags = exc_addend->flags;
|
||||
|
||||
///////////////////
|
||||
// put it together
|
||||
|
@ -2449,16 +2465,20 @@ extracolormap_t *R_AddColormaps(extracolormap_t *exc_augend, extracolormap_t *ex
|
|||
|
||||
// Thanks to quake2 source!
|
||||
// utils3/qdata/images.c
|
||||
UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b)
|
||||
UINT8 NearestPaletteColor(UINT8 r, UINT8 g, UINT8 b, RGBA_t *palette)
|
||||
{
|
||||
int dr, dg, db;
|
||||
int distortion, bestdistortion = 256 * 256 * 4, bestcolor = 0, i;
|
||||
|
||||
// Use master palette if none specified
|
||||
if (palette == NULL)
|
||||
palette = pMasterPalette;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
dr = r - pMasterPalette[i].s.red;
|
||||
dg = g - pMasterPalette[i].s.green;
|
||||
db = b - pMasterPalette[i].s.blue;
|
||||
dr = r - palette[i].s.red;
|
||||
dg = g - palette[i].s.green;
|
||||
db = b - palette[i].s.blue;
|
||||
distortion = dr*dr + dg*dg + db*db;
|
||||
if (distortion < bestdistortion)
|
||||
{
|
||||
|
|
13
src/r_data.h
13
src/r_data.h
|
@ -135,12 +135,12 @@ void R_AddColormapToList(extracolormap_t *extra_colormap);
|
|||
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
boolean R_CheckDefaultColormapByValues(boolean checkrgba, boolean checkfadergba, boolean checkparams,
|
||||
INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog, lumpnum_t lump);
|
||||
extracolormap_t *R_GetColormapFromListByValues(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog, lumpnum_t lump);
|
||||
INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 flags, lumpnum_t lump);
|
||||
extracolormap_t *R_GetColormapFromListByValues(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 flags, lumpnum_t lump);
|
||||
#else
|
||||
boolean R_CheckDefaultColormapByValues(boolean checkrgba, boolean checkfadergba, boolean checkparams,
|
||||
INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog);
|
||||
extracolormap_t *R_GetColormapFromListByValues(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog);
|
||||
INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 flags);
|
||||
extracolormap_t *R_GetColormapFromListByValues(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 flags);
|
||||
#endif
|
||||
boolean R_CheckDefaultColormap(extracolormap_t *extra_colormap, boolean checkrgba, boolean checkfadergba, boolean checkparams);
|
||||
boolean R_CheckEqualColormaps(extracolormap_t *exc_a, extracolormap_t *exc_b, boolean checkrgba, boolean checkfadergba, boolean checkparams);
|
||||
|
@ -151,7 +151,7 @@ extracolormap_t *R_CreateColormap(char *p1, char *p2, char *p3);
|
|||
extracolormap_t *R_AddColormaps(extracolormap_t *exc_augend, extracolormap_t *exc_addend,
|
||||
boolean subR, boolean subG, boolean subB, boolean subA,
|
||||
boolean subFadeR, boolean subFadeG, boolean subFadeB, boolean subFadeA,
|
||||
boolean subFadeStart, boolean subFadeEnd, boolean ignoreFog,
|
||||
boolean subFadeStart, boolean subFadeEnd, boolean ignoreFlags,
|
||||
boolean useAltAlpha, INT16 altAlpha, INT16 altFadeAlpha,
|
||||
boolean lighttable);
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
|
@ -171,7 +171,8 @@ const char *R_NameForColormap(extracolormap_t *extra_colormap);
|
|||
#define R_PutRgbaRGB(r, g, b) (R_PutRgbaR(r) + R_PutRgbaG(g) + R_PutRgbaB(b))
|
||||
#define R_PutRgbaRGBA(r, g, b, a) (R_PutRgbaRGB(r, g, b) + R_PutRgbaA(a))
|
||||
|
||||
UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b);
|
||||
UINT8 NearestPaletteColor(UINT8 r, UINT8 g, UINT8 b, RGBA_t *palette);
|
||||
#define NearestColor(r, g, b) NearestPaletteColor(r, g, b, NULL)
|
||||
|
||||
extern INT32 numtextures;
|
||||
|
||||
|
|
|
@ -53,11 +53,14 @@ typedef struct
|
|||
// Could even use more than 32 levels.
|
||||
typedef UINT8 lighttable_t;
|
||||
|
||||
#define CMF_FADEFULLBRIGHTSPRITES 1
|
||||
#define CMF_FOG 4
|
||||
|
||||
// ExtraColormap type. Use for extra_colormaps from now on.
|
||||
typedef struct extracolormap_s
|
||||
{
|
||||
UINT8 fadestart, fadeend;
|
||||
UINT8 fog; // categorical value, not boolean
|
||||
UINT8 flags;
|
||||
|
||||
// store rgba values in combined bitwise
|
||||
// also used in OpenGL instead lighttables
|
||||
|
@ -84,6 +87,8 @@ typedef struct extracolormap_s
|
|||
typedef struct
|
||||
{
|
||||
fixed_t x, y;
|
||||
boolean floorzset, ceilingzset;
|
||||
fixed_t floorz, ceilingz;
|
||||
} vertex_t;
|
||||
|
||||
// Forward of linedefs, for sectors.
|
||||
|
@ -142,7 +147,7 @@ typedef enum
|
|||
FF_QUICKSAND = 0x1000000, ///< Quicksand!
|
||||
FF_PLATFORM = 0x2000000, ///< You can jump up through this to the top.
|
||||
FF_REVERSEPLATFORM = 0x4000000, ///< A fall-through floor in normal gravity, a platform in reverse gravity.
|
||||
FF_INTANGABLEFLATS = 0x6000000, ///< Both flats are intangable, but the sides are still solid.
|
||||
FF_INTANGIBLEFLATS = 0x6000000, ///< Both flats are intangible, but the sides are still solid.
|
||||
FF_SHATTER = 0x8000000, ///< Used with ::FF_BUSTUP. Bustable on mere touch.
|
||||
FF_SPINBUST = 0x10000000, ///< Used with ::FF_BUSTUP. Also bustable if you're in your spinning frames.
|
||||
FF_STRONGBUST = 0x20000000, ///< Used with ::FF_BUSTUP. Only bustable by "strong" characters (Knuckles) and abilities (bouncing, twinspin, melee).
|
||||
|
|
|
@ -644,6 +644,7 @@ void R_CalcTiltedLighting(fixed_t start, fixed_t end)
|
|||
}
|
||||
}
|
||||
|
||||
#define PLANELIGHTFLOAT (BASEVIDWIDTH * BASEVIDWIDTH / vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f * FIXED_TO_FLOAT(fovtan))
|
||||
|
||||
/** \brief The R_DrawTiltedSpan_8 function
|
||||
Draw slopes! Holy sheit!
|
||||
|
@ -669,7 +670,7 @@ void R_DrawTiltedSpan_8(void)
|
|||
|
||||
// Lighting is simple. It's just linear interpolation from start to end
|
||||
{
|
||||
float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f;
|
||||
float planelightfloat = PLANELIGHTFLOAT;
|
||||
float lightstart, lightend;
|
||||
|
||||
lightend = (iz + ds_szp->x*width) * planelightfloat;
|
||||
|
@ -805,7 +806,7 @@ void R_DrawTiltedTranslucentSpan_8(void)
|
|||
|
||||
// Lighting is simple. It's just linear interpolation from start to end
|
||||
{
|
||||
float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f;
|
||||
float planelightfloat = PLANELIGHTFLOAT;
|
||||
float lightstart, lightend;
|
||||
|
||||
lightend = (iz + ds_szp->x*width) * planelightfloat;
|
||||
|
@ -942,7 +943,7 @@ void R_DrawTiltedTranslucentWaterSpan_8(void)
|
|||
|
||||
// Lighting is simple. It's just linear interpolation from start to end
|
||||
{
|
||||
float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f;
|
||||
float planelightfloat = PLANELIGHTFLOAT;
|
||||
float lightstart, lightend;
|
||||
|
||||
lightend = (iz + ds_szp->x*width) * planelightfloat;
|
||||
|
@ -1078,7 +1079,7 @@ void R_DrawTiltedSplat_8(void)
|
|||
|
||||
// Lighting is simple. It's just linear interpolation from start to end
|
||||
{
|
||||
float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f;
|
||||
float planelightfloat = PLANELIGHTFLOAT;
|
||||
float lightstart, lightend;
|
||||
|
||||
lightend = (iz + ds_szp->x*width) * planelightfloat;
|
||||
|
|
|
@ -62,6 +62,9 @@ void R_DrawSpan_NPO2_8 (void)
|
|||
}
|
||||
|
||||
#ifdef ESLOPE
|
||||
|
||||
#define PLANELIGHTFLOAT (BASEVIDWIDTH * BASEVIDWIDTH / vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f * FIXED_TO_FLOAT(fovtan))
|
||||
|
||||
/** \brief The R_DrawTiltedSpan_NPO2_8 function
|
||||
Draw slopes! Holy sheit!
|
||||
*/
|
||||
|
@ -86,7 +89,7 @@ void R_DrawTiltedSpan_NPO2_8(void)
|
|||
|
||||
// Lighting is simple. It's just linear interpolation from start to end
|
||||
{
|
||||
float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f;
|
||||
float planelightfloat = PLANELIGHTFLOAT;
|
||||
float lightstart, lightend;
|
||||
|
||||
lightend = (iz + ds_szp->x*width) * planelightfloat;
|
||||
|
@ -282,7 +285,7 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void)
|
|||
|
||||
// Lighting is simple. It's just linear interpolation from start to end
|
||||
{
|
||||
float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f;
|
||||
float planelightfloat = PLANELIGHTFLOAT;
|
||||
float lightstart, lightend;
|
||||
|
||||
lightend = (iz + ds_szp->x*width) * planelightfloat;
|
||||
|
@ -476,7 +479,7 @@ void R_DrawTiltedSplat_NPO2_8(void)
|
|||
|
||||
// Lighting is simple. It's just linear interpolation from start to end
|
||||
{
|
||||
float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f;
|
||||
float planelightfloat = PLANELIGHTFLOAT;
|
||||
float lightstart, lightend;
|
||||
|
||||
lightend = (iz + ds_szp->x*width) * planelightfloat;
|
||||
|
@ -869,7 +872,7 @@ void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void)
|
|||
|
||||
// Lighting is simple. It's just linear interpolation from start to end
|
||||
{
|
||||
float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f;
|
||||
float planelightfloat = PLANELIGHTFLOAT;
|
||||
float lightstart, lightend;
|
||||
|
||||
lightend = (iz + ds_szp->x*width) * planelightfloat;
|
||||
|
|
421
src/r_main.c
421
src/r_main.c
|
@ -59,6 +59,7 @@ INT32 centerx, centery;
|
|||
fixed_t centerxfrac, centeryfrac;
|
||||
fixed_t projection;
|
||||
fixed_t projectiony; // aspect ratio
|
||||
fixed_t fovtan; // field of view
|
||||
|
||||
// just for profiling purposes
|
||||
size_t framecount;
|
||||
|
@ -70,6 +71,7 @@ angle_t viewangle, aimingangle;
|
|||
fixed_t viewcos, viewsin;
|
||||
sector_t *viewsector;
|
||||
player_t *viewplayer;
|
||||
mobj_t *r_viewmobj;
|
||||
|
||||
//
|
||||
// precalculated math tables
|
||||
|
@ -108,10 +110,12 @@ static CV_PossibleValue_t drawdist_precip_cons_t[] = {
|
|||
{1024, "1024"}, {1536, "1536"}, {2048, "2048"},
|
||||
{0, "None"}, {0, NULL}};
|
||||
|
||||
static CV_PossibleValue_t fov_cons_t[] = {{60*FRACUNIT, "MIN"}, {179*FRACUNIT, "MAX"}, {0, NULL}};
|
||||
static CV_PossibleValue_t translucenthud_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}};
|
||||
static CV_PossibleValue_t maxportals_cons_t[] = {{0, "MIN"}, {12, "MAX"}, {0, NULL}}; // lmao rendering 32 portals, you're a card
|
||||
static CV_PossibleValue_t homremoval_cons_t[] = {{0, "No"}, {1, "Yes"}, {2, "Flash"}, {0, NULL}};
|
||||
|
||||
static void Fov_OnChange(void);
|
||||
static void ChaseCam_OnChange(void);
|
||||
static void ChaseCam2_OnChange(void);
|
||||
static void FlipCam_OnChange(void);
|
||||
|
@ -125,12 +129,7 @@ consvar_t cv_chasecam2 = {"chasecam2", "On", CV_CALL, CV_OnOff, ChaseCam2_OnChan
|
|||
consvar_t cv_flipcam = {"flipcam", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, FlipCam_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_flipcam2 = {"flipcam2", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, FlipCam2_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
#if defined(FLOORSPLATS) || defined(GLBADSHADOWS)
|
||||
consvar_t cv_shadow = {"shadow", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
#endif //#if defined(FLOORSPLATS) || defined(GLBADSHADOWS)
|
||||
#ifdef GLBADSHADOWS
|
||||
consvar_t cv_shadowoffs = {"offsetshadows", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
#endif //#ifdef GLBADSHADOWS
|
||||
consvar_t cv_shadow = {"shadow", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_skybox = {"skybox", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_allowmlook = {"allowmlook", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_showhud = {"showhud", "Yes", CV_CALL, CV_YesNo, R_SetViewSize, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
@ -141,6 +140,7 @@ consvar_t cv_drawdist = {"drawdist", "Infinite", CV_SAVE, drawdist_cons_t, NULL,
|
|||
consvar_t cv_drawdist_nights = {"drawdist_nights", "2048", CV_SAVE, drawdist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_drawdist_precip = {"drawdist_precip", "1024", CV_SAVE, drawdist_precip_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
//consvar_t cv_precipdensity = {"precipdensity", "Moderate", CV_SAVE, precipdensity_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_fov = {"fov", "90", CV_FLOAT|CV_CALL, fov_cons_t, Fov_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// Okay, whoever said homremoval causes a performance hit should be shot.
|
||||
consvar_t cv_homremoval = {"homremoval", "No", CV_SAVE, homremoval_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
@ -184,6 +184,14 @@ void SplitScreen_OnChange(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
static void Fov_OnChange(void)
|
||||
{
|
||||
// Shouldn't be needed with render parity?
|
||||
//if ((netgame || multiplayer) && !cv_debug && cv_fov.value != 90*FRACUNIT)
|
||||
// CV_Set(&cv_fov, cv_fov.defaultvalue);
|
||||
|
||||
R_SetViewSize();
|
||||
}
|
||||
|
||||
static void ChaseCam_OnChange(void)
|
||||
{
|
||||
|
@ -448,8 +456,8 @@ static void R_InitTextureMapping(void)
|
|||
//
|
||||
// Calc focallength
|
||||
// so FIELDOFVIEW angles covers SCREENWIDTH.
|
||||
focallength = FixedDiv(centerxfrac,
|
||||
FINETANGENT(FINEANGLES/4+/*cv_fov.value*/ FIELDOFVIEW/2));
|
||||
focallength = FixedDiv(projection,
|
||||
FINETANGENT(FINEANGLES/4+FIELDOFVIEW/2));
|
||||
|
||||
#ifdef ESLOPE
|
||||
focallengthf = FIXED_TO_FLOAT(focallength);
|
||||
|
@ -457,9 +465,9 @@ static void R_InitTextureMapping(void)
|
|||
|
||||
for (i = 0; i < FINEANGLES/2; i++)
|
||||
{
|
||||
if (FINETANGENT(i) > FRACUNIT*2)
|
||||
if (FINETANGENT(i) > fovtan*2)
|
||||
t = -1;
|
||||
else if (FINETANGENT(i) < -FRACUNIT*2)
|
||||
else if (FINETANGENT(i) < -fovtan*2)
|
||||
t = viewwidth+1;
|
||||
else
|
||||
{
|
||||
|
@ -539,6 +547,303 @@ static inline void R_InitLightTables(void)
|
|||
}
|
||||
}
|
||||
|
||||
//#define WOUGHMP_WOUGHMP // I got a fish-eye lens - I'll make a rap video with a couple of friends
|
||||
// it's kinda laggy sometimes
|
||||
|
||||
static struct {
|
||||
angle_t rollangle; // pre-shifted by fineshift
|
||||
#ifdef WOUGHMP_WOUGHMP
|
||||
fixed_t fisheye;
|
||||
#endif
|
||||
|
||||
fixed_t zoomneeded;
|
||||
INT32 *scrmap;
|
||||
INT32 scrmapsize;
|
||||
|
||||
INT32 x1; // clip rendering horizontally for efficiency
|
||||
INT16 ceilingclip[MAXVIDWIDTH], floorclip[MAXVIDWIDTH];
|
||||
|
||||
boolean use;
|
||||
} viewmorph = {
|
||||
0,
|
||||
#ifdef WOUGHMP_WOUGHMP
|
||||
0,
|
||||
#endif
|
||||
|
||||
FRACUNIT,
|
||||
NULL,
|
||||
0,
|
||||
|
||||
0,
|
||||
{}, {},
|
||||
|
||||
false
|
||||
};
|
||||
|
||||
void R_CheckViewMorph(void)
|
||||
{
|
||||
float zoomfactor, rollcos, rollsin;
|
||||
float x1, y1, x2, y2;
|
||||
fixed_t temp;
|
||||
INT32 end, vx, vy, pos, usedpos;
|
||||
INT32 usedx, usedy, halfwidth = vid.width/2, halfheight = vid.height/2;
|
||||
#ifdef WOUGHMP_WOUGHMP
|
||||
float fisheyemap[MAXVIDWIDTH/2 + 1];
|
||||
#endif
|
||||
|
||||
angle_t rollangle = players[displayplayer].viewrollangle;
|
||||
#ifdef WOUGHMP_WOUGHMP
|
||||
fixed_t fisheye = cv_cam2_turnmultiplier.value; // temporary test value
|
||||
#endif
|
||||
|
||||
rollangle >>= ANGLETOFINESHIFT;
|
||||
rollangle = ((rollangle+2) & ~3) & FINEMASK; // Limit the distinct number of angles to reduce recalcs from angles changing a lot.
|
||||
|
||||
#ifdef WOUGHMP_WOUGHMP
|
||||
fisheye &= ~0x7FF; // Same
|
||||
#endif
|
||||
|
||||
if (rollangle == viewmorph.rollangle &&
|
||||
#ifdef WOUGHMP_WOUGHMP
|
||||
fisheye == viewmorph.fisheye &&
|
||||
#endif
|
||||
viewmorph.scrmapsize == vid.width*vid.height)
|
||||
return; // No change
|
||||
|
||||
viewmorph.rollangle = rollangle;
|
||||
#ifdef WOUGHMP_WOUGHMP
|
||||
viewmorph.fisheye = fisheye;
|
||||
#endif
|
||||
|
||||
if (viewmorph.rollangle == 0
|
||||
#ifdef WOUGHMP_WOUGHMP
|
||||
&& viewmorph.fisheye == 0
|
||||
#endif
|
||||
)
|
||||
{
|
||||
viewmorph.use = false;
|
||||
viewmorph.x1 = 0;
|
||||
if (viewmorph.zoomneeded != FRACUNIT)
|
||||
R_SetViewSize();
|
||||
viewmorph.zoomneeded = FRACUNIT;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (viewmorph.scrmapsize != vid.width*vid.height)
|
||||
{
|
||||
if (viewmorph.scrmap)
|
||||
free(viewmorph.scrmap);
|
||||
viewmorph.scrmap = malloc(vid.width*vid.height * sizeof(INT32));
|
||||
viewmorph.scrmapsize = vid.width*vid.height;
|
||||
}
|
||||
|
||||
temp = FINECOSINE(rollangle);
|
||||
rollcos = FIXED_TO_FLOAT(temp);
|
||||
temp = FINESINE(rollangle);
|
||||
rollsin = FIXED_TO_FLOAT(temp);
|
||||
|
||||
// Calculate maximum zoom needed
|
||||
x1 = (vid.width*fabsf(rollcos) + vid.height*fabsf(rollsin)) / vid.width;
|
||||
y1 = (vid.height*fabsf(rollcos) + vid.width*fabsf(rollsin)) / vid.height;
|
||||
|
||||
#ifdef WOUGHMP_WOUGHMP
|
||||
if (fisheye)
|
||||
{
|
||||
float f = FIXED_TO_FLOAT(fisheye);
|
||||
for (vx = 0; vx <= halfwidth; vx++)
|
||||
fisheyemap[vx] = 1.0f / cos(atan(vx * f / halfwidth));
|
||||
|
||||
f = cos(atan(f));
|
||||
if (f < 1.0f)
|
||||
{
|
||||
x1 /= f;
|
||||
y1 /= f;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
temp = max(x1, y1)*FRACUNIT;
|
||||
if (temp < FRACUNIT)
|
||||
temp = FRACUNIT;
|
||||
else
|
||||
temp |= 0x3FFF; // Limit how many times the viewport needs to be recalculated
|
||||
|
||||
//CONS_Printf("Setting zoom to %f\n", FIXED_TO_FLOAT(temp));
|
||||
|
||||
if (temp != viewmorph.zoomneeded)
|
||||
{
|
||||
viewmorph.zoomneeded = temp;
|
||||
R_SetViewSize();
|
||||
}
|
||||
|
||||
zoomfactor = FIXED_TO_FLOAT(viewmorph.zoomneeded);
|
||||
|
||||
end = vid.width * vid.height - 1;
|
||||
|
||||
pos = 0;
|
||||
|
||||
// Pre-multiply rollcos and rollsin to use for positional stuff
|
||||
rollcos /= zoomfactor;
|
||||
rollsin /= zoomfactor;
|
||||
|
||||
x1 = -(halfwidth * rollcos - halfheight * rollsin);
|
||||
y1 = -(halfheight * rollcos + halfwidth * rollsin);
|
||||
|
||||
#ifdef WOUGHMP_WOUGHMP
|
||||
if (fisheye)
|
||||
viewmorph.x1 = (INT32)(halfwidth - (halfwidth * fabsf(rollcos) + halfheight * fabsf(rollsin)) * fisheyemap[halfwidth]);
|
||||
else
|
||||
#endif
|
||||
viewmorph.x1 = (INT32)(halfwidth - (halfwidth * fabsf(rollcos) + halfheight * fabsf(rollsin)));
|
||||
//CONS_Printf("saving %d cols\n", viewmorph.x1);
|
||||
|
||||
// Set ceilingclip and floorclip
|
||||
for (vx = 0; vx < vid.width; vx++)
|
||||
{
|
||||
viewmorph.ceilingclip[vx] = vid.height;
|
||||
viewmorph.floorclip[vx] = -1;
|
||||
}
|
||||
x2 = x1;
|
||||
y2 = y1;
|
||||
for (vx = 0; vx < vid.width; vx++)
|
||||
{
|
||||
INT16 xa, ya, xb, yb;
|
||||
xa = x2+halfwidth;
|
||||
ya = y2+halfheight-1;
|
||||
xb = vid.width-1-xa;
|
||||
yb = vid.height-1-ya;
|
||||
|
||||
viewmorph.ceilingclip[xa] = min(viewmorph.ceilingclip[xa], ya);
|
||||
viewmorph.floorclip[xa] = max(viewmorph.floorclip[xa], ya);
|
||||
viewmorph.ceilingclip[xb] = min(viewmorph.ceilingclip[xb], yb);
|
||||
viewmorph.floorclip[xb] = max(viewmorph.floorclip[xb], yb);
|
||||
x2 += rollcos;
|
||||
y2 += rollsin;
|
||||
}
|
||||
x2 = x1;
|
||||
y2 = y1;
|
||||
for (vy = 0; vy < vid.height; vy++)
|
||||
{
|
||||
INT16 xa, ya, xb, yb;
|
||||
xa = x2+halfwidth;
|
||||
ya = y2+halfheight;
|
||||
xb = vid.width-1-xa;
|
||||
yb = vid.height-1-ya;
|
||||
|
||||
viewmorph.ceilingclip[xa] = min(viewmorph.ceilingclip[xa], ya);
|
||||
viewmorph.floorclip[xa] = max(viewmorph.floorclip[xa], ya);
|
||||
viewmorph.ceilingclip[xb] = min(viewmorph.ceilingclip[xb], yb);
|
||||
viewmorph.floorclip[xb] = max(viewmorph.floorclip[xb], yb);
|
||||
x2 -= rollsin;
|
||||
y2 += rollcos;
|
||||
}
|
||||
|
||||
//CONS_Printf("Top left corner is %f %f\n", x1, y1);
|
||||
|
||||
#ifdef WOUGHMP_WOUGHMP
|
||||
if (fisheye)
|
||||
{
|
||||
for (vy = 0; vy < halfheight; vy++)
|
||||
{
|
||||
x2 = x1;
|
||||
y2 = y1;
|
||||
x1 -= rollsin;
|
||||
y1 += rollcos;
|
||||
|
||||
for (vx = 0; vx < vid.width; vx++)
|
||||
{
|
||||
usedx = halfwidth + x2*fisheyemap[(int) floorf(fabsf(y2*zoomfactor))];
|
||||
usedy = halfheight + y2*fisheyemap[(int) floorf(fabsf(x2*zoomfactor))];
|
||||
|
||||
usedpos = usedx + usedy*vid.width;
|
||||
|
||||
viewmorph.scrmap[pos] = usedpos;
|
||||
viewmorph.scrmap[end-pos] = end-usedpos;
|
||||
|
||||
x2 += rollcos;
|
||||
y2 += rollsin;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
x1 += halfwidth;
|
||||
y1 += halfheight;
|
||||
|
||||
for (vy = 0; vy < halfheight; vy++)
|
||||
{
|
||||
x2 = x1;
|
||||
y2 = y1;
|
||||
x1 -= rollsin;
|
||||
y1 += rollcos;
|
||||
|
||||
for (vx = 0; vx < vid.width; vx++)
|
||||
{
|
||||
usedx = x2;
|
||||
usedy = y2;
|
||||
|
||||
usedpos = usedx + usedy*vid.width;
|
||||
|
||||
viewmorph.scrmap[pos] = usedpos;
|
||||
viewmorph.scrmap[end-pos] = end-usedpos;
|
||||
|
||||
x2 += rollcos;
|
||||
y2 += rollsin;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
#ifdef WOUGHMP_WOUGHMP
|
||||
}
|
||||
#endif
|
||||
|
||||
viewmorph.use = true;
|
||||
}
|
||||
|
||||
void R_ApplyViewMorph(void)
|
||||
{
|
||||
UINT8 *tmpscr = screens[4];
|
||||
UINT8 *srcscr = screens[0];
|
||||
INT32 p, end = vid.width * vid.height;
|
||||
|
||||
if (!viewmorph.use)
|
||||
return;
|
||||
|
||||
if (cv_debug & DBG_VIEWMORPH)
|
||||
{
|
||||
UINT8 border = 32;
|
||||
UINT8 grid = 160;
|
||||
INT32 ws = vid.width / 4;
|
||||
INT32 hs = vid.width * (vid.height / 4);
|
||||
|
||||
memcpy(tmpscr, srcscr, vid.width*vid.height);
|
||||
for (p = 0; p < vid.width; p++)
|
||||
{
|
||||
tmpscr[viewmorph.scrmap[p]] = border;
|
||||
tmpscr[viewmorph.scrmap[p + hs]] = grid;
|
||||
tmpscr[viewmorph.scrmap[p + hs*2]] = grid;
|
||||
tmpscr[viewmorph.scrmap[p + hs*3]] = grid;
|
||||
tmpscr[viewmorph.scrmap[end - 1 - p]] = border;
|
||||
}
|
||||
for (p = vid.width; p < end; p += vid.width)
|
||||
{
|
||||
tmpscr[viewmorph.scrmap[p]] = border;
|
||||
tmpscr[viewmorph.scrmap[p + ws]] = grid;
|
||||
tmpscr[viewmorph.scrmap[p + ws*2]] = grid;
|
||||
tmpscr[viewmorph.scrmap[p + ws*3]] = grid;
|
||||
tmpscr[viewmorph.scrmap[end - 1 - p]] = border;
|
||||
}
|
||||
}
|
||||
else
|
||||
for (p = 0; p < end; p++)
|
||||
tmpscr[p] = srcscr[viewmorph.scrmap[p]];
|
||||
|
||||
VID_BlitLinearScreen(tmpscr, screens[0],
|
||||
vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.width);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// R_SetViewSize
|
||||
|
@ -563,6 +868,7 @@ void R_ExecuteSetViewSize(void)
|
|||
INT32 j;
|
||||
INT32 level;
|
||||
INT32 startmapl;
|
||||
angle_t fov;
|
||||
|
||||
setsizeneeded = false;
|
||||
|
||||
|
@ -585,9 +891,12 @@ void R_ExecuteSetViewSize(void)
|
|||
centerxfrac = centerx<<FRACBITS;
|
||||
centeryfrac = centery<<FRACBITS;
|
||||
|
||||
projection = centerxfrac;
|
||||
//projectiony = (((vid.height*centerx*BASEVIDWIDTH)/BASEVIDHEIGHT)/vid.width)<<FRACBITS;
|
||||
projectiony = centerxfrac;
|
||||
fov = FixedAngle(cv_fov.value/2) + ANGLE_90;
|
||||
fovtan = FixedMul(FINETANGENT(fov >> ANGLETOFINESHIFT), viewmorph.zoomneeded);
|
||||
if (splitscreen == 1) // Splitscreen FOV should be adjusted to maintain expected vertical view
|
||||
fovtan = 17*fovtan/10;
|
||||
|
||||
projection = projectiony = FixedDiv(centerxfrac, fovtan);
|
||||
|
||||
R_InitViewBuffer(scaledviewwidth, viewheight);
|
||||
|
||||
|
@ -613,7 +922,7 @@ void R_ExecuteSetViewSize(void)
|
|||
for (i = 0; i < j; i++)
|
||||
{
|
||||
dy = ((i - viewheight*8)<<FRACBITS) + FRACUNIT/2;
|
||||
dy = abs(dy);
|
||||
dy = FixedMul(abs(dy), fovtan);
|
||||
yslopetab[i] = FixedDiv(centerx*FRACUNIT, dy);
|
||||
}
|
||||
}
|
||||
|
@ -690,9 +999,9 @@ subsector_t *R_PointInSubsector(fixed_t x, fixed_t y)
|
|||
}
|
||||
|
||||
//
|
||||
// R_IsPointInSubsector, same as above but returns 0 if not in subsector
|
||||
// R_PointInSubsectorOrNull, same as above but returns 0 if not in subsector
|
||||
//
|
||||
subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y)
|
||||
subsector_t *R_PointInSubsectorOrNull(fixed_t x, fixed_t y)
|
||||
{
|
||||
node_t *node;
|
||||
INT32 side, i;
|
||||
|
@ -731,10 +1040,8 @@ subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y)
|
|||
// R_SetupFrame
|
||||
//
|
||||
|
||||
static mobj_t *viewmobj;
|
||||
|
||||
// WARNING: a should be unsigned but to add with 2048, it isn't!
|
||||
#define AIMINGTODY(a) ((FINETANGENT((2048+(((INT32)a)>>ANGLETOFINESHIFT)) & FINEMASK)*160)>>FRACBITS)
|
||||
#define AIMINGTODY(a) ((FINETANGENT((2048+(((INT32)a)>>ANGLETOFINESHIFT)) & FINEMASK)*160)/fovtan)
|
||||
|
||||
// recalc necessary stuff for mouseaiming
|
||||
// slopes are already calculated for the full possible view (which is 4*viewheight).
|
||||
|
@ -789,16 +1096,16 @@ void R_SetupFrame(player_t *player)
|
|||
if (player->awayviewtics)
|
||||
{
|
||||
// cut-away view stuff
|
||||
viewmobj = player->awayviewmobj; // should be a MT_ALTVIEWMAN
|
||||
I_Assert(viewmobj != NULL);
|
||||
viewz = viewmobj->z + 20*FRACUNIT;
|
||||
r_viewmobj = player->awayviewmobj; // should be a MT_ALTVIEWMAN
|
||||
I_Assert(r_viewmobj != NULL);
|
||||
viewz = r_viewmobj->z + 20*FRACUNIT;
|
||||
aimingangle = player->awayviewaiming;
|
||||
viewangle = viewmobj->angle;
|
||||
viewangle = r_viewmobj->angle;
|
||||
}
|
||||
else if (!player->spectator && chasecam)
|
||||
// use outside cam view
|
||||
{
|
||||
viewmobj = NULL;
|
||||
r_viewmobj = NULL;
|
||||
viewz = thiscam->z + (thiscam->height>>1);
|
||||
aimingangle = thiscam->aiming;
|
||||
viewangle = thiscam->angle;
|
||||
|
@ -808,11 +1115,11 @@ void R_SetupFrame(player_t *player)
|
|||
{
|
||||
viewz = player->viewz;
|
||||
|
||||
viewmobj = player->mo;
|
||||
I_Assert(viewmobj != NULL);
|
||||
r_viewmobj = player->mo;
|
||||
I_Assert(r_viewmobj != NULL);
|
||||
|
||||
aimingangle = player->aiming;
|
||||
viewangle = viewmobj->angle;
|
||||
viewangle = r_viewmobj->angle;
|
||||
|
||||
if (!demoplayback && player->playerstate != PST_DEAD)
|
||||
{
|
||||
|
@ -846,13 +1153,13 @@ void R_SetupFrame(player_t *player)
|
|||
}
|
||||
else
|
||||
{
|
||||
viewx = viewmobj->x;
|
||||
viewy = viewmobj->y;
|
||||
viewx = r_viewmobj->x;
|
||||
viewy = r_viewmobj->y;
|
||||
viewx += quake.x;
|
||||
viewy += quake.y;
|
||||
|
||||
if (viewmobj->subsector)
|
||||
viewsector = viewmobj->subsector->sector;
|
||||
if (r_viewmobj->subsector)
|
||||
viewsector = r_viewmobj->subsector->sector;
|
||||
else
|
||||
viewsector = R_PointInSubsector(viewx, viewy)->sector;
|
||||
}
|
||||
|
@ -874,12 +1181,12 @@ void R_SkyboxFrame(player_t *player)
|
|||
thiscam = &camera;
|
||||
|
||||
// cut-away view stuff
|
||||
viewmobj = skyboxmo[0];
|
||||
r_viewmobj = skyboxmo[0];
|
||||
#ifdef PARANOIA
|
||||
if (!viewmobj)
|
||||
if (!r_viewmobj)
|
||||
{
|
||||
const size_t playeri = (size_t)(player - players);
|
||||
I_Error("R_SkyboxFrame: viewmobj null (player %s)", sizeu1(playeri));
|
||||
I_Error("R_SkyboxFrame: r_viewmobj null (player %s)", sizeu1(playeri));
|
||||
}
|
||||
#endif
|
||||
if (player->awayviewtics)
|
||||
|
@ -910,13 +1217,13 @@ void R_SkyboxFrame(player_t *player)
|
|||
}
|
||||
}
|
||||
}
|
||||
viewangle += viewmobj->angle;
|
||||
viewangle += r_viewmobj->angle;
|
||||
|
||||
viewplayer = player;
|
||||
|
||||
viewx = viewmobj->x;
|
||||
viewy = viewmobj->y;
|
||||
viewz = viewmobj->z; // 26/04/17: use actual Z position instead of spawnpoint angle!
|
||||
viewx = r_viewmobj->x;
|
||||
viewy = r_viewmobj->y;
|
||||
viewz = r_viewmobj->z; // 26/04/17: use actual Z position instead of spawnpoint angle!
|
||||
|
||||
if (mapheaderinfo[gamemap-1])
|
||||
{
|
||||
|
@ -956,29 +1263,29 @@ void R_SkyboxFrame(player_t *player)
|
|||
else if (mh->skybox_scaley < 0)
|
||||
y = (campos.y - skyboxmo[1]->y) * -mh->skybox_scaley;
|
||||
|
||||
if (viewmobj->angle == 0)
|
||||
if (r_viewmobj->angle == 0)
|
||||
{
|
||||
viewx += x;
|
||||
viewy += y;
|
||||
}
|
||||
else if (viewmobj->angle == ANGLE_90)
|
||||
else if (r_viewmobj->angle == ANGLE_90)
|
||||
{
|
||||
viewx -= y;
|
||||
viewy += x;
|
||||
}
|
||||
else if (viewmobj->angle == ANGLE_180)
|
||||
else if (r_viewmobj->angle == ANGLE_180)
|
||||
{
|
||||
viewx -= x;
|
||||
viewy -= y;
|
||||
}
|
||||
else if (viewmobj->angle == ANGLE_270)
|
||||
else if (r_viewmobj->angle == ANGLE_270)
|
||||
{
|
||||
viewx += y;
|
||||
viewy -= x;
|
||||
}
|
||||
else
|
||||
{
|
||||
angle_t ang = viewmobj->angle>>ANGLETOFINESHIFT;
|
||||
angle_t ang = r_viewmobj->angle>>ANGLETOFINESHIFT;
|
||||
viewx += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang));
|
||||
viewy += FixedMul(x, FINESINE(ang)) + FixedMul(y,FINECOSINE(ang));
|
||||
}
|
||||
|
@ -989,8 +1296,8 @@ void R_SkyboxFrame(player_t *player)
|
|||
viewz += campos.z * -mh->skybox_scalez;
|
||||
}
|
||||
|
||||
if (viewmobj->subsector)
|
||||
viewsector = viewmobj->subsector->sector;
|
||||
if (r_viewmobj->subsector)
|
||||
viewsector = r_viewmobj->subsector->sector;
|
||||
else
|
||||
viewsector = R_PointInSubsector(viewx, viewy)->sector;
|
||||
|
||||
|
@ -1071,9 +1378,22 @@ void R_RenderPlayerView(player_t *player)
|
|||
validcount++;
|
||||
|
||||
// Clear buffers.
|
||||
R_ClearClipSegs();
|
||||
R_ClearDrawSegs();
|
||||
R_ClearPlanes();
|
||||
if (viewmorph.use)
|
||||
{
|
||||
portalclipstart = viewmorph.x1;
|
||||
portalclipend = viewwidth-viewmorph.x1-1;
|
||||
R_PortalClearClipSegs(portalclipstart, portalclipend);
|
||||
memcpy(ceilingclip, viewmorph.ceilingclip, sizeof(INT16)*vid.width);
|
||||
memcpy(floorclip, viewmorph.floorclip, sizeof(INT16)*vid.width);
|
||||
}
|
||||
else
|
||||
{
|
||||
portalclipstart = 0;
|
||||
portalclipend = viewwidth-1;
|
||||
R_ClearClipSegs();
|
||||
}
|
||||
R_ClearDrawSegs();
|
||||
R_ClearSprites();
|
||||
#ifdef FLOORSPLATS
|
||||
R_ClearVisibleFloorSplats();
|
||||
|
@ -1203,15 +1523,12 @@ void R_RegisterEngineStuff(void)
|
|||
CV_RegisterVar(&cv_drawdist);
|
||||
CV_RegisterVar(&cv_drawdist_nights);
|
||||
CV_RegisterVar(&cv_drawdist_precip);
|
||||
CV_RegisterVar(&cv_fov);
|
||||
|
||||
CV_RegisterVar(&cv_chasecam);
|
||||
CV_RegisterVar(&cv_chasecam2);
|
||||
#if defined(FLOORSPLATS) || defined(GLBADSHADOWS)
|
||||
|
||||
CV_RegisterVar(&cv_shadow);
|
||||
#endif //#if defined(FLOORSPLATS) || defined(GLBADSHADOWS)
|
||||
#ifdef GLBADSHADOWS
|
||||
CV_RegisterVar(&cv_shadowoffs);
|
||||
#endif //#ifdef GLBADSHADOWS
|
||||
CV_RegisterVar(&cv_skybox);
|
||||
|
||||
CV_RegisterVar(&cv_cam_dist);
|
||||
|
|
15
src/r_main.h
15
src/r_main.h
|
@ -26,6 +26,7 @@ extern INT32 centerx, centery;
|
|||
|
||||
extern fixed_t centerxfrac, centeryfrac;
|
||||
extern fixed_t projection, projectiony;
|
||||
extern fixed_t fovtan; // field of view
|
||||
|
||||
extern size_t validcount, linecount, loopcount, framecount;
|
||||
|
||||
|
@ -45,6 +46,8 @@ extern size_t validcount, linecount, loopcount, framecount;
|
|||
#define MAXLIGHTZ 128
|
||||
#define LIGHTZSHIFT 20
|
||||
|
||||
#define LIGHTRESOLUTIONFIX (640*fovtan/vid.width)
|
||||
|
||||
extern lighttable_t *scalelight[LIGHTLEVELS][MAXLIGHTSCALE];
|
||||
extern lighttable_t *scalelightfixed[MAXLIGHTSCALE];
|
||||
extern lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ];
|
||||
|
@ -64,7 +67,7 @@ fixed_t R_PointToDist2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1);
|
|||
|
||||
fixed_t R_ScaleFromGlobalAngle(angle_t visangle);
|
||||
subsector_t *R_PointInSubsector(fixed_t x, fixed_t y);
|
||||
subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y);
|
||||
subsector_t *R_PointInSubsectorOrNull(fixed_t x, fixed_t y);
|
||||
|
||||
boolean R_DoCulling(line_t *cullheight, line_t *viewcullheight, fixed_t vz, fixed_t bottomh, fixed_t toph);
|
||||
|
||||
|
@ -76,14 +79,11 @@ extern consvar_t cv_showhud, cv_translucenthud;
|
|||
extern consvar_t cv_homremoval;
|
||||
extern consvar_t cv_chasecam, cv_chasecam2;
|
||||
extern consvar_t cv_flipcam, cv_flipcam2;
|
||||
#if defined(FLOORSPLATS) || defined(GLBADSHADOWS)
|
||||
|
||||
extern consvar_t cv_shadow;
|
||||
#endif
|
||||
#ifdef GLBADSHADOWS
|
||||
extern conscar_t cv_shadowoffs;
|
||||
#endif //#ifdef GLBADSHADOWS
|
||||
extern consvar_t cv_translucency;
|
||||
extern consvar_t cv_drawdist, cv_drawdist_nights, cv_drawdist_precip;
|
||||
extern consvar_t cv_fov;
|
||||
extern consvar_t cv_skybox;
|
||||
extern consvar_t cv_tailspickup;
|
||||
|
||||
|
@ -94,6 +94,9 @@ void R_InitHardwareMode(void);
|
|||
#endif
|
||||
void R_ReloadHUDGraphics(void);
|
||||
|
||||
void R_CheckViewMorph(void);
|
||||
void R_ApplyViewMorph(void);
|
||||
|
||||
// just sets setsizeneeded true
|
||||
extern boolean setsizeneeded;
|
||||
void R_SetViewSize(void);
|
||||
|
|
|
@ -1196,7 +1196,7 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp
|
|||
INT32 angle;
|
||||
patch_t *patch;
|
||||
patch_t *newpatch;
|
||||
UINT16 *rawsrc, *rawdst;
|
||||
UINT16 *rawdst;
|
||||
size_t size;
|
||||
INT32 bflip = (flip != 0x00);
|
||||
|
||||
|
@ -1242,16 +1242,6 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp
|
|||
leftoffset = width - leftoffset;
|
||||
}
|
||||
|
||||
// Draw the sprite to a temporary buffer.
|
||||
size = (width*height);
|
||||
rawsrc = Z_Malloc(size * sizeof(UINT16), PU_STATIC, NULL);
|
||||
|
||||
// can't memset here
|
||||
for (i = 0; i < size; i++)
|
||||
rawsrc[i] = 0xFF00;
|
||||
|
||||
R_PatchToMaskedFlat(patch, rawsrc, bflip);
|
||||
|
||||
// Don't cache angle = 0
|
||||
for (angle = 1; angle < ROTANGLES; angle++)
|
||||
{
|
||||
|
|
|
@ -44,9 +44,6 @@
|
|||
// Quincunx antialiasing of flats!
|
||||
//#define QUINCUNX
|
||||
|
||||
// good night sweet prince
|
||||
#define SHITPLANESPARENCY
|
||||
|
||||
//SoM: 3/23/2000: Use Boom visplane hashing.
|
||||
|
||||
visplane_t *visplanes[MAXVISPLANES];
|
||||
|
@ -995,11 +992,7 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
else // Opaque, but allow transparent flat pixels
|
||||
spanfunctype = SPANDRAWFUNC_SPLAT;
|
||||
|
||||
#ifdef SHITPLANESPARENCY
|
||||
if ((spanfunctype == SPANDRAWFUNC_SPLAT) != (pl->extra_colormap && (pl->extra_colormap->fog & 4)))
|
||||
#else
|
||||
if (!pl->extra_colormap || !(pl->extra_colormap->fog & 2))
|
||||
#endif
|
||||
if ((spanfunctype == SPANDRAWFUNC_SPLAT) || (pl->extra_colormap && (pl->extra_colormap->flags & CMF_FOG)))
|
||||
light = (pl->lightlevel >> LIGHTSEGSHIFT);
|
||||
else
|
||||
light = LIGHTLEVELS-1;
|
||||
|
@ -1053,11 +1046,7 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
else // Opaque, but allow transparent flat pixels
|
||||
spanfunctype = SPANDRAWFUNC_SPLAT;
|
||||
|
||||
#ifdef SHITPLANESPARENCY
|
||||
if ((spanfunctype == SPANDRAWFUNC_SPLAT) != (pl->extra_colormap && (pl->extra_colormap->fog & 4)))
|
||||
#else
|
||||
if (!pl->extra_colormap || !(pl->extra_colormap->fog & 2))
|
||||
#endif
|
||||
if ((spanfunctype == SPANDRAWFUNC_SPLAT) || (pl->extra_colormap && (pl->extra_colormap->flags & CMF_FOG)))
|
||||
light = (pl->lightlevel >> LIGHTSEGSHIFT);
|
||||
else
|
||||
light = LIGHTLEVELS-1;
|
||||
|
|
44
src/r_segs.c
44
src/r_segs.c
|
@ -199,7 +199,7 @@ static void R_DrawWallSplats(void)
|
|||
// draw the columns
|
||||
for (dc_x = x1; dc_x <= x2; dc_x++, spryscale += rw_scalestep)
|
||||
{
|
||||
pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT;
|
||||
pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
|
||||
if (pindex >= MAXLIGHTSCALE)
|
||||
pindex = MAXLIGHTSCALE - 1;
|
||||
dc_colormap = walllights[pindex];
|
||||
|
@ -418,14 +418,14 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
rlight->extra_colormap = *light->extra_colormap;
|
||||
rlight->flags = light->flags;
|
||||
|
||||
if (rlight->flags & FF_FOG || (rlight->extra_colormap && rlight->extra_colormap->fog))
|
||||
if ((colfunc != colfuncs[COLDRAWFUNC_FUZZY])
|
||||
|| (rlight->flags & FF_FOG)
|
||||
|| (rlight->extra_colormap && (rlight->extra_colormap->flags & CMF_FOG)))
|
||||
lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT);
|
||||
else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY])
|
||||
lightnum = LIGHTLEVELS - 1;
|
||||
else
|
||||
lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT);
|
||||
lightnum = LIGHTLEVELS - 1;
|
||||
|
||||
if (rlight->extra_colormap && rlight->extra_colormap->fog)
|
||||
if (rlight->extra_colormap && (rlight->extra_colormap->flags & CMF_FOG))
|
||||
;
|
||||
else if (curline->v1->y == curline->v2->y)
|
||||
lightnum--;
|
||||
|
@ -437,18 +437,14 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (colfunc == colfuncs[COLDRAWFUNC_FUZZY])
|
||||
{
|
||||
if (frontsector->extra_colormap && frontsector->extra_colormap->fog)
|
||||
lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT);
|
||||
else
|
||||
lightnum = LIGHTLEVELS - 1;
|
||||
}
|
||||
else
|
||||
if ((colfunc != colfuncs[COLDRAWFUNC_FUZZY])
|
||||
|| (frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG)))
|
||||
lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT);
|
||||
else
|
||||
lightnum = LIGHTLEVELS - 1;
|
||||
|
||||
if (colfunc == colfuncs[COLDRAWFUNC_FOG]
|
||||
|| (frontsector->extra_colormap && frontsector->extra_colormap->fog))
|
||||
|| (frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG)))
|
||||
;
|
||||
else if (curline->v1->y == curline->v2->y)
|
||||
lightnum--;
|
||||
|
@ -599,7 +595,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
else
|
||||
xwalllights = scalelight[rlight->lightnum];
|
||||
|
||||
pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT;
|
||||
pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
|
||||
|
||||
if (pindex >= MAXLIGHTSCALE)
|
||||
pindex = MAXLIGHTSCALE - 1;
|
||||
|
@ -644,7 +640,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
}
|
||||
|
||||
// calculate lighting
|
||||
pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT;
|
||||
pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
|
||||
|
||||
if (pindex >= MAXLIGHTSCALE)
|
||||
pindex = MAXLIGHTSCALE - 1;
|
||||
|
@ -947,7 +943,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
else
|
||||
rlight->lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT);
|
||||
|
||||
if (pfloor->flags & FF_FOG || rlight->flags & FF_FOG || (rlight->extra_colormap && rlight->extra_colormap->fog))
|
||||
if (pfloor->flags & FF_FOG || rlight->flags & FF_FOG || (rlight->extra_colormap && (rlight->extra_colormap->flags & CMF_FOG)))
|
||||
;
|
||||
else if (curline->v1->y == curline->v2->y)
|
||||
rlight->lightnum--;
|
||||
|
@ -962,7 +958,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
else
|
||||
{
|
||||
// Get correct light level!
|
||||
if ((frontsector->extra_colormap && frontsector->extra_colormap->fog))
|
||||
if ((frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG)))
|
||||
lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT);
|
||||
else if (pfloor->flags & FF_FOG)
|
||||
lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT);
|
||||
|
@ -972,7 +968,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
lightnum = R_FakeFlat(frontsector, &tempsec, &templight, &templight, false)
|
||||
->lightlevel >> LIGHTSEGSHIFT;
|
||||
|
||||
if (pfloor->flags & FF_FOG || (frontsector->extra_colormap && frontsector->extra_colormap->fog));
|
||||
if (pfloor->flags & FF_FOG || (frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG)));
|
||||
else if (curline->v1->y == curline->v2->y)
|
||||
lightnum--;
|
||||
else if (curline->v1->x == curline->v2->x)
|
||||
|
@ -1188,7 +1184,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
else
|
||||
xwalllights = scalelight[lightnum];
|
||||
|
||||
pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT;
|
||||
pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
|
||||
|
||||
if (pindex >= MAXLIGHTSCALE)
|
||||
pindex = MAXLIGHTSCALE-1;
|
||||
|
@ -1281,7 +1277,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
}
|
||||
|
||||
// calculate lighting
|
||||
pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT;
|
||||
pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
|
||||
|
||||
if (pindex >= MAXLIGHTSCALE)
|
||||
pindex = MAXLIGHTSCALE - 1;
|
||||
|
@ -1486,7 +1482,7 @@ static void R_RenderSegLoop (void)
|
|||
if (segtextured)
|
||||
{
|
||||
// calculate lighting
|
||||
pindex = FixedMul(rw_scale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT;
|
||||
pindex = FixedMul(rw_scale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
|
||||
|
||||
if (pindex >= MAXLIGHTSCALE)
|
||||
pindex = MAXLIGHTSCALE-1;
|
||||
|
@ -1521,7 +1517,7 @@ static void R_RenderSegLoop (void)
|
|||
else
|
||||
xwalllights = scalelight[lightnum];
|
||||
|
||||
pindex = FixedMul(rw_scale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT;
|
||||
pindex = FixedMul(rw_scale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
|
||||
|
||||
if (pindex >= MAXLIGHTSCALE)
|
||||
pindex = MAXLIGHTSCALE-1;
|
||||
|
|
|
@ -76,5 +76,5 @@ void R_SetupSkyDraw(void)
|
|||
void R_SetSkyScale(void)
|
||||
{
|
||||
fixed_t difference = vid.fdupx-(vid.dupx<<FRACBITS);
|
||||
skyscale = FixedDiv(FRACUNIT, vid.fdupx+difference);
|
||||
skyscale = FixedDiv(fovtan, vid.fdupx+difference);
|
||||
}
|
||||
|
|
|
@ -86,6 +86,7 @@ extern fixed_t viewx, viewy, viewz;
|
|||
extern angle_t viewangle, aimingangle;
|
||||
extern sector_t *viewsector;
|
||||
extern player_t *viewplayer;
|
||||
extern mobj_t *r_viewmobj;
|
||||
|
||||
extern consvar_t cv_allowmlook;
|
||||
extern consvar_t cv_maxportals;
|
||||
|
|
566
src/r_things.c
566
src/r_things.c
|
@ -756,9 +756,7 @@ void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight)
|
|||
static void R_DrawVisSprite(vissprite_t *vis)
|
||||
{
|
||||
column_t *column;
|
||||
#ifdef RANGECHECK
|
||||
INT32 texturecolumn;
|
||||
#endif
|
||||
fixed_t frac;
|
||||
patch_t *patch = vis->patch;
|
||||
fixed_t this_scale = vis->mobj->scale;
|
||||
|
@ -891,6 +889,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
if (!(vis->scalestep))
|
||||
{
|
||||
sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale);
|
||||
sprtopscreen += vis->shear.tan * vis->shear.offset;
|
||||
dc_iscale = FixedDiv(FRACUNIT, vis->scale);
|
||||
}
|
||||
|
||||
|
@ -906,28 +905,51 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
if (vis->x2 >= vid.width)
|
||||
vis->x2 = vid.width-1;
|
||||
|
||||
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale)
|
||||
// Split drawing loops for paper and non-paper to reduce conditional checks per sprite
|
||||
if (vis->scalestep)
|
||||
{
|
||||
#ifdef RANGECHECK
|
||||
// Papersprite drawing loop
|
||||
|
||||
texturecolumn = frac>>FRACBITS;
|
||||
|
||||
if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width))
|
||||
I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc_x);
|
||||
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn]));
|
||||
#else
|
||||
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS]));
|
||||
#endif
|
||||
if (vis->scalestep)
|
||||
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, spryscale += vis->scalestep)
|
||||
{
|
||||
angle_t angle = ((vis->centerangle + xtoviewangle[dc_x]) >> ANGLETOFINESHIFT) & 0xFFF;
|
||||
texturecolumn = (vis->paperoffset - FixedMul(FINETANGENT(angle), vis->paperdistance)) / this_scale;
|
||||
|
||||
if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width))
|
||||
continue;
|
||||
|
||||
if (vis->xiscale < 0) // Flipped sprite
|
||||
texturecolumn = SHORT(patch->width) - 1 - texturecolumn;
|
||||
|
||||
sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale));
|
||||
dc_iscale = (0xffffffffu / (unsigned)spryscale);
|
||||
|
||||
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn]));
|
||||
|
||||
if (vis->cut & SC_VFLIP)
|
||||
R_DrawFlippedMaskedColumn(column, patch->height);
|
||||
else
|
||||
R_DrawMaskedColumn(column);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Non-paper drawing loop
|
||||
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale, sprtopscreen += vis->shear.tan)
|
||||
{
|
||||
#ifdef RANGECHECK
|
||||
texturecolumn = frac>>FRACBITS;
|
||||
if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width))
|
||||
I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc_x);
|
||||
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn]));
|
||||
#else
|
||||
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS]));
|
||||
#endif
|
||||
if (vis->cut & SC_VFLIP)
|
||||
R_DrawFlippedMaskedColumn(column, patch->height);
|
||||
else
|
||||
R_DrawMaskedColumn(column);
|
||||
}
|
||||
if (vis->cut & SC_VFLIP)
|
||||
R_DrawFlippedMaskedColumn(column, patch->height);
|
||||
else
|
||||
R_DrawMaskedColumn(column);
|
||||
spryscale += vis->scalestep;
|
||||
}
|
||||
|
||||
colfunc = colfuncs[BASEDRAWFUNC];
|
||||
|
@ -1072,10 +1094,10 @@ static void R_SplitSprite(vissprite_t *sprite)
|
|||
|
||||
newsprite->extra_colormap = *sector->lightlist[i].extra_colormap;
|
||||
|
||||
if (!((newsprite->cut & SC_FULLBRIGHT)
|
||||
&& (!newsprite->extra_colormap || !(newsprite->extra_colormap->fog & 1))))
|
||||
if (!(newsprite->cut & SC_FULLBRIGHT)
|
||||
|| (newsprite->extra_colormap && (newsprite->extra_colormap->flags & CMF_FADEFULLBRIGHTSPRITES)))
|
||||
{
|
||||
lindex = FixedMul(sprite->xscale, FixedDiv(640, vid.width))>>(LIGHTSCALESHIFT);
|
||||
lindex = FixedMul(sprite->xscale, LIGHTRESOLUTIONFIX)>>(LIGHTSCALESHIFT);
|
||||
|
||||
if (lindex >= MAXLIGHTSCALE)
|
||||
lindex = MAXLIGHTSCALE-1;
|
||||
|
@ -1086,7 +1108,255 @@ static void R_SplitSprite(vissprite_t *sprite)
|
|||
}
|
||||
}
|
||||
|
||||
//#define PROPERPAPER // This was reverted less than 7 hours before 2.2's release because of very strange, frequent crashes.
|
||||
//
|
||||
// R_GetShadowZ(thing, shadowslope)
|
||||
// Get the first visible floor below the object for shadows
|
||||
// shadowslope is filled with the floor's slope, if provided
|
||||
//
|
||||
fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
|
||||
{
|
||||
fixed_t z, floorz = INT32_MIN;
|
||||
pslope_t *slope, *floorslope = NULL;
|
||||
msecnode_t *node;
|
||||
sector_t *sector;
|
||||
ffloor_t *rover;
|
||||
|
||||
for (node = thing->touching_sectorlist; node; node = node->m_sectorlist_next)
|
||||
{
|
||||
sector = node->m_sector;
|
||||
|
||||
slope = (sector->heightsec != -1) ? NULL : sector->f_slope;
|
||||
z = slope ? P_GetZAt(slope, thing->x, thing->y) : (
|
||||
(sector->heightsec != -1) ? sectors[sector->heightsec].floorheight : sector->floorheight
|
||||
);
|
||||
|
||||
if (z < thing->z+thing->height/2 && z > floorz)
|
||||
{
|
||||
floorz = z;
|
||||
floorslope = slope;
|
||||
}
|
||||
|
||||
if (sector->ffloors)
|
||||
for (rover = sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES) || (rover->alpha < 90 && !(rover->flags & FF_SWIMMABLE)))
|
||||
continue;
|
||||
|
||||
z = *rover->t_slope ? P_GetZAt(*rover->t_slope, thing->x, thing->y) : *rover->topheight;
|
||||
if (z < thing->z+thing->height/2 && z > floorz)
|
||||
{
|
||||
floorz = z;
|
||||
floorslope = *rover->t_slope;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (thing->floorz > floorz + (!floorslope ? 0 : FixedMul(abs(floorslope->zdelta), thing->radius*3/2)))
|
||||
{
|
||||
floorz = thing->floorz;
|
||||
floorslope = NULL;
|
||||
}
|
||||
|
||||
#if 0 // Unfortunately, this drops CEZ2 down to sub-17 FPS on my i7.
|
||||
//#ifdef POLYOBJECTS
|
||||
// Check polyobjects and see if floorz needs to be altered, for rings only because they don't update floorz
|
||||
if (thing->type == MT_RING)
|
||||
{
|
||||
INT32 xl, xh, yl, yh, bx, by;
|
||||
|
||||
xl = (unsigned)(thing->x - thing->radius - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
xh = (unsigned)(thing->x + thing->radius - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
yl = (unsigned)(thing->y - thing->radius - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
yh = (unsigned)(thing->y + thing->radius - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
|
||||
BMBOUNDFIX(xl, xh, yl, yh);
|
||||
|
||||
validcount++;
|
||||
|
||||
for (by = yl; by <= yh; by++)
|
||||
for (bx = xl; bx <= xh; bx++)
|
||||
{
|
||||
INT32 offset;
|
||||
polymaplink_t *plink; // haleyjd 02/22/06
|
||||
|
||||
if (bx < 0 || by < 0 || bx >= bmapwidth || by >= bmapheight)
|
||||
continue;
|
||||
|
||||
offset = by*bmapwidth + bx;
|
||||
|
||||
// haleyjd 02/22/06: consider polyobject lines
|
||||
plink = polyblocklinks[offset];
|
||||
|
||||
while (plink)
|
||||
{
|
||||
polyobj_t *po = plink->po;
|
||||
|
||||
if (po->validcount != validcount) // if polyobj hasn't been checked
|
||||
{
|
||||
po->validcount = validcount;
|
||||
|
||||
if (!P_MobjInsidePolyobj(po, thing) || !(po->flags & POF_RENDERPLANES))
|
||||
{
|
||||
plink = (polymaplink_t *)(plink->link.next);
|
||||
continue;
|
||||
}
|
||||
|
||||
// We're inside it! Yess...
|
||||
z = po->lines[0]->backsector->ceilingheight;
|
||||
|
||||
if (z < thing->z+thing->height/2 && z > floorz)
|
||||
{
|
||||
floorz = z;
|
||||
floorslope = NULL;
|
||||
}
|
||||
}
|
||||
plink = (polymaplink_t *)(plink->link.next);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (shadowslope != NULL)
|
||||
*shadowslope = floorslope;
|
||||
|
||||
return floorz;
|
||||
}
|
||||
|
||||
static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, fixed_t tx, fixed_t tz)
|
||||
{
|
||||
vissprite_t *shadow;
|
||||
patch_t *patch;
|
||||
fixed_t xscale, yscale, shadowxscale, shadowyscale, shadowskew, x1, x2;
|
||||
INT32 light = 0;
|
||||
fixed_t scalemul; UINT8 trans;
|
||||
fixed_t floordiff;
|
||||
fixed_t floorz;
|
||||
pslope_t *floorslope;
|
||||
|
||||
floorz = R_GetShadowZ(thing, &floorslope);
|
||||
|
||||
if (abs(floorz-viewz)/tz > 4) return; // Prevent stretchy shadows and possible crashes
|
||||
|
||||
floordiff = abs(thing->z - floorz);
|
||||
|
||||
trans = floordiff / (100*FRACUNIT) + 3;
|
||||
if (trans >= 9) return;
|
||||
|
||||
scalemul = FixedMul(FRACUNIT - floordiff/640, scale);
|
||||
|
||||
patch = W_CachePatchName("DSHADOW", PU_CACHE);
|
||||
xscale = FixedDiv(projection, tz);
|
||||
yscale = FixedDiv(projectiony, tz);
|
||||
shadowxscale = FixedMul(thing->radius*2, scalemul);
|
||||
shadowyscale = FixedMul(FixedMul(thing->radius*2, scalemul), FixedDiv(abs(floorz - viewz), tz));
|
||||
shadowyscale = min(shadowyscale, shadowxscale) / patch->height;
|
||||
shadowxscale /= patch->width;
|
||||
shadowskew = 0;
|
||||
|
||||
if (floorslope)
|
||||
{
|
||||
// haha let's try some dumb stuff
|
||||
fixed_t xslope, zslope;
|
||||
angle_t sloperelang = (R_PointToAngle(thing->x, thing->y) - floorslope->xydirection) >> ANGLETOFINESHIFT;
|
||||
|
||||
xslope = FixedMul(FINESINE(sloperelang), floorslope->zdelta);
|
||||
zslope = FixedMul(FINECOSINE(sloperelang), floorslope->zdelta);
|
||||
|
||||
//CONS_Printf("Shadow is sloped by %d %d\n", xslope, zslope);
|
||||
|
||||
if (viewz < floorz)
|
||||
shadowyscale += FixedMul(FixedMul(thing->radius*2 / patch->height, scalemul), zslope);
|
||||
else
|
||||
shadowyscale -= FixedMul(FixedMul(thing->radius*2 / patch->height, scalemul), zslope);
|
||||
|
||||
shadowyscale = abs(shadowyscale);
|
||||
|
||||
shadowskew = xslope;
|
||||
}
|
||||
|
||||
tx -= patch->width * shadowxscale/2;
|
||||
x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
|
||||
if (x1 >= viewwidth) return;
|
||||
|
||||
tx += patch->width * shadowxscale;
|
||||
x2 = ((centerxfrac + FixedMul(tx,xscale))>>FRACBITS); x2--;
|
||||
if (x2 < 0 || x2 <= x1) return;
|
||||
|
||||
if (shadowyscale < FRACUNIT/patch->height) return; // fix some crashes?
|
||||
|
||||
shadow = R_NewVisSprite();
|
||||
shadow->patch = patch;
|
||||
shadow->heightsec = vis->heightsec;
|
||||
|
||||
shadow->thingheight = FRACUNIT;
|
||||
shadow->pz = floorz;
|
||||
shadow->pzt = shadow->pz + shadow->thingheight;
|
||||
|
||||
shadow->mobjflags = 0;
|
||||
shadow->sortscale = vis->sortscale;
|
||||
shadow->dispoffset = vis->dispoffset - 5;
|
||||
shadow->gx = thing->x;
|
||||
shadow->gy = thing->y;
|
||||
shadow->gzt = shadow->pz + shadow->patch->height * shadowyscale / 2;
|
||||
shadow->gz = shadow->gzt - shadow->patch->height * shadowyscale;
|
||||
shadow->texturemid = FixedMul(thing->scale, FixedDiv(shadow->gzt - viewz, shadowyscale));
|
||||
if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES)
|
||||
shadow->texturemid = FixedMul(shadow->texturemid, ((skin_t *)thing->skin)->highresscale);
|
||||
shadow->scalestep = 0;
|
||||
shadow->shear.tan = shadowskew; // repurposed variable
|
||||
|
||||
shadow->mobj = thing; // Easy access! Tails 06-07-2002
|
||||
|
||||
shadow->x1 = x1 < portalclipstart ? portalclipstart : x1;
|
||||
shadow->x2 = x2 >= portalclipend ? portalclipend-1 : x2;
|
||||
|
||||
shadow->xscale = FixedMul(xscale, shadowxscale); //SoM: 4/17/2000
|
||||
shadow->scale = FixedMul(yscale, shadowyscale);
|
||||
shadow->sector = vis->sector;
|
||||
shadow->szt = (INT16)((centeryfrac - FixedMul(shadow->gzt - viewz, yscale))>>FRACBITS);
|
||||
shadow->sz = (INT16)((centeryfrac - FixedMul(shadow->gz - viewz, yscale))>>FRACBITS);
|
||||
shadow->cut = SC_ISSCALED|SC_SHADOW; //check this
|
||||
|
||||
shadow->startfrac = 0;
|
||||
//shadow->xiscale = 0x7ffffff0 / (shadow->xscale/2);
|
||||
shadow->xiscale = (patch->width<<FRACBITS)/(x2-x1+1); // fuck it
|
||||
|
||||
if (shadow->x1 > x1)
|
||||
shadow->startfrac += shadow->xiscale*(shadow->x1-x1);
|
||||
|
||||
// reusing x1 variable
|
||||
x1 += (x2-x1)/2;
|
||||
shadow->shear.offset = shadow->x1-x1;
|
||||
|
||||
if (thing->subsector->sector->numlights)
|
||||
{
|
||||
INT32 lightnum;
|
||||
#ifdef ESLOPE // R_GetPlaneLight won't work on sloped lights!
|
||||
light = thing->subsector->sector->numlights - 1;
|
||||
|
||||
for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) {
|
||||
fixed_t h = thing->subsector->sector->lightlist[lightnum].slope ? P_GetZAt(thing->subsector->sector->lightlist[lightnum].slope, thing->x, thing->y)
|
||||
: thing->subsector->sector->lightlist[lightnum].height;
|
||||
if (h <= shadow->gzt) {
|
||||
light = lightnum - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
light = R_GetPlaneLight(thing->subsector->sector, shadow->gzt, false);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (thing->subsector->sector->numlights)
|
||||
shadow->extra_colormap = *thing->subsector->sector->lightlist[light].extra_colormap;
|
||||
else
|
||||
shadow->extra_colormap = thing->subsector->sector->extra_colormap;
|
||||
|
||||
shadow->transmap = transtables + (trans<<FF_TRANSSHIFT);
|
||||
shadow->colormap = scalelight[0][0]; // full dark!
|
||||
|
||||
objectsdrawn++;
|
||||
}
|
||||
|
||||
//
|
||||
// R_ProjectSprite
|
||||
|
@ -1124,7 +1394,11 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
fixed_t iscale;
|
||||
fixed_t scalestep;
|
||||
fixed_t offset, offset2;
|
||||
|
||||
fixed_t basetx; // drop shadows
|
||||
|
||||
boolean papersprite = !!(thing->frame & FF_PAPERSPRITE);
|
||||
fixed_t paperoffset = 0, paperdistance = 0; angle_t centerangle = 0;
|
||||
|
||||
INT32 dispoffset = thing->info->dispoffset;
|
||||
|
||||
|
@ -1142,10 +1416,6 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
INT32 rollangle = 0;
|
||||
#endif
|
||||
|
||||
#ifndef PROPERPAPER
|
||||
fixed_t ang_scale = FRACUNIT;
|
||||
#endif
|
||||
|
||||
// transform the origin point
|
||||
tr_x = thing->x - viewx;
|
||||
tr_y = thing->y - viewy;
|
||||
|
@ -1156,15 +1426,15 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
tz = gxt-gyt;
|
||||
|
||||
// thing is behind view plane?
|
||||
if (!(papersprite) && (tz < FixedMul(MINZ, this_scale))) // papersprite clipping is handled later
|
||||
if (!papersprite && (tz < FixedMul(MINZ, this_scale))) // papersprite clipping is handled later
|
||||
return;
|
||||
|
||||
gxt = -FixedMul(tr_x, viewsin);
|
||||
gyt = FixedMul(tr_y, viewcos);
|
||||
tx = -(gyt + gxt);
|
||||
basetx = tx = -(gyt + gxt);
|
||||
|
||||
// too far off the side?
|
||||
if (abs(tx) > tz<<2)
|
||||
if (!papersprite && abs(tx) > tz<<2) // papersprite clipping is handled later
|
||||
return;
|
||||
|
||||
// aspect ratio stuff
|
||||
|
@ -1228,13 +1498,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
#endif
|
||||
|
||||
if (sprframe->rotate != SRF_SINGLE || papersprite)
|
||||
{
|
||||
ang = R_PointToAngle (thing->x, thing->y) - (thing->player ? thing->player->drawangle : thing->angle);
|
||||
#ifndef PROPERPAPER
|
||||
if (papersprite)
|
||||
ang_scale = abs(FINESINE(ang>>ANGLETOFINESHIFT));
|
||||
#endif
|
||||
}
|
||||
|
||||
if (sprframe->rotate == SRF_SINGLE)
|
||||
{
|
||||
|
@ -1300,31 +1564,11 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
else
|
||||
offset = -spr_offset;
|
||||
offset = FixedMul(offset, this_scale);
|
||||
#ifndef PROPERPAPER
|
||||
tx += FixedMul(offset, ang_scale);
|
||||
x1 = (centerxfrac + FixedMul (tx,xscale)) >>FRACBITS;
|
||||
|
||||
// off the right side?
|
||||
if (x1 > viewwidth)
|
||||
return;
|
||||
#endif
|
||||
offset2 = FixedMul(spr_width, this_scale);
|
||||
#ifndef PROPERPAPER
|
||||
tx += FixedMul(offset2, ang_scale);
|
||||
x2 = ((centerxfrac + FixedMul (tx,xscale)) >> FRACBITS) - (papersprite ? 2 : 1);
|
||||
|
||||
// off the left side
|
||||
if (x2 < 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (papersprite)
|
||||
{
|
||||
fixed_t
|
||||
#ifdef PROPERPAPER
|
||||
xscale2,
|
||||
#endif
|
||||
yscale2, cosmul, sinmul, tz2;
|
||||
fixed_t xscale2, yscale2, cosmul, sinmul, tx2, tz2;
|
||||
INT32 range;
|
||||
|
||||
if (ang >= ANGLE_180)
|
||||
|
@ -1342,19 +1586,23 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
gyt = -FixedMul(tr_y, viewsin);
|
||||
tz = gxt-gyt;
|
||||
yscale = FixedDiv(projectiony, tz);
|
||||
if (yscale < 64) return; // Fix some funky visuals
|
||||
//if (yscale < 64) return; // Fix some funky visuals
|
||||
|
||||
#ifdef PROPERPAPER
|
||||
gxt = -FixedMul(tr_x, viewsin);
|
||||
gyt = FixedMul(tr_y, viewcos);
|
||||
tx = -(gyt + gxt);
|
||||
xscale = FixedDiv(projection, tz);
|
||||
x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
|
||||
|
||||
// off the right side?
|
||||
if (x1 > viewwidth)
|
||||
return;
|
||||
#endif
|
||||
// Get paperoffset (offset) and paperoffset (distance)
|
||||
paperoffset = -FixedMul(tr_x, cosmul) - FixedMul(tr_y, sinmul);
|
||||
paperdistance = -FixedMul(tr_x, sinmul) + FixedMul(tr_y, cosmul);
|
||||
if (paperdistance < 0)
|
||||
{
|
||||
paperoffset = -paperoffset;
|
||||
paperdistance = -paperdistance;
|
||||
}
|
||||
centerangle = viewangle - thing->angle;
|
||||
|
||||
tr_x += FixedMul(offset2, cosmul);
|
||||
tr_y += FixedMul(offset2, sinmul);
|
||||
|
@ -1362,38 +1610,52 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
gyt = -FixedMul(tr_y, viewsin);
|
||||
tz2 = gxt-gyt;
|
||||
yscale2 = FixedDiv(projectiony, tz2);
|
||||
if (yscale2 < 64) return; // ditto
|
||||
//if (yscale2 < 64) return; // ditto
|
||||
|
||||
#ifdef PROPERPAPER
|
||||
gxt = -FixedMul(tr_x, viewsin);
|
||||
gyt = FixedMul(tr_y, viewcos);
|
||||
tx = -(gyt + gxt);
|
||||
tx2 = -(gyt + gxt);
|
||||
xscale2 = FixedDiv(projection, tz2);
|
||||
x2 = (centerxfrac + FixedMul(tx,xscale2))>>FRACBITS; x2--;
|
||||
x2 = ((centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS);
|
||||
|
||||
if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier
|
||||
return;
|
||||
|
||||
// Needs partially clipped
|
||||
if (tz < FixedMul(MINZ, this_scale))
|
||||
{
|
||||
fixed_t div = FixedDiv(tz2-tz, FixedMul(MINZ, this_scale)-tz);
|
||||
tx += FixedDiv(tx2-tx, div);
|
||||
tz = FixedMul(MINZ, this_scale);
|
||||
yscale = FixedDiv(projectiony, tz);
|
||||
xscale = FixedDiv(projection, tz);
|
||||
x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
|
||||
}
|
||||
else if (tz2 < FixedMul(MINZ, this_scale))
|
||||
{
|
||||
fixed_t div = FixedDiv(tz-tz2, FixedMul(MINZ, this_scale)-tz2);
|
||||
tx2 += FixedDiv(tx-tx2, div);
|
||||
tz2 = FixedMul(MINZ, this_scale);
|
||||
yscale2 = FixedDiv(projectiony, tz2);
|
||||
xscale2 = FixedDiv(projection, tz2);
|
||||
x2 = (centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS;
|
||||
}
|
||||
|
||||
// off the right side?
|
||||
if (x1 > viewwidth)
|
||||
return;
|
||||
|
||||
// off the left side
|
||||
if (x2 < 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier
|
||||
return;
|
||||
|
||||
if ((range = x2 - x1) <= 0)
|
||||
return;
|
||||
|
||||
#ifdef PROPERPAPER
|
||||
range++; // fencepost problem
|
||||
#endif
|
||||
|
||||
scalestep = (yscale2 - yscale)/range;
|
||||
xscale =
|
||||
#ifdef PROPERPAPER
|
||||
FixedDiv(range<<FRACBITS, abs(offset2))+1
|
||||
#else
|
||||
FixedMul(xscale, ang_scale)
|
||||
#endif
|
||||
;
|
||||
scalestep = ((yscale2 - yscale)/range) ?: 1;
|
||||
xscale = FixedDiv(range<<FRACBITS, abs(offset2));
|
||||
|
||||
// The following two are alternate sorting methods which might be more applicable in some circumstances. TODO - maybe enable via MF2?
|
||||
// sortscale = max(yscale, yscale2);
|
||||
|
@ -1403,7 +1665,6 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
{
|
||||
scalestep = 0;
|
||||
yscale = sortscale;
|
||||
#ifdef PROPERPAPER
|
||||
tx += offset;
|
||||
x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
|
||||
|
||||
|
@ -1417,7 +1678,6 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
// off the left side
|
||||
if (x2 < 0)
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer) // toast 16/09/16 (SYMMETRY)
|
||||
|
@ -1426,7 +1686,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
|
||||
thing = thing->tracer;
|
||||
|
||||
if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW)
|
||||
if (! R_ThingVisible(thing))
|
||||
return;
|
||||
|
||||
tr_x = thing->x - viewx;
|
||||
|
@ -1538,20 +1798,16 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
vis->pzt = vis->pz + vis->thingheight;
|
||||
vis->texturemid = vis->gzt - viewz;
|
||||
vis->scalestep = scalestep;
|
||||
vis->paperoffset = paperoffset;
|
||||
vis->paperdistance = paperdistance;
|
||||
vis->centerangle = centerangle;
|
||||
vis->shear.tan = 0;
|
||||
vis->shear.offset = 0;
|
||||
|
||||
vis->mobj = thing; // Easy access! Tails 06-07-2002
|
||||
|
||||
vis->x1 = x1 < 0 ? 0 : x1;
|
||||
vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2;
|
||||
|
||||
// PORTAL SEMI-CLIPPING
|
||||
if (portalrender)
|
||||
{
|
||||
if (vis->x1 < portalclipstart)
|
||||
vis->x1 = portalclipstart;
|
||||
if (vis->x2 >= portalclipend)
|
||||
vis->x2 = portalclipend-1;
|
||||
}
|
||||
vis->x1 = x1 < portalclipstart ? portalclipstart : x1;
|
||||
vis->x2 = x2 >= portalclipend ? portalclipend-1 : x2;
|
||||
|
||||
vis->xscale = xscale; //SoM: 4/17/2000
|
||||
vis->sector = thing->subsector->sector;
|
||||
|
@ -1608,7 +1864,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
vis->cut |= SC_FULLBRIGHT;
|
||||
|
||||
if (vis->cut & SC_FULLBRIGHT
|
||||
&& (!vis->extra_colormap || !(vis->extra_colormap->fog & 1)))
|
||||
&& (!vis->extra_colormap || !(vis->extra_colormap->flags & CMF_FADEFULLBRIGHTSPRITES)))
|
||||
{
|
||||
// full bright: goggles
|
||||
vis->colormap = colormaps;
|
||||
|
@ -1616,7 +1872,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
else
|
||||
{
|
||||
// diminished light
|
||||
lindex = FixedMul(xscale, FixedDiv(640, vid.width))>>(LIGHTSCALESHIFT);
|
||||
lindex = FixedMul(xscale, LIGHTRESOLUTIONFIX)>>(LIGHTSCALESHIFT);
|
||||
|
||||
if (lindex >= MAXLIGHTSCALE)
|
||||
lindex = MAXLIGHTSCALE-1;
|
||||
|
@ -1630,6 +1886,9 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
if (thing->subsector->sector->numlights)
|
||||
R_SplitSprite(vis);
|
||||
|
||||
if (oldthing->shadowscale && cv_shadow.value)
|
||||
R_ProjectDropShadow(oldthing, vis, oldthing->shadowscale, basetx, tz);
|
||||
|
||||
// Debug
|
||||
++objectsdrawn;
|
||||
}
|
||||
|
@ -1753,18 +2012,12 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
vis->pzt = vis->pz + vis->thingheight;
|
||||
vis->texturemid = vis->gzt - viewz;
|
||||
vis->scalestep = 0;
|
||||
vis->paperdistance = 0;
|
||||
vis->shear.tan = 0;
|
||||
vis->shear.offset = 0;
|
||||
|
||||
vis->x1 = x1 < 0 ? 0 : x1;
|
||||
vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2;
|
||||
|
||||
// PORTAL SEMI-CLIPPING
|
||||
if (portalrender)
|
||||
{
|
||||
if (vis->x1 < portalclipstart)
|
||||
vis->x1 = portalclipstart;
|
||||
if (vis->x2 >= portalclipend)
|
||||
vis->x2 = portalclipend-1;
|
||||
}
|
||||
vis->x1 = x1 < portalclipstart ? portalclipstart : x1;
|
||||
vis->x2 = x2 >= portalclipend ? portalclipend-1 : x2;
|
||||
|
||||
vis->xscale = xscale; //SoM: 4/17/2000
|
||||
vis->sector = thing->subsector->sector;
|
||||
|
@ -1818,7 +2071,7 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
|
|||
mobj_t *thing;
|
||||
precipmobj_t *precipthing; // Tails 08-25-2002
|
||||
INT32 lightnum;
|
||||
fixed_t approx_dist, limit_dist, hoop_limit_dist;
|
||||
fixed_t limit_dist, hoop_limit_dist;
|
||||
|
||||
if (rendermode != render_soft)
|
||||
return;
|
||||
|
@ -1851,35 +2104,10 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
|
|||
// If a limit exists, handle things a tiny bit different.
|
||||
limit_dist = (fixed_t)(cv_drawdist.value) << FRACBITS;
|
||||
hoop_limit_dist = (fixed_t)(cv_drawdist_nights.value) << FRACBITS;
|
||||
if (limit_dist || hoop_limit_dist)
|
||||
for (thing = sec->thinglist; thing; thing = thing->snext)
|
||||
{
|
||||
for (thing = sec->thinglist; thing; thing = thing->snext)
|
||||
{
|
||||
if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW)
|
||||
continue;
|
||||
|
||||
approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
|
||||
|
||||
if (thing->sprite == SPR_HOOP)
|
||||
{
|
||||
if (hoop_limit_dist && approx_dist > hoop_limit_dist)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (limit_dist && approx_dist > limit_dist)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (R_ThingVisibleWithinDist(thing, limit_dist, hoop_limit_dist))
|
||||
R_ProjectSprite(thing);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw everything in sector, no checks
|
||||
for (thing = sec->thinglist; thing; thing = thing->snext)
|
||||
if (!(thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW))
|
||||
R_ProjectSprite(thing);
|
||||
}
|
||||
|
||||
// no, no infinite draw distance for precipitation. this option at zero is supposed to turn it off
|
||||
|
@ -1887,15 +2115,8 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
|
|||
{
|
||||
for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext)
|
||||
{
|
||||
if (precipthing->precipflags & PCF_INVISIBLE)
|
||||
continue;
|
||||
|
||||
approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y);
|
||||
|
||||
if (approx_dist > limit_dist)
|
||||
continue;
|
||||
|
||||
R_ProjectPrecipitationSprite(precipthing);
|
||||
if (R_PrecipThingVisible(precipthing, limit_dist))
|
||||
R_ProjectPrecipitationSprite(precipthing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1945,6 +2166,9 @@ static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 e
|
|||
if (!(ds->cut & SC_LINKDRAW))
|
||||
continue;
|
||||
|
||||
if (ds->cut & SC_SHADOW)
|
||||
continue;
|
||||
|
||||
// reuse dsfirst...
|
||||
for (dsfirst = unsorted.prev; dsfirst != &unsorted; dsfirst = dsfirst->prev)
|
||||
{
|
||||
|
@ -1952,6 +2176,10 @@ static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 e
|
|||
if (dsfirst->cut & SC_LINKDRAW)
|
||||
continue;
|
||||
|
||||
// don't connect to your shadow!
|
||||
if (dsfirst->cut & SC_SHADOW)
|
||||
continue;
|
||||
|
||||
// don't connect if it's not the tracer
|
||||
if (dsfirst->mobj != ds->mobj)
|
||||
continue;
|
||||
|
@ -2590,6 +2818,55 @@ void R_ClipSprites(drawseg_t* dsstart, portal_t* portal)
|
|||
}
|
||||
}
|
||||
|
||||
/* Check if thing may be drawn from our current view. */
|
||||
boolean R_ThingVisible (mobj_t *thing)
|
||||
{
|
||||
return (!(
|
||||
thing->sprite == SPR_NULL ||
|
||||
( thing->flags2 & (MF2_DONTDRAW) ) ||
|
||||
thing == r_viewmobj
|
||||
));
|
||||
}
|
||||
|
||||
boolean R_ThingVisibleWithinDist (mobj_t *thing,
|
||||
fixed_t limit_dist,
|
||||
fixed_t hoop_limit_dist)
|
||||
{
|
||||
fixed_t approx_dist;
|
||||
|
||||
if (! R_ThingVisible(thing))
|
||||
return false;
|
||||
|
||||
approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
|
||||
|
||||
if (thing->sprite == SPR_HOOP)
|
||||
{
|
||||
if (hoop_limit_dist && approx_dist > hoop_limit_dist)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (limit_dist && approx_dist > limit_dist)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Check if precipitation may be drawn from our current view. */
|
||||
boolean R_PrecipThingVisible (precipmobj_t *precipthing,
|
||||
fixed_t limit_dist)
|
||||
{
|
||||
fixed_t approx_dist;
|
||||
|
||||
if (( precipthing->precipflags & PCF_INVISIBLE ))
|
||||
return false;
|
||||
|
||||
approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y);
|
||||
|
||||
return ( approx_dist <= limit_dist );
|
||||
}
|
||||
|
||||
//
|
||||
// R_DrawMasked
|
||||
//
|
||||
|
@ -3159,6 +3436,7 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value)
|
|||
GETFLAG(DASHMODE)
|
||||
GETFLAG(FASTEDGE)
|
||||
GETFLAG(MULTIABILITY)
|
||||
GETFLAG(NONIGHTSROTATION)
|
||||
#undef GETFLAG
|
||||
|
||||
else // let's check if it's a sound, otherwise error out
|
||||
|
|
|
@ -51,12 +51,23 @@ void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight);
|
|||
// (only sprites from namelist are added or replaced)
|
||||
void R_AddSpriteDefs(UINT16 wadnum);
|
||||
|
||||
fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope);
|
||||
|
||||
//SoM: 6/5/2000: Light sprites correctly!
|
||||
void R_AddSprites(sector_t *sec, INT32 lightlevel);
|
||||
void R_InitSprites(void);
|
||||
void R_ClearSprites(void);
|
||||
void R_ClipSprites(drawseg_t* dsstart, portal_t* portal);
|
||||
|
||||
boolean R_ThingVisible (mobj_t *thing);
|
||||
|
||||
boolean R_ThingVisibleWithinDist (mobj_t *thing,
|
||||
fixed_t draw_dist,
|
||||
fixed_t nights_draw_dist);
|
||||
|
||||
boolean R_PrecipThingVisible (precipmobj_t *precipthing,
|
||||
fixed_t precip_draw_dist);
|
||||
|
||||
/** Used to count the amount of masked elements
|
||||
* per portal to later group them in separate
|
||||
* drawnode lists.
|
||||
|
@ -149,7 +160,8 @@ typedef enum
|
|||
SC_LINKDRAW = 1<<3,
|
||||
SC_FULLBRIGHT = 1<<4,
|
||||
SC_VFLIP = 1<<5,
|
||||
SC_ISSCALED = 1>>6,
|
||||
SC_ISSCALED = 1<<6,
|
||||
SC_SHADOW = 1<<7,
|
||||
// masks
|
||||
SC_CUTMASK = SC_TOP|SC_BOTTOM,
|
||||
SC_FLAGMASK = ~SC_CUTMASK
|
||||
|
@ -177,8 +189,16 @@ typedef struct vissprite_s
|
|||
fixed_t startfrac; // horizontal position of x1
|
||||
fixed_t scale, sortscale; // sortscale only differs from scale for paper sprites and MF2_LINKDRAW
|
||||
fixed_t scalestep; // only for paper sprites, 0 otherwise
|
||||
fixed_t paperoffset, paperdistance; // for paper sprites, offset/dist relative to the angle
|
||||
fixed_t xiscale; // negative if flipped
|
||||
|
||||
angle_t centerangle; // for paper sprites
|
||||
|
||||
struct {
|
||||
fixed_t tan; // The amount to shear the sprite vertically per row
|
||||
INT32 offset; // The center of the shearing location offset from x1
|
||||
} shear;
|
||||
|
||||
fixed_t texturemid;
|
||||
patch_t *patch;
|
||||
|
||||
|
|
360
src/s_sound.c
360
src/s_sound.c
|
@ -117,6 +117,13 @@ static consvar_t surround = {"surround", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL
|
|||
consvar_t cv_resetmusic = {"resetmusic", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_resetmusicbyheader = {"resetmusicbyheader", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t cons_1upsound_t[] = {
|
||||
{0, "Jingle"},
|
||||
{1, "Sound"},
|
||||
{0, NULL}
|
||||
};
|
||||
consvar_t cv_1upsound = {"1upsound", "Jingle", CV_SAVE, cons_1upsound_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// Sound system toggles, saved into the config
|
||||
consvar_t cv_gamedigimusic = {"digimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameDigiMusic_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_gamemidimusic = {"midimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameMIDIMusic_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
@ -287,6 +294,7 @@ void S_RegisterSoundStuff(void)
|
|||
CV_RegisterVar(&cv_samplerate);
|
||||
CV_RegisterVar(&cv_resetmusic);
|
||||
CV_RegisterVar(&cv_resetmusicbyheader);
|
||||
CV_RegisterVar(&cv_1upsound);
|
||||
CV_RegisterVar(&cv_playsoundsifunfocused);
|
||||
CV_RegisterVar(&cv_playmusicifunfocused);
|
||||
CV_RegisterVar(&cv_gamesounds);
|
||||
|
@ -1433,6 +1441,12 @@ static tic_t pause_starttic;
|
|||
/// Music Definitions
|
||||
/// ------------------------
|
||||
|
||||
enum
|
||||
{
|
||||
MUSICDEF_220,
|
||||
MUSICDEF_221,
|
||||
};
|
||||
|
||||
musicdef_t soundtestsfx = {
|
||||
"_STSFX", // prevents exactly one valid track name from being used on the sound test
|
||||
"Sound Effects",
|
||||
|
@ -1464,178 +1478,264 @@ static UINT16 W_CheckForMusicDefInPwad(UINT16 wadid)
|
|||
return INT16_MAX; // not found
|
||||
}
|
||||
|
||||
void S_LoadMusicDefs(UINT16 wadnum)
|
||||
static void
|
||||
MusicDefStrcpy (char *p, const char *s, size_t n, int version)
|
||||
{
|
||||
UINT16 lump;
|
||||
char *buf;
|
||||
char *buf2;
|
||||
char *stoken;
|
||||
char *value;
|
||||
size_t size;
|
||||
INT32 i;
|
||||
musicdef_t *def = NULL;
|
||||
UINT16 line = 1; // for better error msgs
|
||||
|
||||
lump = W_CheckForMusicDefInPwad(wadnum);
|
||||
if (lump == INT16_MAX)
|
||||
return;
|
||||
|
||||
buf = W_CacheLumpNumPwad(wadnum, lump, PU_CACHE);
|
||||
size = W_LumpLengthPwad(wadnum, lump);
|
||||
|
||||
// for strtok
|
||||
buf2 = malloc(size+1);
|
||||
if (!buf2)
|
||||
I_Error("S_LoadMusicDefs: No more free memory\n");
|
||||
M_Memcpy(buf2,buf,size);
|
||||
buf2[size] = '\0';
|
||||
|
||||
stoken = strtok (buf2, "\r\n ");
|
||||
// Find music def
|
||||
while (stoken)
|
||||
strlcpy(p, s, n);
|
||||
if (version == MUSICDEF_220)
|
||||
{
|
||||
/*if ((stoken[0] == '/' && stoken[1] == '/')
|
||||
|| (stoken[0] == '#')) // skip comments
|
||||
while (( p = strchr(p, '_') ))
|
||||
*p++ = ' '; // turn _ into spaces.
|
||||
}
|
||||
}
|
||||
|
||||
static boolean
|
||||
ReadMusicDefFields (UINT16 wadnum, int line, boolean fields, char *stoken,
|
||||
musicdef_t **defp, int *versionp)
|
||||
{
|
||||
musicdef_t *def;
|
||||
int version;
|
||||
|
||||
char *value;
|
||||
char *textline;
|
||||
int i;
|
||||
|
||||
if (!stricmp(stoken, "lump"))
|
||||
{
|
||||
value = strtok(NULL, " ");
|
||||
if (!value)
|
||||
{
|
||||
stoken = strtok(NULL, "\r\n"); // skip end of line
|
||||
if (def)
|
||||
stoken = strtok(NULL, "\r\n= ");
|
||||
else
|
||||
stoken = strtok(NULL, "\r\n ");
|
||||
line++;
|
||||
}
|
||||
else*/ if (!stricmp(stoken, "lump"))
|
||||
{
|
||||
value = strtok(NULL, "\r\n ");
|
||||
|
||||
if (!value)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "MUSICDEF: Lump '%s' is missing name. (file %s, line %d)\n", stoken, wadfiles[wadnum]->filename, line);
|
||||
stoken = strtok(NULL, "\r\n"); // skip end of line
|
||||
goto skip_lump;
|
||||
}
|
||||
|
||||
// No existing musicdefs
|
||||
/*if (!musicdefstart)
|
||||
{
|
||||
musicdefstart = Z_Calloc(sizeof (musicdef_t), PU_STATIC, NULL);
|
||||
STRBUFCPY(musicdefstart->name, value);
|
||||
strlwr(musicdefstart->name);
|
||||
def = musicdefstart;
|
||||
//CONS_Printf("S_LoadMusicDefs: Initialized musicdef w/ song '%s'\n", def->name);
|
||||
}
|
||||
else*/
|
||||
{
|
||||
musicdef_t *prev = NULL;
|
||||
def = musicdefstart;
|
||||
|
||||
// Search if this is a replacement
|
||||
//CONS_Printf("S_LoadMusicDefs: Searching for song replacement...\n");
|
||||
while (def)
|
||||
{
|
||||
if (!stricmp(def->name, value))
|
||||
{
|
||||
//CONS_Printf("S_LoadMusicDefs: Found song replacement '%s'\n", def->name);
|
||||
break;
|
||||
}
|
||||
|
||||
prev = def;
|
||||
def = def->next;
|
||||
}
|
||||
|
||||
// Nothing found, add to the end.
|
||||
if (!def)
|
||||
{
|
||||
def = Z_Calloc(sizeof (musicdef_t), PU_STATIC, NULL);
|
||||
STRBUFCPY(def->name, value);
|
||||
strlwr(def->name);
|
||||
def->bpm = TICRATE<<(FRACBITS-1); // FixedDiv((60*TICRATE)<<FRACBITS, 120<<FRACBITS)
|
||||
if (prev != NULL)
|
||||
prev->next = def;
|
||||
//CONS_Printf("S_LoadMusicDefs: Added song '%s'\n", def->name);
|
||||
}
|
||||
}
|
||||
|
||||
skip_lump:
|
||||
stoken = strtok(NULL, "\r\n ");
|
||||
line++;
|
||||
CONS_Alert(CONS_WARNING,
|
||||
"MUSICDEF: Field '%s' is missing name. (file %s, line %d)\n",
|
||||
stoken, wadfiles[wadnum]->filename, line);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = strtok(NULL, "\r\n= ");
|
||||
musicdef_t *prev = NULL;
|
||||
def = musicdefstart;
|
||||
|
||||
// Search if this is a replacement
|
||||
//CONS_Printf("S_LoadMusicDefs: Searching for song replacement...\n");
|
||||
while (def)
|
||||
{
|
||||
if (!stricmp(def->name, value))
|
||||
{
|
||||
//CONS_Printf("S_LoadMusicDefs: Found song replacement '%s'\n", def->name);
|
||||
break;
|
||||
}
|
||||
|
||||
prev = def;
|
||||
def = def->next;
|
||||
}
|
||||
|
||||
// Nothing found, add to the end.
|
||||
if (!def)
|
||||
{
|
||||
def = Z_Calloc(sizeof (musicdef_t), PU_STATIC, NULL);
|
||||
STRBUFCPY(def->name, value);
|
||||
strlwr(def->name);
|
||||
def->bpm = TICRATE<<(FRACBITS-1); // FixedDiv((60*TICRATE)<<FRACBITS, 120<<FRACBITS)
|
||||
if (prev != NULL)
|
||||
prev->next = def;
|
||||
//CONS_Printf("S_LoadMusicDefs: Added song '%s'\n", def->name);
|
||||
}
|
||||
|
||||
(*defp) = def;
|
||||
}
|
||||
}
|
||||
else if (!stricmp(stoken, "version"))
|
||||
{
|
||||
if (fields)/* is this not the first field? */
|
||||
{
|
||||
CONS_Alert(CONS_WARNING,
|
||||
"MUSICDEF: Field '%s' must come first. (file %s, line %d)\n",
|
||||
stoken, wadfiles[wadnum]->filename, line);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = strtok(NULL, " ");
|
||||
if (!value)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "MUSICDEF: Field '%s' is missing value. (file %s, line %d)\n", stoken, wadfiles[wadnum]->filename, line);
|
||||
stoken = strtok(NULL, "\r\n"); // skip end of line
|
||||
goto skip_field;
|
||||
CONS_Alert(CONS_WARNING,
|
||||
"MUSICDEF: Field '%s' is missing version. (file %s, line %d)\n",
|
||||
stoken, wadfiles[wadnum]->filename, line);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strcasecmp(value, "2.2.0"))
|
||||
(*versionp) = MUSICDEF_221;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
version = (*versionp);
|
||||
|
||||
if (version == MUSICDEF_220)
|
||||
value = strtok(NULL, " =");
|
||||
else
|
||||
{
|
||||
value = strtok(NULL, "");
|
||||
|
||||
if (value)
|
||||
{
|
||||
// Find the equals sign.
|
||||
value = strchr(value, '=');
|
||||
}
|
||||
}
|
||||
|
||||
if (!value)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING,
|
||||
"MUSICDEF: Field '%s' is missing value. (file %s, line %d)\n",
|
||||
stoken, wadfiles[wadnum]->filename, line);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
def = (*defp);
|
||||
|
||||
if (!def)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "MUSICDEF: No music definition before field '%s'. (file %s, line %d)\n", stoken, wadfiles[wadnum]->filename, line);
|
||||
free(buf2);
|
||||
return;
|
||||
CONS_Alert(CONS_ERROR,
|
||||
"MUSICDEF: No music definition before field '%s'. (file %s, line %d)\n",
|
||||
stoken, wadfiles[wadnum]->filename, line);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (version != MUSICDEF_220)
|
||||
{
|
||||
// Skip the equals sign.
|
||||
value++;
|
||||
|
||||
// Now skip funny whitespace.
|
||||
value += strspn(value, "\t ");
|
||||
}
|
||||
|
||||
textline = value;
|
||||
i = atoi(value);
|
||||
|
||||
/* based ignored lumps */
|
||||
if (!stricmp(stoken, "usage")) {
|
||||
#if 0 // Ignore for now
|
||||
STRBUFCPY(def->usage, value);
|
||||
for (value = def->usage; *value; value++)
|
||||
if (*value == '_') *value = ' '; // turn _ into spaces.
|
||||
//CONS_Printf("S_LoadMusicDefs: Set usage to '%s'\n", def->usage);
|
||||
STRBUFCPY(def->usage, textline);
|
||||
#endif
|
||||
} else if (!stricmp(stoken, "source")) {
|
||||
#if 0 // Ignore for now
|
||||
STRBUFCPY(def->source, value);
|
||||
for (value = def->source; *value; value++)
|
||||
if (*value == '_') *value = ' '; // turn _ into spaces.
|
||||
//CONS_Printf("S_LoadMusicDefs: Set source to '%s'\n", def->usage);
|
||||
STRBUFCPY(def->source, textline);
|
||||
#endif
|
||||
} else if (!stricmp(stoken, "title")) {
|
||||
STRBUFCPY(def->title, value);
|
||||
for (value = def->title; *value; value++)
|
||||
if (*value == '_') *value = ' '; // turn _ into spaces.
|
||||
//CONS_Printf("S_LoadMusicDefs: Set title to '%s'\n", def->source);
|
||||
MusicDefStrcpy(def->title, textline,
|
||||
sizeof def->title, version);
|
||||
} else if (!stricmp(stoken, "alttitle")) {
|
||||
STRBUFCPY(def->alttitle, value);
|
||||
for (value = def->alttitle; *value; value++)
|
||||
if (*value == '_') *value = ' '; // turn _ into spaces.
|
||||
//CONS_Printf("S_LoadMusicDefs: Set alttitle to '%s'\n", def->source);
|
||||
MusicDefStrcpy(def->alttitle, textline,
|
||||
sizeof def->alttitle, version);
|
||||
} else if (!stricmp(stoken, "authors")) {
|
||||
STRBUFCPY(def->authors, value);
|
||||
for (value = def->authors; *value; value++)
|
||||
if (*value == '_') *value = ' '; // turn _ into spaces.
|
||||
//CONS_Printf("S_LoadMusicDefs: Set authors to '%s'\n", def->source);
|
||||
MusicDefStrcpy(def->authors, textline,
|
||||
sizeof def->authors, version);
|
||||
} else if (!stricmp(stoken, "soundtestpage")) {
|
||||
def->soundtestpage = (UINT8)i;
|
||||
} else if (!stricmp(stoken, "soundtestcond")) {
|
||||
// Convert to map number
|
||||
if (value[0] >= 'A' && value[0] <= 'Z' && value[2] == '\0')
|
||||
i = M_MapNumber(value[0], value[1]);
|
||||
if (textline[0] >= 'A' && textline[0] <= 'Z' && textline[2] == '\0')
|
||||
i = M_MapNumber(textline[0], textline[1]);
|
||||
def->soundtestcond = (INT16)i;
|
||||
} else if (!stricmp(stoken, "stoppingtime")) {
|
||||
double stoppingtime = atof(value)*TICRATE;
|
||||
double stoppingtime = atof(textline)*TICRATE;
|
||||
def->stoppingtics = (tic_t)stoppingtime;
|
||||
} else if (!stricmp(stoken, "bpm")) {
|
||||
double bpm = atof(value);
|
||||
double bpm = atof(textline);
|
||||
fixed_t bpmf = FLOAT_TO_FIXED(bpm);
|
||||
if (bpmf > 0)
|
||||
def->bpm = FixedDiv((60*TICRATE)<<FRACBITS, bpmf);
|
||||
} else {
|
||||
CONS_Alert(CONS_WARNING, "MUSICDEF: Invalid field '%s'. (file %s, line %d)\n", stoken, wadfiles[wadnum]->filename, line);
|
||||
CONS_Alert(CONS_WARNING,
|
||||
"MUSICDEF: Invalid field '%s'. (file %s, line %d)\n",
|
||||
stoken, wadfiles[wadnum]->filename, line);
|
||||
}
|
||||
|
||||
skip_field:
|
||||
stoken = strtok(NULL, "\r\n= ");
|
||||
line++;
|
||||
}
|
||||
}
|
||||
|
||||
free(buf2);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
void S_LoadMusicDefs(UINT16 wadnum)
|
||||
{
|
||||
UINT16 lumpnum;
|
||||
char *lump;
|
||||
char *musdeftext;
|
||||
size_t size;
|
||||
|
||||
char *lf;
|
||||
char *stoken;
|
||||
|
||||
size_t nlf;
|
||||
size_t ncr;
|
||||
|
||||
musicdef_t *def = NULL;
|
||||
int version = MUSICDEF_220;
|
||||
int line = 1; // for better error msgs
|
||||
boolean fields = false;
|
||||
|
||||
lumpnum = W_CheckForMusicDefInPwad(wadnum);
|
||||
if (lumpnum == INT16_MAX)
|
||||
return;
|
||||
|
||||
lump = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
|
||||
size = W_LumpLengthPwad(wadnum, lumpnum);
|
||||
|
||||
// Null-terminated MUSICDEF lump.
|
||||
musdeftext = malloc(size+1);
|
||||
if (!musdeftext)
|
||||
I_Error("S_LoadMusicDefs: No more free memory for the parser\n");
|
||||
M_Memcpy(musdeftext, lump, size);
|
||||
musdeftext[size] = '\0';
|
||||
|
||||
// Find music def
|
||||
stoken = musdeftext;
|
||||
for (;;)
|
||||
{
|
||||
lf = strpbrk(stoken, "\r\n");
|
||||
if (lf)
|
||||
{
|
||||
if (*lf == '\n')
|
||||
nlf = 1;
|
||||
else
|
||||
nlf = 0;
|
||||
*lf++ = '\0';/* now we can delimit to here */
|
||||
}
|
||||
|
||||
stoken = strtok(stoken, " ");
|
||||
if (stoken)
|
||||
{
|
||||
if (! ReadMusicDefFields(wadnum, line, fields, stoken,
|
||||
&def, &version))
|
||||
break;
|
||||
fields = true;
|
||||
}
|
||||
|
||||
if (lf)
|
||||
{
|
||||
do
|
||||
{
|
||||
line += nlf;
|
||||
ncr = strspn(lf, "\r");/* skip CR */
|
||||
lf += ncr;
|
||||
nlf = strspn(lf, "\n");
|
||||
lf += nlf;
|
||||
}
|
||||
while (nlf || ncr) ;
|
||||
|
||||
stoken = lf;/* now the next nonempty line */
|
||||
}
|
||||
else
|
||||
break;/* EOF */
|
||||
}
|
||||
|
||||
free(musdeftext);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -35,6 +35,8 @@ extern consvar_t cv_numChannels;
|
|||
extern consvar_t cv_resetmusic;
|
||||
extern consvar_t cv_resetmusicbyheader;
|
||||
|
||||
extern consvar_t cv_1upsound;
|
||||
|
||||
#define RESETMUSIC (!modeattacking && \
|
||||
(cv_resetmusicbyheader.value ? \
|
||||
(mapheaderinfo[gamemap-1]->musforcereset != -1 ? mapheaderinfo[gamemap-1]->musforcereset : cv_resetmusic.value) \
|
||||
|
|
|
@ -360,10 +360,13 @@ void SCR_Recalc(void)
|
|||
vid.fsmalldupy = vid.smalldupy*FRACUNIT;
|
||||
#endif
|
||||
|
||||
// toggle off automap because some screensize-dependent values will
|
||||
// toggle off (then back on) the automap because some screensize-dependent values will
|
||||
// be calculated next time the automap is activated.
|
||||
if (automapactive)
|
||||
AM_Stop();
|
||||
{
|
||||
am_recalc = true;
|
||||
AM_Start();
|
||||
}
|
||||
|
||||
// set the screen[x] ptrs on the new vidbuffers
|
||||
V_Init();
|
||||
|
|
|
@ -110,7 +110,6 @@ static SDL_bool disable_fullscreen = SDL_FALSE;
|
|||
#define USE_FULLSCREEN (disable_fullscreen||!allow_fullscreen)?0:cv_fullscreen.value
|
||||
static SDL_bool disable_mouse = SDL_FALSE;
|
||||
#define USE_MOUSEINPUT (!disable_mouse && cv_usemouse.value && havefocus)
|
||||
#define IGNORE_MOUSE (!cv_alwaysgrabmouse.value && (menuactive || paused || con_destlines || chat_on || gamestate != GS_LEVEL))
|
||||
#define MOUSE_MENU false //(!disable_mouse && cv_usemouse.value && menuactive && !USE_FULLSCREEN)
|
||||
#define MOUSEBUTTONS_MAX MOUSEBUTTONS
|
||||
|
||||
|
@ -362,6 +361,17 @@ static INT32 Impl_SDL_Scancode_To_Keycode(SDL_Scancode code)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static boolean IgnoreMouse(void)
|
||||
{
|
||||
if (cv_alwaysgrabmouse.value)
|
||||
return false;
|
||||
if (menuactive)
|
||||
return !M_MouseNeeded();
|
||||
if (paused || con_destlines || chat_on || gamestate != GS_LEVEL)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void SDLdoGrabMouse(void)
|
||||
{
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
|
@ -388,7 +398,7 @@ void I_UpdateMouseGrab(void)
|
|||
{
|
||||
if (SDL_WasInit(SDL_INIT_VIDEO) == SDL_INIT_VIDEO && window != NULL
|
||||
&& SDL_GetMouseFocus() == window && SDL_GetKeyboardFocus() == window
|
||||
&& USE_MOUSEINPUT && !IGNORE_MOUSE)
|
||||
&& USE_MOUSEINPUT && !IgnoreMouse())
|
||||
SDLdoGrabMouse();
|
||||
}
|
||||
|
||||
|
@ -596,7 +606,7 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
|
|||
}
|
||||
//else firsttimeonmouse = SDL_FALSE;
|
||||
|
||||
if (USE_MOUSEINPUT && !IGNORE_MOUSE)
|
||||
if (USE_MOUSEINPUT && !IgnoreMouse())
|
||||
SDLdoGrabMouse();
|
||||
}
|
||||
else if (!mousefocus && !kbfocus)
|
||||
|
@ -647,7 +657,7 @@ static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt)
|
|||
|
||||
if (USE_MOUSEINPUT)
|
||||
{
|
||||
if ((SDL_GetMouseFocus() != window && SDL_GetKeyboardFocus() != window) || (IGNORE_MOUSE && !firstmove))
|
||||
if ((SDL_GetMouseFocus() != window && SDL_GetKeyboardFocus() != window) || (IgnoreMouse() && !firstmove))
|
||||
{
|
||||
SDLdoUngrabMouse();
|
||||
firstmove = false;
|
||||
|
@ -700,7 +710,7 @@ static void Impl_HandleMouseButtonEvent(SDL_MouseButtonEvent evt, Uint32 type)
|
|||
// this apparently makes a mouse button down event but not a mouse button up event,
|
||||
// resulting in whatever key was pressed down getting "stuck" if we don't ignore it.
|
||||
// -- Monster Iestyn (28/05/18)
|
||||
if (SDL_GetMouseFocus() != window || IGNORE_MOUSE)
|
||||
if (SDL_GetMouseFocus() != window || IgnoreMouse())
|
||||
return;
|
||||
|
||||
/// \todo inputEvent.button.which
|
||||
|
@ -1082,7 +1092,7 @@ void I_StartupMouse(void)
|
|||
}
|
||||
else
|
||||
firsttimeonmouse = SDL_FALSE;
|
||||
if (cv_usemouse.value && !IGNORE_MOUSE)
|
||||
if (cv_usemouse.value && !IgnoreMouse())
|
||||
SDLdoGrabMouse();
|
||||
else
|
||||
SDLdoUngrabMouse();
|
||||
|
|
|
@ -1219,7 +1219,7 @@
|
|||
C01FCF4B08A954540054247B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CURRENT_PROJECT_VERSION = 2.2.0;
|
||||
CURRENT_PROJECT_VERSION = 2.2.1;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"$(inherited)",
|
||||
NORMALSRB2,
|
||||
|
@ -1231,7 +1231,7 @@
|
|||
C01FCF4C08A954540054247B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CURRENT_PROJECT_VERSION = 2.2.0;
|
||||
CURRENT_PROJECT_VERSION = 2.2.1;
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = NO;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
|
|
|
@ -1278,13 +1278,15 @@ void ST_preDrawTitleCard(void)
|
|||
//
|
||||
void ST_runTitleCard(void)
|
||||
{
|
||||
boolean run = !(paused || P_AutoPause());
|
||||
|
||||
if (!G_IsTitleCardAvailable())
|
||||
return;
|
||||
|
||||
if (lt_ticker >= (lt_endtime + TICRATE))
|
||||
return;
|
||||
|
||||
if (!(paused || P_AutoPause()))
|
||||
if (run || (lt_ticker < PRELEVELTIME))
|
||||
{
|
||||
// tick
|
||||
lt_ticker++;
|
||||
|
|
|
@ -3244,7 +3244,6 @@ Unoptimized version
|
|||
#endif
|
||||
}
|
||||
|
||||
// Taken from my videos-in-SRB2 project
|
||||
// Generates a color look-up table
|
||||
// which has up to 64 colors at each channel
|
||||
// (see the defines in v_video.h)
|
||||
|
@ -3261,7 +3260,7 @@ void InitColorLUT(RGBA_t *palette)
|
|||
for (r = 0; r < CLUTSIZE; r++)
|
||||
for (g = 0; g < CLUTSIZE; g++)
|
||||
for (b = 0; b < CLUTSIZE; b++)
|
||||
colorlookup[r][g][b] = NearestColor(r << SHIFTCOLORBITS, g << SHIFTCOLORBITS, b << SHIFTCOLORBITS);
|
||||
colorlookup[r][g][b] = NearestPaletteColor(r << SHIFTCOLORBITS, g << SHIFTCOLORBITS, b << SHIFTCOLORBITS, palette);
|
||||
clutinit = true;
|
||||
lastpalette = palette;
|
||||
}
|
||||
|
|
|
@ -37,10 +37,7 @@ cv_allcaps;
|
|||
// Allocates buffer screens, call before R_Init.
|
||||
void V_Init(void);
|
||||
|
||||
// Taken from my videos-in-SRB2 project
|
||||
// Generates a color look-up table
|
||||
// which has up to 64 colors at each channel
|
||||
|
||||
// Color look-up table
|
||||
#define COLORBITS 6
|
||||
#define SHIFTCOLORBITS (8-COLORBITS)
|
||||
#define CLUTSIZE (1<<COLORBITS)
|
||||
|
|
37
src/w_wad.c
37
src/w_wad.c
|
@ -822,13 +822,11 @@ UINT16 W_InitFile(const char *filename, boolean mainfile)
|
|||
* backwards, so a later file overrides all earlier ones.
|
||||
*
|
||||
* \param filenames A null-terminated list of files to use.
|
||||
* \return 1 if all files were loaded, 0 if at least one was missing or
|
||||
* \return 1 if base files were loaded, 0 if at least one was missing or
|
||||
* invalid.
|
||||
*/
|
||||
INT32 W_InitMultipleFiles(char **filenames, UINT16 mainfiles)
|
||||
{
|
||||
INT32 rc = 1;
|
||||
|
||||
// open all the files, load headers, and count lumps
|
||||
numwadfiles = 0;
|
||||
|
||||
|
@ -836,13 +834,15 @@ INT32 W_InitMultipleFiles(char **filenames, UINT16 mainfiles)
|
|||
for (; *filenames; filenames++)
|
||||
{
|
||||
//CONS_Debug(DBG_SETUP, "Loading %s\n", *filenames);
|
||||
rc &= (W_InitFile(*filenames, numwadfiles < mainfiles) != INT16_MAX) ? 1 : 0;
|
||||
if (W_InitFile(*filenames, numwadfiles < mainfiles) == INT16_MAX)
|
||||
{
|
||||
CONS_Printf(M_GetText("Errors occurred while loading %s; not added.\n"), *filenames);
|
||||
if (numwadfiles < mainfiles)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!numwadfiles)
|
||||
I_Error("W_InitMultipleFiles: no files found");
|
||||
|
||||
return rc;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Make sure a lump number is valid.
|
||||
|
@ -1691,7 +1691,7 @@ W_VerifyName (const char *name, lumpchecklist_t *checklist, boolean status)
|
|||
size_t j;
|
||||
for (j = 0; checklist[j].len && checklist[j].name; ++j)
|
||||
{
|
||||
if (( strncmp(name, checklist[j].name,
|
||||
if (( strncasecmp(name, checklist[j].name,
|
||||
checklist[j].len) != false ) == status)
|
||||
{
|
||||
return true;
|
||||
|
@ -1746,6 +1746,19 @@ W_VerifyWAD (FILE *fp, lumpchecklist_t *checklist, boolean status)
|
|||
return true;
|
||||
}
|
||||
|
||||
// List of blacklisted folders to use when checking the PK3
|
||||
static lumpchecklist_t folderblacklist[] =
|
||||
{
|
||||
{"Lua/", 4},
|
||||
{"SOC/", 4},
|
||||
{"Sprites/", 8},
|
||||
{"Textures/", 9},
|
||||
{"Patches/", 8},
|
||||
{"Flats/", 6},
|
||||
{"Fades/", 6},
|
||||
{NULL, 0},
|
||||
};
|
||||
|
||||
static int
|
||||
W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status)
|
||||
{
|
||||
|
@ -1797,7 +1810,7 @@ W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status)
|
|||
else
|
||||
trimname = fullname; // Care taken for root files.
|
||||
|
||||
if (*trimname) // Ignore directories
|
||||
if (*trimname) // Ignore directories, well kinda
|
||||
{
|
||||
if ((dotpos = strrchr(trimname, '.')) == 0)
|
||||
dotpos = fullname + strlen(fullname); // Watch for files without extension.
|
||||
|
@ -1807,6 +1820,10 @@ W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status)
|
|||
|
||||
if (! W_VerifyName(lumpname, checklist, status))
|
||||
return false;
|
||||
|
||||
// Check for directories next, if it's blacklisted it will return false
|
||||
if (W_VerifyName(fullname, folderblacklist, status))
|
||||
return false;
|
||||
}
|
||||
|
||||
free(fullname);
|
||||
|
|
19
src/z_zone.c
19
src/z_zone.c
|
@ -232,12 +232,12 @@ void Z_Free(void *ptr)
|
|||
|
||||
// Free the memory and get rid of the block.
|
||||
free(block->real);
|
||||
block->prev->next = block->next;
|
||||
block->next->prev = block->prev;
|
||||
free(block);
|
||||
#ifdef VALGRIND_DESTROY_MEMPOOL
|
||||
VALGRIND_DESTROY_MEMPOOL(block);
|
||||
#endif
|
||||
block->prev->next = block->next;
|
||||
block->next->prev = block->prev;
|
||||
free(block);
|
||||
}
|
||||
|
||||
/** malloc() that doesn't accept failure.
|
||||
|
@ -317,13 +317,9 @@ void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits)
|
|||
// The mem header lives 'sizeof (memhdr_t)' bytes before given.
|
||||
hdr = (memhdr_t *)((UINT8 *)given - sizeof *hdr);
|
||||
|
||||
#ifdef VALGRIND_CREATE_MEMPOOL
|
||||
VALGRIND_CREATE_MEMPOOL(block, padsize, Z_calloc);
|
||||
#ifdef HAVE_VALGRIND
|
||||
Z_calloc = false;
|
||||
#endif
|
||||
#ifdef VALGRIND_MEMPOOL_ALLOC
|
||||
VALGRIND_MEMPOOL_ALLOC(block, hdr, size + sizeof *hdr);
|
||||
#endif
|
||||
|
||||
block->next = head.next;
|
||||
block->prev = &head;
|
||||
|
@ -341,6 +337,13 @@ void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits)
|
|||
block->size = blocksize;
|
||||
block->realsize = size;
|
||||
|
||||
#ifdef VALGRIND_CREATE_MEMPOOL
|
||||
VALGRIND_CREATE_MEMPOOL(block, padsize, Z_calloc);
|
||||
#endif
|
||||
//#ifdef VALGRIND_MEMPOOL_ALLOC
|
||||
// VALGRIND_MEMPOOL_ALLOC(block, hdr, size + sizeof *hdr);
|
||||
//#endif
|
||||
|
||||
hdr->id = ZONEID;
|
||||
hdr->block = block;
|
||||
|
||||
|
|
1
tools/musicdef-2.2.1/Makefile
Normal file
1
tools/musicdef-2.2.1/Makefile
Normal file
|
@ -0,0 +1 @@
|
|||
musicdef-2.2.1:
|
77
tools/musicdef-2.2.1/musicdef-2.2.1.c
Normal file
77
tools/musicdef-2.2.1/musicdef-2.2.1.c
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
Copyright 2020 James R.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define strcasecmp _stricmp
|
||||
#else
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
int
|
||||
main (int ac, char **av)
|
||||
{
|
||||
char line[256];
|
||||
char buf[256];
|
||||
char *var;
|
||||
char *val;
|
||||
char *p;
|
||||
int n;
|
||||
(void)ac;
|
||||
(void)av;
|
||||
fputs(
|
||||
"Copyright 2020 James R.\n"
|
||||
"All rights reserved.\n"
|
||||
"\n"
|
||||
"Usage: musicdef-2.2.1 < old-MUSICDEF > new-MUSICDEF\n"
|
||||
"\n"
|
||||
,stderr);
|
||||
while (fgets(line, sizeof line, stdin))
|
||||
{
|
||||
memcpy(buf, line, sizeof buf);
|
||||
if (( var = strtok(buf, " =") ))
|
||||
{
|
||||
if (!(
|
||||
strcasecmp(var, "TITLE") &&
|
||||
strcasecmp(var, "ALTTITLE") &&
|
||||
strcasecmp(var, "AUTHORS")
|
||||
)){
|
||||
if (( val = strtok(0, "") ))
|
||||
{
|
||||
for (p = val; ( p = strchr(p, '_') ); )
|
||||
{
|
||||
n = strspn(p, "_");
|
||||
memset(p, ' ', n);
|
||||
p += n;
|
||||
}
|
||||
printf("%s %s", var, val);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
fputs(line, stdout);
|
||||
}
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue