mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-01-24 10:11:33 +00:00
Merge branch SRB2:next into addonloadedhook
This commit is contained in:
commit
675667cb83
66 changed files with 1858 additions and 912 deletions
|
@ -1,5 +1,5 @@
|
|||
===============================================================================
|
||||
Universal Doom Map Format Sonic Robo Blast 2 extensions v1.0 19.02.2024
|
||||
Universal Doom Map Format Sonic Robo Blast 2 extensions v1.0 19.06.2024
|
||||
|
||||
Copyright (c) 2024 Sonic Team Junior
|
||||
uses Universal Doom Map Format Specification v1.1 as a template,
|
||||
|
@ -143,6 +143,9 @@ Sonic Robo Blast 2 defines the following standardized fields:
|
|||
offsetx_bottom = <float>; // X offset for lower texture. Default = 0.0.
|
||||
offsety_bottom = <float>; // Y offset for lower texture. Default = 0.0.
|
||||
|
||||
light = <integer>; // Light level, relative to 'sector' light level. Default = 0.
|
||||
lightabsolute = <bool>; // true = 'light' is an absolute value, ignoring 'sector' light level.
|
||||
|
||||
comment = <string>; // A comment. Implementors should attach no special
|
||||
// semantic meaning to this field.
|
||||
}
|
||||
|
|
|
@ -115,7 +115,7 @@ mapformat_udmf
|
|||
|
||||
// Enables setting distinct brightness for floor, ceiling, and walls
|
||||
distinctfloorandceilingbrightness = true;
|
||||
distinctwallbrightness = false;
|
||||
distinctwallbrightness = true;
|
||||
|
||||
// Enables setting distinct brightness for upper, middle, and lower sidedef parts
|
||||
distinctsidedefpartbrightness = false;
|
||||
|
|
|
@ -280,18 +280,18 @@ universalfields
|
|||
default = "";
|
||||
}
|
||||
|
||||
//light
|
||||
//{
|
||||
// type = 0;
|
||||
// default = 0;
|
||||
//}
|
||||
//
|
||||
//lightabsolute
|
||||
//{
|
||||
// type = 3;
|
||||
// default = false;
|
||||
//}
|
||||
//
|
||||
light
|
||||
{
|
||||
type = 0;
|
||||
default = 0;
|
||||
}
|
||||
|
||||
lightabsolute
|
||||
{
|
||||
type = 3;
|
||||
default = false;
|
||||
}
|
||||
|
||||
//light_top
|
||||
//{
|
||||
// type = 0;
|
||||
|
|
|
@ -71,7 +71,7 @@ apng_create_info_struct (png_structp pngp)
|
|||
{
|
||||
apng_infop ainfop;
|
||||
(void)pngp;
|
||||
if (( ainfop = calloc(sizeof (apng_info),1) ))
|
||||
if (( ainfop = calloc(1,sizeof (apng_info)) ))
|
||||
{
|
||||
apng_set_write_fn(pngp, ainfop, 0, 0, 0, 0, 0);
|
||||
apng_set_set_acTL_fn(pngp, ainfop, 0);
|
||||
|
|
|
@ -11,9 +11,6 @@
|
|||
/// \brief Macros to read/write from/to a UINT8 *,
|
||||
/// used for packet creation and such
|
||||
|
||||
#if defined (__alpha__) || defined (__arm__) || defined (__mips__) || defined (__ia64__) || defined (__clang__)
|
||||
#define DEALIGNED
|
||||
#endif
|
||||
|
||||
#include "endian.h"
|
||||
|
||||
|
@ -21,7 +18,6 @@
|
|||
//
|
||||
// Little-endian machines
|
||||
//
|
||||
#ifdef DEALIGNED
|
||||
#define WRITEUINT8(p,b) do { UINT8 *p_tmp = (void *)p; const UINT8 tv = ( UINT8)(b); memcpy(p, &tv, sizeof( UINT8)); p_tmp++; p = (void *)p_tmp; } while (0)
|
||||
#define WRITESINT8(p,b) do { SINT8 *p_tmp = (void *)p; const SINT8 tv = ( UINT8)(b); memcpy(p, &tv, sizeof( UINT8)); p_tmp++; p = (void *)p_tmp; } while (0)
|
||||
#define WRITEINT16(p,b) do { INT16 *p_tmp = (void *)p; const INT16 tv = ( INT16)(b); memcpy(p, &tv, sizeof( INT16)); p_tmp++; p = (void *)p_tmp; } while (0)
|
||||
|
@ -31,20 +27,8 @@
|
|||
#define WRITECHAR(p,b) do { char *p_tmp = (void *)p; const char tv = ( char)(b); memcpy(p, &tv, sizeof( char)); p_tmp++; p = (void *)p_tmp; } while (0)
|
||||
#define WRITEFIXED(p,b) do { fixed_t *p_tmp = (void *)p; const fixed_t tv = (fixed_t)(b); memcpy(p, &tv, sizeof(fixed_t)); p_tmp++; p = (void *)p_tmp; } while (0)
|
||||
#define WRITEANGLE(p,b) do { angle_t *p_tmp = (void *)p; const angle_t tv = (angle_t)(b); memcpy(p, &tv, sizeof(angle_t)); p_tmp++; p = (void *)p_tmp; } while (0)
|
||||
#else
|
||||
#define WRITEUINT8(p,b) do { UINT8 *p_tmp = ( UINT8 *)p; *p_tmp = ( UINT8)(b); p_tmp++; p = (void *)p_tmp; } while (0)
|
||||
#define WRITESINT8(p,b) do { SINT8 *p_tmp = ( SINT8 *)p; *p_tmp = ( SINT8)(b); p_tmp++; p = (void *)p_tmp; } while (0)
|
||||
#define WRITEINT16(p,b) do { INT16 *p_tmp = ( INT16 *)p; *p_tmp = ( INT16)(b); p_tmp++; p = (void *)p_tmp; } while (0)
|
||||
#define WRITEUINT16(p,b) do { UINT16 *p_tmp = ( UINT16 *)p; *p_tmp = ( UINT16)(b); p_tmp++; p = (void *)p_tmp; } while (0)
|
||||
#define WRITEINT32(p,b) do { INT32 *p_tmp = ( INT32 *)p; *p_tmp = ( INT32)(b); p_tmp++; p = (void *)p_tmp; } while (0)
|
||||
#define WRITEUINT32(p,b) do { UINT32 *p_tmp = ( UINT32 *)p; *p_tmp = ( UINT32)(b); p_tmp++; p = (void *)p_tmp; } while (0)
|
||||
#define WRITECHAR(p,b) do { char *p_tmp = ( char *)p; *p_tmp = ( char)(b); p_tmp++; p = (void *)p_tmp; } while (0)
|
||||
#define WRITEFIXED(p,b) do { fixed_t *p_tmp = (fixed_t *)p; *p_tmp = (fixed_t)(b); p_tmp++; p = (void *)p_tmp; } while (0)
|
||||
#define WRITEANGLE(p,b) do { angle_t *p_tmp = (angle_t *)p; *p_tmp = (angle_t)(b); p_tmp++; p = (void *)p_tmp; } while (0)
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#ifdef DEALIGNED
|
||||
#define READUINT8(p) ({ UINT8 *p_tmp = (void *)p; UINT8 b; memcpy(&b, p, sizeof( UINT8)); p_tmp++; p = (void *)p_tmp; b; })
|
||||
#define READSINT8(p) ({ SINT8 *p_tmp = (void *)p; SINT8 b; memcpy(&b, p, sizeof( SINT8)); p_tmp++; p = (void *)p_tmp; b; })
|
||||
#define READINT16(p) ({ INT16 *p_tmp = (void *)p; INT16 b; memcpy(&b, p, sizeof( INT16)); p_tmp++; p = (void *)p_tmp; b; })
|
||||
|
@ -55,17 +39,6 @@
|
|||
#define READFIXED(p) ({ fixed_t *p_tmp = (void *)p; fixed_t b; memcpy(&b, p, sizeof(fixed_t)); p_tmp++; p = (void *)p_tmp; b; })
|
||||
#define READANGLE(p) ({ angle_t *p_tmp = (void *)p; angle_t b; memcpy(&b, p, sizeof(angle_t)); p_tmp++; p = (void *)p_tmp; b; })
|
||||
#else
|
||||
#define READUINT8(p) ({ UINT8 *p_tmp = ( UINT8 *)p; UINT8 b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
|
||||
#define READSINT8(p) ({ SINT8 *p_tmp = ( SINT8 *)p; SINT8 b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
|
||||
#define READINT16(p) ({ INT16 *p_tmp = ( INT16 *)p; INT16 b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
|
||||
#define READUINT16(p) ({ UINT16 *p_tmp = ( UINT16 *)p; UINT16 b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
|
||||
#define READINT32(p) ({ INT32 *p_tmp = ( INT32 *)p; INT32 b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
|
||||
#define READUINT32(p) ({ UINT32 *p_tmp = ( UINT32 *)p; UINT32 b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
|
||||
#define READCHAR(p) ({ char *p_tmp = ( char *)p; char b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
|
||||
#define READFIXED(p) ({ fixed_t *p_tmp = (fixed_t *)p; fixed_t b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
|
||||
#define READANGLE(p) ({ angle_t *p_tmp = (angle_t *)p; angle_t b = *p_tmp; p_tmp++; p = (void *)p_tmp; b; })
|
||||
#endif
|
||||
#else
|
||||
#define READUINT8(p) *(( UINT8 *)p)++
|
||||
#define READSINT8(p) *(( SINT8 *)p)++
|
||||
#define READINT16(p) *(( INT16 *)p)++
|
||||
|
@ -148,8 +121,6 @@ FUNCINLINE static ATTRINLINE UINT32 readulong(void *ptr)
|
|||
#define READANGLE(p) ({ angle_t *p_tmp = (angle_t *)p; angle_t b = readulong(p); p_tmp++; p = (void *)p_tmp; b; })
|
||||
#endif //SRB2_BIG_ENDIAN
|
||||
|
||||
#undef DEALIGNED
|
||||
|
||||
#define WRITESTRINGN(p, s, n) { \
|
||||
size_t tmp_i; \
|
||||
\
|
||||
|
|
|
@ -1992,7 +1992,7 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth)
|
|||
if (var->flags & CV_NETVAR)
|
||||
{
|
||||
// send the value of the variable
|
||||
UINT8 buf[128];
|
||||
UINT8 buf[512];
|
||||
UINT8 *p = buf;
|
||||
|
||||
// Loading from a config in a netgame? Set revert value.
|
||||
|
@ -2065,11 +2065,10 @@ static void CV_SetValueMaybeStealth(consvar_t *var, INT32 value, boolean stealth
|
|||
if (var == &cv_forceskin) // Special handling.
|
||||
{
|
||||
const char *tmpskin = NULL;
|
||||
if ((value < 0) || (value >= numskins))
|
||||
;
|
||||
else
|
||||
if (value >= 0 && value < numskins)
|
||||
tmpskin = skins[value]->name;
|
||||
memcpy(val, tmpskin, SKINNAMESIZE);
|
||||
if (tmpskin)
|
||||
memcpy(val, tmpskin, SKINNAMESIZE);
|
||||
}
|
||||
else
|
||||
sprintf(val, "%d", value);
|
||||
|
|
12
src/d_main.c
12
src/d_main.c
|
@ -679,13 +679,13 @@ static void D_Display(void)
|
|||
s[sizeof s - 1] = '\0';
|
||||
|
||||
snprintf(s, sizeof s - 1, "get %d b/s", getbps);
|
||||
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-ST_HEIGHT-40, V_YELLOWMAP, s);
|
||||
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-40, V_YELLOWMAP, s);
|
||||
snprintf(s, sizeof s - 1, "send %d b/s", sendbps);
|
||||
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-ST_HEIGHT-30, V_YELLOWMAP, s);
|
||||
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-30, V_YELLOWMAP, s);
|
||||
snprintf(s, sizeof s - 1, "GameMiss %.2f%%", gamelostpercent);
|
||||
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-ST_HEIGHT-20, V_YELLOWMAP, s);
|
||||
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-20, V_YELLOWMAP, s);
|
||||
snprintf(s, sizeof s - 1, "SysMiss %.2f%%", lostpercent);
|
||||
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-ST_HEIGHT-10, V_YELLOWMAP, s);
|
||||
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-10, V_YELLOWMAP, s);
|
||||
}
|
||||
|
||||
if (cv_perfstats.value)
|
||||
|
@ -1024,7 +1024,7 @@ void D_StartTitle(void)
|
|||
#define REALLOC_FILE_LIST \
|
||||
if (list->files == NULL) \
|
||||
{ \
|
||||
list->files = calloc(sizeof(list->files), 2); \
|
||||
list->files = calloc(2, sizeof(list->files)); \
|
||||
list->numfiles = 1; \
|
||||
} \
|
||||
else \
|
||||
|
@ -1535,7 +1535,7 @@ void D_SRB2Main(void)
|
|||
I_Error("Cannot find a map remotely named '%s'\n", word);
|
||||
else
|
||||
{
|
||||
if (!M_CheckParm("-server"))
|
||||
if (!(M_CheckParm("-server") || dedicated))
|
||||
G_SetUsedCheats(true);
|
||||
autostart = true;
|
||||
}
|
||||
|
|
|
@ -1390,8 +1390,8 @@ static const char *searchWad(const char *searchDir)
|
|||
|
||||
#define CHECKWADPATH(ret) \
|
||||
do { \
|
||||
I_OutputMsg(",%s", returnWadPath); \
|
||||
if (isWadPathOk(returnWadPath)) \
|
||||
I_OutputMsg(",%s", ret); \
|
||||
if (isWadPathOk(ret)) \
|
||||
return ret; \
|
||||
} while (0)
|
||||
|
||||
|
@ -1416,7 +1416,9 @@ static const char *locateWad(void)
|
|||
#ifndef NOCWD
|
||||
// examine current dir
|
||||
strcpy(returnWadPath, ".");
|
||||
CHECKWADPATH(NULL);
|
||||
I_OutputMsg(",%s", returnWadPath);
|
||||
if (isWadPathOk(returnWadPath))
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
@ -1433,9 +1435,15 @@ static const char *locateWad(void)
|
|||
|
||||
#ifndef NOHOME
|
||||
// find in $HOME
|
||||
I_OutputMsg(",HOME");
|
||||
if ((envstr = I_GetEnv("HOME")) != NULL)
|
||||
SEARCHWAD(envstr);
|
||||
{
|
||||
char *tmp = malloc(strlen(envstr) + 1 + sizeof(DEFAULTDIR));
|
||||
strcpy(tmp, envstr);
|
||||
strcat(tmp, "/");
|
||||
strcat(tmp, DEFAULTDIR);
|
||||
CHECKWADPATH(tmp);
|
||||
free(tmp);
|
||||
}
|
||||
#endif
|
||||
|
||||
// search paths
|
||||
|
|
|
@ -2791,7 +2791,7 @@ void readframe(MYFILE *f, INT32 num)
|
|||
size_t z;
|
||||
boolean found = false;
|
||||
size_t actionlen = strlen(word2) + 1;
|
||||
char *actiontocompare = calloc(actionlen, 1);
|
||||
char *actiontocompare = calloc(1, actionlen);
|
||||
|
||||
strcpy(actiontocompare, word2);
|
||||
strupr(actiontocompare);
|
||||
|
|
|
@ -4483,6 +4483,8 @@ const char *const PLAYERFLAG_LIST[] = {
|
|||
"CANCARRY", // Can carry?
|
||||
"FINISHED",
|
||||
|
||||
"SHIELDDOWN", // Shield has been pressed.
|
||||
|
||||
NULL // stop loop here.
|
||||
};
|
||||
|
||||
|
|
|
@ -444,12 +444,11 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
|||
strcpy(&searchpath[searchpathindex[depthleft]],dent->d_name);
|
||||
|
||||
#if defined(__linux__) || defined(__FreeBSD__)
|
||||
if (dent->d_type == DT_UNKNOWN)
|
||||
if (lstat(searchpath,&fsstat) == 0 && S_ISDIR(fsstat.st_mode))
|
||||
if (dent->d_type == DT_UNKNOWN || dent->d_type == DT_LNK)
|
||||
if (stat(searchpath,&fsstat) == 0 && S_ISDIR(fsstat.st_mode))
|
||||
dent->d_type = DT_DIR;
|
||||
|
||||
// Linux and FreeBSD has a special field for file type on dirent, so use that to speed up lookups.
|
||||
// FIXME: should we also follow symlinks?
|
||||
if (dent->d_type == DT_DIR && depthleft)
|
||||
#else
|
||||
if (stat(searchpath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat
|
||||
|
@ -1191,7 +1190,7 @@ boolean preparefilemenu(boolean samedepth)
|
|||
size_t i;
|
||||
|
||||
if (filenamebuf == NULL)
|
||||
filenamebuf = calloc(sizeof(char) * MAX_WADPATH, numwadfiles);
|
||||
filenamebuf = calloc(numwadfiles, sizeof(char) * MAX_WADPATH);
|
||||
|
||||
for (i = 0; i < numwadfiles; i++)
|
||||
{
|
||||
|
|
|
@ -3352,7 +3352,7 @@ void G_AddPlayer(INT32 playernum)
|
|||
|
||||
p->playerstate = PST_REBORN;
|
||||
|
||||
p->height = mobjinfo[MT_PLAYER].height;
|
||||
p->height = skins[p->skin]->height;
|
||||
|
||||
if (G_GametypeUsesLives() || ((netgame || multiplayer) && (gametyperules & GTR_FRIENDLY)))
|
||||
p->lives = cv_startinglives.value;
|
||||
|
|
|
@ -450,15 +450,10 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex, GLMipmap_t
|
|||
|
||||
texture = textures[texnum];
|
||||
|
||||
mipmap->flags = TF_WRAPXY;
|
||||
mipmap->width = (UINT16)texture->width;
|
||||
mipmap->height = (UINT16)texture->height;
|
||||
mipmap->format = textureformat;
|
||||
|
||||
blockwidth = texture->width;
|
||||
blockheight = texture->height;
|
||||
blocksize = (blockwidth * blockheight);
|
||||
block = MakeBlock(&grtex->mipmap);
|
||||
blocksize = blockwidth * blockheight;
|
||||
block = MakeBlock(mipmap);
|
||||
|
||||
// Composite the columns together.
|
||||
for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++)
|
||||
|
@ -488,7 +483,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex, GLMipmap_t
|
|||
realpatch = W_CachePatchNumPwad(wadnum, lumpnum, PU_PATCH);
|
||||
}
|
||||
|
||||
HWR_DrawTexturePatchInCache(&grtex->mipmap, blockwidth, blockheight, texture, patch, realpatch);
|
||||
HWR_DrawTexturePatchInCache(mipmap, blockwidth, blockheight, texture, patch, realpatch);
|
||||
|
||||
if (free_patch)
|
||||
Patch_Free(realpatch);
|
||||
|
@ -680,25 +675,24 @@ void HWR_InitMapTextures(void)
|
|||
gl_maptexturesloaded = false;
|
||||
}
|
||||
|
||||
static void DeleteTextureMipmap(GLMipmap_t *grMipmap)
|
||||
static void DeleteTextureMipmap(GLMipmap_t *grMipmap, boolean delete_mipmap)
|
||||
{
|
||||
HWD.pfnDeleteTexture(grMipmap);
|
||||
|
||||
// Chroma-keyed textures do not own their texture data, so do not free it
|
||||
if (!(grMipmap->flags & TF_CHROMAKEYED))
|
||||
if (delete_mipmap)
|
||||
Z_Free(grMipmap->data);
|
||||
}
|
||||
|
||||
static void FreeMapTexture(GLMapTexture_t *tex)
|
||||
static void FreeMapTexture(GLMapTexture_t *tex, boolean delete_chromakeys)
|
||||
{
|
||||
if (tex->mipmap.nextcolormap)
|
||||
{
|
||||
DeleteTextureMipmap(tex->mipmap.nextcolormap);
|
||||
DeleteTextureMipmap(tex->mipmap.nextcolormap, delete_chromakeys);
|
||||
free(tex->mipmap.nextcolormap);
|
||||
tex->mipmap.nextcolormap = NULL;
|
||||
}
|
||||
|
||||
DeleteTextureMipmap(&tex->mipmap);
|
||||
DeleteTextureMipmap(&tex->mipmap, true);
|
||||
}
|
||||
|
||||
void HWR_FreeMapTextures(void)
|
||||
|
@ -707,8 +701,8 @@ void HWR_FreeMapTextures(void)
|
|||
|
||||
for (i = 0; i < gl_numtextures; i++)
|
||||
{
|
||||
FreeMapTexture(&gl_textures[i]);
|
||||
FreeMapTexture(&gl_flats[i]);
|
||||
FreeMapTexture(&gl_textures[i], true);
|
||||
FreeMapTexture(&gl_flats[i], false);
|
||||
}
|
||||
|
||||
// now the heap don't have any 'user' pointing to our
|
||||
|
@ -741,22 +735,7 @@ void HWR_LoadMapTextures(size_t pnumtextures)
|
|||
// --------------------------------------------------------------------------
|
||||
// Make sure texture is downloaded and set it as the source
|
||||
// --------------------------------------------------------------------------
|
||||
static void GetMapTexture(INT32 tex, GLMapTexture_t *grtex, GLMipmap_t *mipmap)
|
||||
{
|
||||
// Generate texture if missing from the cache
|
||||
if (!mipmap->data && !mipmap->downloaded)
|
||||
HWR_GenerateTexture(tex, grtex, mipmap);
|
||||
|
||||
// If hardware does not have the texture, then call pfnSetTexture to upload it
|
||||
if (!mipmap->downloaded)
|
||||
HWD.pfnSetTexture(mipmap);
|
||||
HWR_SetCurrentTexture(mipmap);
|
||||
|
||||
// The system-memory data can be purged now.
|
||||
Z_ChangeTag(mipmap->data, PU_HWRCACHE_UNLOCKED);
|
||||
}
|
||||
|
||||
GLMapTexture_t *HWR_GetTexture(INT32 tex)
|
||||
GLMapTexture_t *HWR_GetTexture(INT32 tex, boolean chromakeyed)
|
||||
{
|
||||
if (tex < 0 || tex >= (signed)gl_numtextures)
|
||||
{
|
||||
|
@ -769,7 +748,46 @@ GLMapTexture_t *HWR_GetTexture(INT32 tex)
|
|||
|
||||
GLMapTexture_t *grtex = &gl_textures[tex];
|
||||
|
||||
GetMapTexture(tex, grtex, &grtex->mipmap);
|
||||
GLMipmap_t *grMipmap = &grtex->mipmap;
|
||||
GLMipmap_t *originalMipmap = grMipmap;
|
||||
|
||||
if (!originalMipmap->downloaded)
|
||||
{
|
||||
originalMipmap->flags = TF_WRAPXY;
|
||||
originalMipmap->width = (UINT16)textures[tex]->width;
|
||||
originalMipmap->height = (UINT16)textures[tex]->height;
|
||||
originalMipmap->format = textureformat;
|
||||
}
|
||||
|
||||
// If chroma-keyed, create or use a different mipmap for the variant
|
||||
if (chromakeyed && !textures[tex]->transparency)
|
||||
{
|
||||
// Allocate it if it wasn't already
|
||||
if (!originalMipmap->nextcolormap)
|
||||
{
|
||||
GLMipmap_t *newMipmap = calloc(1, sizeof (*grMipmap));
|
||||
if (newMipmap == NULL)
|
||||
I_Error("%s: Out of memory", "HWR_GetTexture");
|
||||
|
||||
newMipmap->flags = originalMipmap->flags | TF_CHROMAKEYED;
|
||||
newMipmap->width = originalMipmap->width;
|
||||
newMipmap->height = originalMipmap->height;
|
||||
newMipmap->format = originalMipmap->format;
|
||||
originalMipmap->nextcolormap = newMipmap;
|
||||
}
|
||||
|
||||
// Generate, upload and bind the variant texture instead of the original one
|
||||
grMipmap = originalMipmap->nextcolormap;
|
||||
}
|
||||
|
||||
if (!grMipmap->data)
|
||||
HWR_GenerateTexture(tex, grtex, grMipmap);
|
||||
|
||||
if (!grMipmap->downloaded)
|
||||
HWD.pfnSetTexture(grMipmap);
|
||||
HWR_SetCurrentTexture(grMipmap);
|
||||
|
||||
Z_ChangeTag(grMipmap->data, PU_HWRCACHE_UNLOCKED);
|
||||
|
||||
return grtex;
|
||||
}
|
||||
|
|
|
@ -120,7 +120,7 @@ void HWR_GetPatch(patch_t *patch);
|
|||
void HWR_GetMappedPatch(patch_t *patch, const UINT8 *colormap);
|
||||
void HWR_GetFadeMask(lumpnum_t fademasklumpnum);
|
||||
|
||||
GLMapTexture_t *HWR_GetTexture(INT32 tex);
|
||||
GLMapTexture_t *HWR_GetTexture(INT32 tex, boolean chromakeyed);
|
||||
void HWR_GetLevelFlat(levelflat_t *levelflat, boolean chromakeyed);
|
||||
void HWR_GetRawFlat(lumpnum_t flatlumpnum);
|
||||
|
||||
|
|
|
@ -309,6 +309,43 @@ static FUINT HWR_CalcSlopeLight(FUINT lightnum, angle_t dir, fixed_t delta)
|
|||
return (FUINT)finallight;
|
||||
}
|
||||
|
||||
static UINT8 HWR_SideLightLevel(side_t *side, INT16 base_lightlevel)
|
||||
{
|
||||
return max(0, min(255, side->light +
|
||||
((side->lightabsolute) ? 0 : base_lightlevel)));
|
||||
}
|
||||
|
||||
/* TODO: implement per-texture lighting
|
||||
static UINT8 HWR_TopLightLevel(side_t *side, INT16 base_lightlevel)
|
||||
{
|
||||
return max(0, min(255, side->light_top +
|
||||
((side->lightabsolute_top) ? 0 : HWR_SideLightLevel(side, base_lightlevel))));
|
||||
}
|
||||
|
||||
static UINT8 HWR_MidLightLevel(side_t *side, INT16 base_lightlevel)
|
||||
{
|
||||
return max(0, min(255, side->light_mid +
|
||||
((side->lightabsolute_mid) ? 0 : HWR_SideLightLevel(side, base_lightlevel))));
|
||||
}
|
||||
|
||||
static UINT8 HWR_BottomLightLevel(side_t *side, INT16 base_lightlevel)
|
||||
{
|
||||
return max(0, min(255, side->light_bottom +
|
||||
((side->lightabsolute_bottom) ? 0 : HWR_SideLightLevel(side, base_lightlevel))));
|
||||
}
|
||||
*/
|
||||
|
||||
static UINT8 HWR_FloorLightLevel(sector_t *sector, INT16 base_lightlevel)
|
||||
{
|
||||
return max(0, min(255, sector->floorlightlevel +
|
||||
((sector->floorlightabsolute) ? 0 : base_lightlevel)));
|
||||
}
|
||||
|
||||
static UINT8 HWR_CeilingLightLevel(sector_t *sector, INT16 base_lightlevel)
|
||||
{
|
||||
return max(0, min(255, sector->ceilinglightlevel +
|
||||
((sector->ceilinglightabsolute) ? 0 : base_lightlevel)));
|
||||
}
|
||||
// ==========================================================================
|
||||
// FLOOR/CEILING GENERATION FROM SUBSECTORS
|
||||
// ==========================================================================
|
||||
|
@ -705,8 +742,9 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
|
|||
fixed_t v2x = FloatToFixed(wallVerts[1].x);
|
||||
fixed_t v2y = FloatToFixed(wallVerts[1].z);
|
||||
|
||||
FUINT lightnum = HWR_SideLightLevel(gl_sidedef, sector->lightlevel);
|
||||
const UINT8 alpha = Surf->PolyColor.s.alpha;
|
||||
FUINT lightnum = HWR_CalcWallLight(sector->lightlevel, v1x, v1y, v2x, v2y);
|
||||
lightnum = HWR_CalcWallLight(lightnum, v1x, v1y, v2x, v2y);
|
||||
extracolormap_t *colormap = NULL;
|
||||
|
||||
if (!r_renderwalls)
|
||||
|
@ -750,13 +788,13 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
|
|||
{
|
||||
if (pfloor && (pfloor->fofflags & FOF_FOG))
|
||||
{
|
||||
lightnum = pfloor->master->frontsector->lightlevel;
|
||||
lightnum = HWR_SideLightLevel(gl_sidedef, pfloor->master->frontsector->lightlevel);
|
||||
colormap = pfloor->master->frontsector->extra_colormap;
|
||||
lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, v1x, v1y, v2x, v2y);
|
||||
}
|
||||
else
|
||||
{
|
||||
lightnum = *list[i].lightlevel;
|
||||
lightnum = HWR_SideLightLevel(gl_sidedef, *list[i].lightlevel);
|
||||
colormap = *list[i].extra_colormap;
|
||||
lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, v1x, v1y, v2x, v2y);
|
||||
}
|
||||
|
@ -951,7 +989,7 @@ static void HWR_RenderMidtexture(INT32 gl_midtexture, float cliplow, float cliph
|
|||
else
|
||||
repeats = 1;
|
||||
|
||||
GLMapTexture_t *grTex = HWR_GetTexture(gl_midtexture);
|
||||
GLMapTexture_t *grTex = HWR_GetTexture(gl_midtexture, true);
|
||||
float xscale = FixedToFloat(gl_sidedef->scalex_mid);
|
||||
float yscale = FixedToFloat(gl_sidedef->scaley_mid);
|
||||
|
||||
|
@ -1167,7 +1205,7 @@ static void HWR_ProcessSeg(void)
|
|||
float cliplow = (float)gl_curline->offset;
|
||||
float cliphigh = cliplow + (gl_curline->flength * FRACUNIT);
|
||||
|
||||
FUINT lightnum = gl_frontsector->lightlevel;
|
||||
FUINT lightnum = HWR_SideLightLevel(gl_sidedef, gl_frontsector->lightlevel);
|
||||
extracolormap_t *colormap = gl_frontsector->extra_colormap;
|
||||
lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, vs.x, vs.y, ve.x, ve.y);
|
||||
|
||||
|
@ -1210,7 +1248,7 @@ static void HWR_ProcessSeg(void)
|
|||
// check TOP TEXTURE
|
||||
if ((worldhighslope < worldtopslope || worldhigh < worldtop) && gl_toptexture)
|
||||
{
|
||||
grTex = HWR_GetTexture(gl_toptexture);
|
||||
grTex = HWR_GetTexture(gl_toptexture, false);
|
||||
xscale = FixedToFloat(abs(gl_sidedef->scalex_top));
|
||||
yscale = FixedToFloat(abs(gl_sidedef->scaley_top));
|
||||
|
||||
|
@ -1300,7 +1338,7 @@ static void HWR_ProcessSeg(void)
|
|||
// check BOTTOM TEXTURE
|
||||
if ((worldlowslope > worldbottomslope || worldlow > worldbottom) && gl_bottomtexture)
|
||||
{
|
||||
grTex = HWR_GetTexture(gl_bottomtexture);
|
||||
grTex = HWR_GetTexture(gl_bottomtexture, false);
|
||||
xscale = FixedToFloat(abs(gl_sidedef->scalex_bottom));
|
||||
yscale = FixedToFloat(abs(gl_sidedef->scaley_bottom));
|
||||
|
||||
|
@ -1414,7 +1452,7 @@ static void HWR_ProcessSeg(void)
|
|||
// Single sided line... Deal only with the middletexture (if one exists)
|
||||
if (gl_midtexture && gl_linedef->special != SPECIAL_HORIZON_LINE) // (Ignore horizon line for OGL)
|
||||
{
|
||||
grTex = HWR_GetTexture(gl_midtexture);
|
||||
grTex = HWR_GetTexture(gl_midtexture, false);
|
||||
xscale = FixedToFloat(gl_sidedef->scalex_mid);
|
||||
yscale = FixedToFloat(gl_sidedef->scaley_mid);
|
||||
|
||||
|
@ -1588,7 +1626,7 @@ static void HWR_ProcessSeg(void)
|
|||
// -- Monster Iestyn 26/06/18
|
||||
fixed_t texturevpeg = side->rowoffset + side->offsety_mid;
|
||||
|
||||
grTex = HWR_GetTexture(texnum);
|
||||
grTex = HWR_GetTexture(texnum, true);
|
||||
xscale = FixedToFloat(side->scalex_mid);
|
||||
yscale = FixedToFloat(side->scaley_mid);
|
||||
|
||||
|
@ -1628,11 +1666,11 @@ static void HWR_ProcessSeg(void)
|
|||
{
|
||||
blendmode = PF_Fog|PF_NoTexture;
|
||||
|
||||
lightnum = rover->master->frontsector->lightlevel;
|
||||
lightnum = HWR_SideLightLevel(gl_sidedef, rover->master->frontsector->lightlevel);
|
||||
colormap = rover->master->frontsector->extra_colormap;
|
||||
lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, vs.x, vs.y, ve.x, ve.y);
|
||||
|
||||
Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap);
|
||||
Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(HWR_SideLightLevel(gl_sidedef, rover->master->frontsector->lightlevel), rover->master->frontsector->extra_colormap);
|
||||
|
||||
if (gl_frontsector->numlights)
|
||||
HWR_SplitWall(gl_frontsector, wallVerts, 0, &Surf, rover->fofflags, rover, blendmode);
|
||||
|
@ -1745,7 +1783,7 @@ static void HWR_ProcessSeg(void)
|
|||
// -- Monster Iestyn 26/06/18
|
||||
fixed_t texturevpeg = side->rowoffset + side->offsety_mid;
|
||||
|
||||
grTex = HWR_GetTexture(texnum);
|
||||
grTex = HWR_GetTexture(texnum, true);
|
||||
xscale = FixedToFloat(side->scalex_mid);
|
||||
yscale = FixedToFloat(side->scaley_mid);
|
||||
|
||||
|
@ -1785,7 +1823,7 @@ static void HWR_ProcessSeg(void)
|
|||
{
|
||||
blendmode = PF_Fog|PF_NoTexture;
|
||||
|
||||
lightnum = rover->master->frontsector->lightlevel;
|
||||
lightnum = HWR_SideLightLevel(gl_sidedef, rover->master->frontsector->lightlevel);
|
||||
colormap = rover->master->frontsector->extra_colormap;
|
||||
lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, vs.x, vs.y, ve.x, ve.y);
|
||||
|
||||
|
@ -2442,7 +2480,7 @@ static void HWR_Subsector(size_t num)
|
|||
rover; rover = rover->next)
|
||||
{
|
||||
fixed_t bottomCullHeight, topCullHeight, centerHeight;
|
||||
|
||||
|
||||
if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_RENDERPLANES))
|
||||
continue;
|
||||
if (sub->validcount == validcount)
|
||||
|
@ -2471,13 +2509,13 @@ static void HWR_Subsector(size_t num)
|
|||
UINT8 alpha;
|
||||
|
||||
light = R_GetPlaneLight(gl_frontsector, centerHeight, viewz < bottomCullHeight ? true : false);
|
||||
alpha = HWR_FogBlockAlpha(*gl_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap);
|
||||
alpha = HWR_FogBlockAlpha(HWR_FloorLightLevel(rover->master->frontsector, *gl_frontsector->lightlist[light].lightlevel), rover->master->frontsector->extra_colormap);
|
||||
|
||||
HWR_AddTransparentFloor(0,
|
||||
&extrasubsectors[num],
|
||||
false,
|
||||
*rover->bottomheight,
|
||||
*gl_frontsector->lightlist[light].lightlevel,
|
||||
HWR_FloorLightLevel(rover->master->frontsector, *gl_frontsector->lightlist[light].lightlevel),
|
||||
alpha, rover->master->frontsector, PF_Fog|PF_NoTexture,
|
||||
true, false, rover->master->frontsector->extra_colormap);
|
||||
}
|
||||
|
@ -2489,7 +2527,7 @@ static void HWR_Subsector(size_t num)
|
|||
&extrasubsectors[num],
|
||||
false,
|
||||
*rover->bottomheight,
|
||||
*gl_frontsector->lightlist[light].lightlevel,
|
||||
HWR_FloorLightLevel(rover->master->frontsector, *gl_frontsector->lightlist[light].lightlevel),
|
||||
max(0, min(rover->alpha, 255)), rover->master->frontsector,
|
||||
HWR_RippleBlend(gl_frontsector, rover, false) | (rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent),
|
||||
false, rover->fofflags & FOF_SPLAT, *gl_frontsector->lightlist[light].extra_colormap);
|
||||
|
@ -2498,8 +2536,9 @@ static void HWR_Subsector(size_t num)
|
|||
{
|
||||
HWR_GetLevelFlat(&levelflats[*rover->bottompic], rover->fofflags & FOF_SPLAT);
|
||||
light = R_GetPlaneLight(gl_frontsector, centerHeight, viewz < bottomCullHeight ? true : false);
|
||||
HWR_RenderPlane(sub, &extrasubsectors[num], false, *rover->bottomheight, HWR_RippleBlend(gl_frontsector, rover, false)|PF_Occlude, *gl_frontsector->lightlist[light].lightlevel, &levelflats[*rover->bottompic],
|
||||
rover->master->frontsector, 255, *gl_frontsector->lightlist[light].extra_colormap);
|
||||
HWR_RenderPlane(sub, &extrasubsectors[num], false, *rover->bottomheight, HWR_RippleBlend(gl_frontsector, rover, false)|PF_Occlude,
|
||||
HWR_FloorLightLevel(rover->master->frontsector, *gl_frontsector->lightlist[light].lightlevel),
|
||||
&levelflats[*rover->bottompic], rover->master->frontsector, 255, *gl_frontsector->lightlist[light].extra_colormap);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2516,13 +2555,13 @@ static void HWR_Subsector(size_t num)
|
|||
UINT8 alpha;
|
||||
|
||||
light = R_GetPlaneLight(gl_frontsector, centerHeight, viewz < topCullHeight ? true : false);
|
||||
alpha = HWR_FogBlockAlpha(*gl_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap);
|
||||
alpha = HWR_FogBlockAlpha(HWR_CeilingLightLevel(rover->master->frontsector, *gl_frontsector->lightlist[light].lightlevel), rover->master->frontsector->extra_colormap);
|
||||
|
||||
HWR_AddTransparentFloor(0,
|
||||
&extrasubsectors[num],
|
||||
true,
|
||||
*rover->topheight,
|
||||
*gl_frontsector->lightlist[light].lightlevel,
|
||||
HWR_CeilingLightLevel(rover->master->frontsector, *gl_frontsector->lightlist[light].lightlevel),
|
||||
alpha, rover->master->frontsector, PF_Fog|PF_NoTexture,
|
||||
true, false, rover->master->frontsector->extra_colormap);
|
||||
}
|
||||
|
@ -2534,7 +2573,7 @@ static void HWR_Subsector(size_t num)
|
|||
&extrasubsectors[num],
|
||||
true,
|
||||
*rover->topheight,
|
||||
*gl_frontsector->lightlist[light].lightlevel,
|
||||
HWR_CeilingLightLevel(rover->master->frontsector, *gl_frontsector->lightlist[light].lightlevel),
|
||||
max(0, min(rover->alpha, 255)), rover->master->frontsector,
|
||||
HWR_RippleBlend(gl_frontsector, rover, false) | (rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent),
|
||||
false, rover->fofflags & FOF_SPLAT, *gl_frontsector->lightlist[light].extra_colormap);
|
||||
|
@ -2543,8 +2582,9 @@ static void HWR_Subsector(size_t num)
|
|||
{
|
||||
HWR_GetLevelFlat(&levelflats[*rover->toppic], rover->fofflags & FOF_SPLAT);
|
||||
light = R_GetPlaneLight(gl_frontsector, centerHeight, viewz < topCullHeight ? true : false);
|
||||
HWR_RenderPlane(sub, &extrasubsectors[num], true, *rover->topheight, HWR_RippleBlend(gl_frontsector, rover, false)|PF_Occlude, *gl_frontsector->lightlist[light].lightlevel, &levelflats[*rover->toppic],
|
||||
rover->master->frontsector, 255, *gl_frontsector->lightlist[light].extra_colormap);
|
||||
HWR_RenderPlane(sub, &extrasubsectors[num], true, *rover->topheight, HWR_RippleBlend(gl_frontsector, rover, false)|PF_Occlude,
|
||||
HWR_CeilingLightLevel(rover->master->frontsector, *gl_frontsector->lightlist[light].lightlevel),
|
||||
&levelflats[*rover->toppic], rover->master->frontsector, 255, *gl_frontsector->lightlist[light].extra_colormap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2880,7 +2920,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
|
|||
}
|
||||
|
||||
HWR_Lighting(&sSurf, 0, colormap);
|
||||
sSurf.PolyColor.s.alpha = alpha;
|
||||
sSurf.PolyColor.s.alpha = FixedMul(thing->alpha, alpha);
|
||||
|
||||
if (HWR_UseShader())
|
||||
{
|
||||
|
@ -3054,11 +3094,16 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
|
|||
// baseWallVerts is used to know the final shape to easily get the vertex
|
||||
// co-ordinates
|
||||
memcpy(wallVerts, baseWallVerts, sizeof(baseWallVerts));
|
||||
|
||||
fixed_t newalpha = spr->mobj->alpha;
|
||||
|
||||
// if sprite has linkdraw, then dont write to z-buffer (by not using PF_Occlude)
|
||||
// this will result in sprites drawn afterwards to be drawn on top like intended when using linkdraw.
|
||||
if ((spr->mobj->flags2 & MF2_LINKDRAW) && spr->mobj->tracer)
|
||||
{
|
||||
newalpha = spr->mobj->tracer->alpha;
|
||||
occlusion = 0;
|
||||
}
|
||||
else
|
||||
occlusion = PF_Occlude;
|
||||
|
||||
|
@ -3094,6 +3139,8 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
|
|||
blend = HWR_GetBlendModeFlag(blendmode)|occlusion;
|
||||
if (!occlusion) use_linkdraw_hack = true;
|
||||
}
|
||||
|
||||
Surf.PolyColor.s.alpha = FixedMul(newalpha, Surf.PolyColor.s.alpha);
|
||||
|
||||
if (HWR_UseShader())
|
||||
{
|
||||
|
@ -3543,11 +3590,15 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
|
|||
FBITFIELD blend = 0;
|
||||
FBITFIELD occlusion;
|
||||
boolean use_linkdraw_hack = false;
|
||||
fixed_t newalpha = spr->mobj->alpha;
|
||||
|
||||
// if sprite has linkdraw, then dont write to z-buffer (by not using PF_Occlude)
|
||||
// this will result in sprites drawn afterwards to be drawn on top like intended when using linkdraw.
|
||||
if ((spr->mobj->flags2 & MF2_LINKDRAW) && spr->mobj->tracer)
|
||||
{
|
||||
occlusion = 0;
|
||||
newalpha = spr->mobj->tracer->alpha;
|
||||
}
|
||||
else
|
||||
occlusion = PF_Occlude;
|
||||
|
||||
|
@ -3583,6 +3634,8 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
|
|||
blend = HWR_GetBlendModeFlag(blendmode)|occlusion;
|
||||
if (!occlusion) use_linkdraw_hack = true;
|
||||
}
|
||||
|
||||
Surf.PolyColor.s.alpha = FixedMul(newalpha, Surf.PolyColor.s.alpha);
|
||||
|
||||
if (spr->renderflags & RF_SHADOWEFFECTS)
|
||||
{
|
||||
|
@ -3893,7 +3946,7 @@ void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boo
|
|||
|
||||
planeinfo[numplanes].isceiling = isceiling;
|
||||
planeinfo[numplanes].fixedheight = fixedheight;
|
||||
planeinfo[numplanes].lightlevel = (planecolormap && (planecolormap->flags & CMF_FOG)) ? 255 : lightlevel;
|
||||
planeinfo[numplanes].lightlevel = (planecolormap && (planecolormap->flags & CMF_FOG)) ? lightlevel : 255; // TODO: 2.3: Make transparent FOF planes always use light level
|
||||
planeinfo[numplanes].levelflat = levelflat;
|
||||
planeinfo[numplanes].xsub = xsub;
|
||||
planeinfo[numplanes].alpha = alpha;
|
||||
|
@ -3925,7 +3978,7 @@ void HWR_AddTransparentPolyobjectFloor(levelflat_t *levelflat, polyobj_t *polyse
|
|||
|
||||
polyplaneinfo[numpolyplanes].isceiling = isceiling;
|
||||
polyplaneinfo[numpolyplanes].fixedheight = fixedheight;
|
||||
polyplaneinfo[numpolyplanes].lightlevel = (planecolormap && (planecolormap->flags & CMF_FOG)) ? 255 : lightlevel;
|
||||
polyplaneinfo[numpolyplanes].lightlevel = (planecolormap && (planecolormap->flags & CMF_FOG)) ? lightlevel : 255; // TODO: 2.3: Make transparent polyobject planes always use light level
|
||||
polyplaneinfo[numpolyplanes].levelflat = levelflat;
|
||||
polyplaneinfo[numpolyplanes].polysector = polysector;
|
||||
polyplaneinfo[numpolyplanes].alpha = alpha;
|
||||
|
@ -4086,7 +4139,7 @@ static void HWR_CreateDrawNodes(void)
|
|||
else if (sortnode[sortindex[i]].wall)
|
||||
{
|
||||
if (!(sortnode[sortindex[i]].wall->blend & PF_NoTexture))
|
||||
HWR_GetTexture(sortnode[sortindex[i]].wall->texnum);
|
||||
HWR_GetTexture(sortnode[sortindex[i]].wall->texnum, true);
|
||||
HWR_RenderWall(sortnode[sortindex[i]].wall->wallVerts, &sortnode[sortindex[i]].wall->Surf, sortnode[sortindex[i]].wall->blend, sortnode[sortindex[i]].wall->fogwall,
|
||||
sortnode[sortindex[i]].wall->lightlevel, sortnode[sortindex[i]].wall->wallcolormap);
|
||||
}
|
||||
|
@ -5066,6 +5119,8 @@ static void HWR_DrawSkyBackground(player_t *player)
|
|||
|
||||
HWD.pfnSetBlend(PF_Translucent|PF_NoDepthTest|PF_Modulated);
|
||||
|
||||
HWR_GetTexture(texturetranslation[skytexture], false);
|
||||
|
||||
if (cv_glskydome.value)
|
||||
{
|
||||
FTransform dometransform;
|
||||
|
@ -5081,8 +5136,6 @@ static void HWR_DrawSkyBackground(player_t *player)
|
|||
HWR_SetTransformAiming(&dometransform, player, false);
|
||||
dometransform.angley = (float)((viewangle-ANGLE_270)>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES);
|
||||
|
||||
HWR_GetTexture(texturetranslation[skytexture]);
|
||||
|
||||
if (gl_sky.texture != texturetranslation[skytexture])
|
||||
{
|
||||
HWR_ClearSkyDome();
|
||||
|
@ -5102,7 +5155,6 @@ static void HWR_DrawSkyBackground(player_t *player)
|
|||
float aspectratio;
|
||||
float angleturn;
|
||||
|
||||
HWR_GetTexture(texturetranslation[skytexture]);
|
||||
aspectratio = (float)vid.width/(float)vid.height;
|
||||
|
||||
//Hurdler: the sky is the only texture who need 4.0f instead of 1.0
|
||||
|
|
|
@ -1154,6 +1154,9 @@ static void adjustTextureCoords(model_t *model, patch_t *patch)
|
|||
int i;
|
||||
GLPatch_t *gpatch = ((GLPatch_t *)patch->hardware);
|
||||
|
||||
if (!gpatch)
|
||||
return;
|
||||
|
||||
for (i = 0; i < model->numMeshes; i++)
|
||||
{
|
||||
int j;
|
||||
|
@ -1286,6 +1289,11 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
// Apparently people don't like jump frames like that, so back it goes
|
||||
//if (tics > durs)
|
||||
//durs = tics;
|
||||
|
||||
// Make linkdraw objects use their tracer's alpha value
|
||||
fixed_t newalpha = spr->mobj->alpha;
|
||||
if ((spr->mobj->flags2 & MF2_LINKDRAW) && spr->mobj->tracer)
|
||||
newalpha = spr->mobj->tracer->alpha;
|
||||
|
||||
INT32 blendmode;
|
||||
if (spr->mobj->frame & FF_BLENDMASK)
|
||||
|
@ -1300,6 +1308,8 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
Surf.PolyColor.s.alpha = (spr->mobj->flags2 & MF2_SHADOW) ? 0x40 : 0xff;
|
||||
Surf.PolyFlags = HWR_GetBlendModeFlag(blendmode);
|
||||
}
|
||||
|
||||
Surf.PolyColor.s.alpha = FixedMul(newalpha, Surf.PolyColor.s.alpha);
|
||||
|
||||
// don't forget to enable the depth test because we can't do this
|
||||
// like before: model polygons are not sorted
|
||||
|
|
|
@ -448,6 +448,101 @@ void HWR_LoadAllCustomShaders(void)
|
|||
HWR_LoadCustomShadersFromFile(i, W_FileHasFolders(wadfiles[i]));
|
||||
}
|
||||
|
||||
static const char version_directives[][14] = {
|
||||
"#version 330\n",
|
||||
"#version 150\n",
|
||||
"#version 140\n",
|
||||
"#version 130\n",
|
||||
"#version 120\n",
|
||||
"#version 110\n",
|
||||
};
|
||||
|
||||
static boolean HWR_VersionDirectiveExists(const char* source)
|
||||
{
|
||||
return strncmp(source, "#version", 8) == 0;
|
||||
}
|
||||
|
||||
static char* HWR_PrependVersionDirective(const char* source, UINT32 version_index)
|
||||
{
|
||||
const UINT32 version_len = sizeof(version_directives[version_index]) - 1;
|
||||
const UINT32 source_len = strlen(source);
|
||||
|
||||
char* result = Z_Malloc(source_len + version_len + 1, PU_STATIC, NULL);
|
||||
strcpy(result, version_directives[version_index]);
|
||||
strcpy(result + version_len, source);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void HWR_ReplaceVersionInplace(char* shader, UINT32 version_index)
|
||||
{
|
||||
shader[9] = version_directives[version_index][9];
|
||||
shader[10] = version_directives[version_index][10];
|
||||
shader[11] = version_directives[version_index][11];
|
||||
}
|
||||
|
||||
static boolean HWR_CheckVersionDirectives(const char* vert, const char* frag)
|
||||
{
|
||||
return HWR_VersionDirectiveExists(vert) && HWR_VersionDirectiveExists(frag);
|
||||
}
|
||||
|
||||
static void HWR_TryToCompileShaderWithImplicitVersion(INT32 shader_index, INT32 shaderxlat_id)
|
||||
{
|
||||
char* vert_shader = gl_shaders[shader_index].vertex;
|
||||
char* frag_shader = gl_shaders[shader_index].fragment;
|
||||
|
||||
boolean vert_shader_version_exists = HWR_VersionDirectiveExists(vert_shader);
|
||||
boolean frag_shader_version_exists = HWR_VersionDirectiveExists(frag_shader);
|
||||
|
||||
if(!vert_shader_version_exists) {
|
||||
CONS_Alert(CONS_WARNING, "HWR_LoadCustomShadersFromFile: vertex shader '%s' is missing a #version directive\n", HWR_GetShaderName(shaderxlat_id));
|
||||
}
|
||||
|
||||
if(!frag_shader_version_exists) {
|
||||
CONS_Alert(CONS_WARNING, "HWR_LoadCustomShadersFromFile: fragment shader '%s' is missing a #version directive\n", HWR_GetShaderName(shaderxlat_id));
|
||||
}
|
||||
|
||||
// try to compile as is
|
||||
HWR_CompileShader(shader_index);
|
||||
if (gl_shaders[shader_index].compiled)
|
||||
return;
|
||||
|
||||
// try each version directive
|
||||
for(UINT32 i = 0; i < sizeof(version_directives) / sizeof(version_directives[0]); ++i) {
|
||||
CONS_Alert(CONS_NOTICE, "HWR_TryToCompileShaderWithImplicitVersion: Trying %s\n", version_directives[i]);
|
||||
|
||||
if(!vert_shader_version_exists) {
|
||||
// first time reallocation would have to be made
|
||||
|
||||
if(i == 0) {
|
||||
void* old = (void*)gl_shaders[shader_index].vertex;
|
||||
vert_shader = gl_shaders[shader_index].vertex = HWR_PrependVersionDirective(vert_shader, i);
|
||||
Z_Free(old);
|
||||
} else {
|
||||
HWR_ReplaceVersionInplace(vert_shader, i);
|
||||
}
|
||||
}
|
||||
|
||||
if(!frag_shader_version_exists) {
|
||||
if(i == 0) {
|
||||
void* old = (void*)gl_shaders[shader_index].fragment;
|
||||
frag_shader = gl_shaders[shader_index].fragment = HWR_PrependVersionDirective(frag_shader, i);
|
||||
Z_Free(old);
|
||||
} else {
|
||||
HWR_ReplaceVersionInplace(frag_shader, i);
|
||||
}
|
||||
}
|
||||
|
||||
HWR_CompileShader(shader_index);
|
||||
if (gl_shaders[shader_index].compiled) {
|
||||
CONS_Alert(CONS_NOTICE, "HWR_TryToCompileShaderWithImplicitVersion: Compiled with %s\n",
|
||||
version_directives[i]);
|
||||
CONS_Alert(CONS_WARNING, "Implicit GLSL version is used. Correct behavior is not guaranteed\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HWR_LoadCustomShadersFromFile(UINT16 wadnum, boolean PK3)
|
||||
{
|
||||
UINT16 lump;
|
||||
|
@ -610,7 +705,13 @@ skip_field:
|
|||
gl_shaders[shader_index].fragment = Z_StrDup(gl_shadersources[i].fragment);
|
||||
if (!gl_shaders[shader_index].vertex)
|
||||
gl_shaders[shader_index].vertex = Z_StrDup(gl_shadersources[i].vertex);
|
||||
HWR_CompileShader(shader_index);
|
||||
|
||||
if(!HWR_CheckVersionDirectives(gl_shaders[shader_index].vertex, gl_shaders[shader_index].fragment)) {
|
||||
HWR_TryToCompileShaderWithImplicitVersion(shader_index, i);
|
||||
} else {
|
||||
HWR_CompileShader(shader_index);
|
||||
}
|
||||
|
||||
if (!gl_shaders[shader_index].compiled)
|
||||
CONS_Alert(CONS_ERROR, "HWR_LoadCustomShadersFromFile: A compilation error occured for the %s shader in file %s. See the console messages above for more information.\n", shaderxlat[i].type, wadfiles[wadnum]->filename);
|
||||
}
|
||||
|
|
112
src/hu_stuff.c
112
src/hu_stuff.c
|
@ -29,7 +29,7 @@
|
|||
#include "i_video.h"
|
||||
#include "i_system.h"
|
||||
|
||||
#include "st_stuff.h" // ST_HEIGHT
|
||||
#include "st_stuff.h"
|
||||
#include "r_local.h"
|
||||
|
||||
#include "keys.h"
|
||||
|
@ -204,7 +204,7 @@ void HU_LoadGraphics(void)
|
|||
HU_SetFontProperties(&hu_font, 0, 4, 8, 12);
|
||||
HU_SetFontProperties(&tny_font, 0, 2, 4, 12);
|
||||
HU_SetFontProperties(&cred_font, 0, 16, 16, 16);
|
||||
HU_SetFontProperties(<_font, 0, 16, 20, 20);
|
||||
HU_SetFontProperties(<_font, 0, 16, 20, 16);
|
||||
HU_SetFontProperties(&ntb_font, 2, 4, 20, 21);
|
||||
HU_SetFontProperties(&nto_font, 0, 4, 20, 21);
|
||||
|
||||
|
@ -1218,27 +1218,36 @@ static void HU_drawMiniChat(void)
|
|||
INT32 charwidth = 4, charheight = 6;
|
||||
INT32 boxw = cv_chatwidth.value;
|
||||
INT32 dx = 0, dy = 0;
|
||||
boolean prev_linereturn = false;
|
||||
|
||||
if (!chat_nummsg_min)
|
||||
return; // needless to say it's useless to do anything if we don't have anything to draw.
|
||||
|
||||
for (size_t i = chat_nummsg_min; i > 0; i--)
|
||||
{
|
||||
char *msg = V_ChatWordWrap(chatx, boxw-charwidth, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]);
|
||||
char *msg = V_ChatWordWrap(0, boxw-charwidth-2, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE|V_MONOSPACE, chat_mini[i-1]);
|
||||
for(size_t j = 0; msg[j]; j++) // iterate through msg
|
||||
{
|
||||
if (msg[j] == '\n') // get back down.
|
||||
{
|
||||
chatheight += charheight;
|
||||
dx = 0;
|
||||
if (!prev_linereturn)
|
||||
{
|
||||
chatheight += charheight;
|
||||
dx = 0;
|
||||
}
|
||||
prev_linereturn = true;
|
||||
}
|
||||
else if (msg[j] >= FONTSTART)
|
||||
{
|
||||
prev_linereturn = false;
|
||||
|
||||
dx += charwidth;
|
||||
if (dx >= boxw)
|
||||
|
||||
if (dx >= boxw-charwidth-2)
|
||||
{
|
||||
dx = 0;
|
||||
chatheight += charheight;
|
||||
prev_linereturn = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1250,35 +1259,43 @@ static void HU_drawMiniChat(void)
|
|||
}
|
||||
|
||||
y = chaty - (chatheight + charheight);
|
||||
prev_linereturn = false;
|
||||
|
||||
for (size_t i = 0; i < chat_nummsg_min; i++) // iterate through our hot messages
|
||||
{
|
||||
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.
|
||||
char *msg = V_ChatWordWrap(chatx, boxw-charwidth, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it.
|
||||
char *msg = V_ChatWordWrap(0, boxw-charwidth-2, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE|V_MONOSPACE, chat_mini[i]); // get the current message, and word wrap it.
|
||||
UINT8 *colormap = NULL;
|
||||
|
||||
for(size_t j = 0; msg[j]; j++) // iterate through msg
|
||||
{
|
||||
if (msg[j] == '\n') // get back down.
|
||||
{
|
||||
dy += charheight;
|
||||
dx = 0;
|
||||
if (!prev_linereturn)
|
||||
{
|
||||
dy += charheight;
|
||||
dx = 0;
|
||||
}
|
||||
prev_linereturn = true;
|
||||
}
|
||||
else if (msg[j] & 0x80) // get colormap
|
||||
colormap = V_GetStringColormap(((msg[j] & 0x7f) << V_CHARCOLORSHIFT) & V_CHARCOLORMASK);
|
||||
else if (msg[j] >= FONTSTART)
|
||||
{
|
||||
prev_linereturn = false;
|
||||
|
||||
if (cv_chatbacktint.value) // on request of wolfy
|
||||
V_DrawFillConsoleMap(x + dx + 2, y+dy, charwidth, charheight, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT);
|
||||
|
||||
V_DrawChatCharacter(x + dx + 2, y+dy, msg[j] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag, true, colormap);
|
||||
|
||||
V_DrawChatCharacter(x + dx + 2, y+dy, msg[j] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_MONOSPACE|transflag, true, colormap);
|
||||
dx += charwidth;
|
||||
if (dx >= boxw)
|
||||
|
||||
if (dx >= boxw-charwidth-2)
|
||||
{
|
||||
dx = 0;
|
||||
dy += charheight;
|
||||
prev_linereturn = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1303,6 +1320,7 @@ static void HU_drawChatLog(INT32 offset)
|
|||
UINT32 i = 0;
|
||||
INT32 chat_topy, chat_bottomy;
|
||||
boolean atbottom = false;
|
||||
boolean prev_linereturn = false;
|
||||
|
||||
// make sure that our scroll position isn't "illegal";
|
||||
if (chat_scroll > chat_maxscroll)
|
||||
|
@ -1335,27 +1353,38 @@ static void HU_drawChatLog(INT32 offset)
|
|||
|
||||
for (i=0; i<chat_nummsg_log; i++) // iterate through our chatlog
|
||||
{
|
||||
char *msg = V_ChatWordWrap(chatx, boxw-charwidth, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it.
|
||||
char *msg = V_ChatWordWrap(0, boxw-charwidth-2, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE|V_MONOSPACE, chat_log[i]); // get the current message, and word wrap it.
|
||||
UINT8 *colormap = NULL;
|
||||
for(size_t j = 0; msg[j]; j++) // iterate through msg
|
||||
{
|
||||
if (msg[j] == '\n') // get back down.
|
||||
{
|
||||
dy += charheight;
|
||||
dx = 0;
|
||||
if (!prev_linereturn)
|
||||
{
|
||||
dy += charheight;
|
||||
dx = 0;
|
||||
}
|
||||
prev_linereturn = true;
|
||||
}
|
||||
else if (msg[j] & 0x80) // get colormap
|
||||
colormap = V_GetStringColormap(((msg[j] & 0x7f) << V_CHARCOLORSHIFT) & V_CHARCOLORMASK);
|
||||
else if (msg[j] >= FONTSTART)
|
||||
else
|
||||
{
|
||||
if ((y+dy+2 >= chat_topy) && (y+dy < (chat_bottomy)))
|
||||
V_DrawChatCharacter(x + dx + 2, y+dy+2, msg[j] |V_SNAPTOBOTTOM|V_SNAPTOLEFT, true, colormap);
|
||||
prev_linereturn = false;
|
||||
|
||||
dx += charwidth;
|
||||
if (dx >= boxw-charwidth-2 && i<chat_nummsg_log) // end of message shouldn't count, nor should invisible characters!!!!
|
||||
if (msg[j] >= FONTSTART)
|
||||
{
|
||||
if ((y+dy+2 >= chat_topy) && (y+dy < (chat_bottomy)))
|
||||
V_DrawChatCharacter(x + dx + 2, y+dy+2, msg[j] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_MONOSPACE, true, colormap);
|
||||
|
||||
dx += charwidth;
|
||||
}
|
||||
|
||||
if (dx >= boxw-charwidth-2 && i < chat_nummsg_log) // end of message shouldn't count, nor should invisible characters!!!!
|
||||
{
|
||||
dx = 0;
|
||||
dy += charheight;
|
||||
prev_linereturn = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2463,53 +2492,20 @@ static inline void HU_DrawSpectatorTicker(void)
|
|||
{
|
||||
int i;
|
||||
int length = 0, height = 174;
|
||||
int totallength = 0, templength = 0;
|
||||
int totallength = 0;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] && players[i].spectator)
|
||||
totallength += (signed)strlen(player_names[i]) * 8 + 16;
|
||||
|
||||
length -= (leveltime % (totallength + BASEVIDWIDTH));
|
||||
length += BASEVIDWIDTH;
|
||||
length -= (leveltime % (totallength + (vid.width / vid.dup)));
|
||||
length += (vid.width / vid.dup);
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i] && players[i].spectator)
|
||||
{
|
||||
char *pos;
|
||||
char initial[MAXPLAYERNAME+1];
|
||||
char current[MAXPLAYERNAME+1];
|
||||
|
||||
strcpy(initial, player_names[i]);
|
||||
pos = initial;
|
||||
|
||||
if (length >= -((signed)strlen(player_names[i]) * 8 + 16) && length <= BASEVIDWIDTH)
|
||||
{
|
||||
if (length < 0)
|
||||
{
|
||||
UINT8 eatenchars = (UINT8)(abs(length) / 8 + 1);
|
||||
|
||||
if (eatenchars <= strlen(initial))
|
||||
{
|
||||
// Eat one letter off the left side,
|
||||
// then compensate the drawing position.
|
||||
pos += eatenchars;
|
||||
strcpy(current, pos);
|
||||
templength = length % 8 + 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(current, " ");
|
||||
templength = length;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(current, initial);
|
||||
templength = length;
|
||||
}
|
||||
|
||||
V_DrawString(templength, height + 8, V_TRANSLUCENT|V_ALLOWLOWERCASE, current);
|
||||
}
|
||||
if (length >= -((signed)strlen(player_names[i]) * 8 + 16) && length <= (vid.width / vid.dup))
|
||||
V_DrawString(length, height + 8, V_TRANSLUCENT|V_ALLOWLOWERCASE|V_SNAPTOLEFT, player_names[i]);
|
||||
|
||||
length += (signed)strlen(player_names[i]) * 8 + 16;
|
||||
}
|
||||
|
|
538
src/info.h
538
src/info.h
|
@ -298,276 +298,278 @@ enum actionnum
|
|||
NUMACTIONS
|
||||
};
|
||||
|
||||
struct mobj_s;
|
||||
|
||||
// IMPORTANT NOTE: If you add/remove from this list of action
|
||||
// functions, don't forget to update them in deh_tables.c!
|
||||
void A_Explode();
|
||||
void A_Pain();
|
||||
void A_Fall();
|
||||
void A_MonitorPop();
|
||||
void A_GoldMonitorPop();
|
||||
void A_GoldMonitorRestore();
|
||||
void A_GoldMonitorSparkle();
|
||||
void A_Look();
|
||||
void A_Chase();
|
||||
void A_FaceStabChase();
|
||||
void A_FaceStabRev();
|
||||
void A_FaceStabHurl();
|
||||
void A_FaceStabMiss();
|
||||
void A_StatueBurst();
|
||||
void A_FaceTarget();
|
||||
void A_FaceTracer();
|
||||
void A_Scream();
|
||||
void A_BossDeath();
|
||||
void A_SetShadowScale();
|
||||
void A_ShadowScream(); // MARIA!!!!!!
|
||||
void A_CustomPower(); // Use this for a custom power
|
||||
void A_GiveWeapon(); // Gives the player weapon(s)
|
||||
void A_RingBox(); // Obtained Ring Box Tails
|
||||
void A_Invincibility(); // Obtained Invincibility Box
|
||||
void A_SuperSneakers(); // Obtained Super Sneakers Box
|
||||
void A_BunnyHop(); // have bunny hop tails
|
||||
void A_BubbleSpawn(); // Randomly spawn bubbles
|
||||
void A_FanBubbleSpawn();
|
||||
void A_BubbleRise(); // Bubbles float to surface
|
||||
void A_BubbleCheck(); // Don't draw if not underwater
|
||||
void A_AwardScore();
|
||||
void A_ExtraLife(); // Extra Life
|
||||
void A_GiveShield(); // Obtained Shield
|
||||
void A_GravityBox();
|
||||
void A_ScoreRise(); // Rise the score logo
|
||||
void A_AttractChase(); // Ring Chase
|
||||
void A_DropMine(); // Drop Mine from Skim or Jetty-Syn Bomber
|
||||
void A_FishJump(); // Fish Jump
|
||||
void A_ThrownRing(); // Sparkle trail for red ring
|
||||
void A_SetSolidSteam();
|
||||
void A_UnsetSolidSteam();
|
||||
void A_SignSpin();
|
||||
void A_SignPlayer();
|
||||
void A_OverlayThink();
|
||||
void A_JetChase();
|
||||
void A_JetbThink(); // Jetty-Syn Bomber Thinker
|
||||
void A_JetgThink(); // Jetty-Syn Gunner Thinker
|
||||
void A_JetgShoot(); // Jetty-Syn Shoot Function
|
||||
void A_ShootBullet(); // JetgShoot without reactiontime setting
|
||||
void A_MinusDigging();
|
||||
void A_MinusPopup();
|
||||
void A_MinusCheck();
|
||||
void A_ChickenCheck();
|
||||
void A_MouseThink(); // Mouse Thinker
|
||||
void A_DetonChase(); // Deton Chaser
|
||||
void A_CapeChase(); // Fake little Super Sonic cape
|
||||
void A_RotateSpikeBall(); // Spike ball rotation
|
||||
void A_SlingAppear();
|
||||
void A_UnidusBall();
|
||||
void A_RockSpawn();
|
||||
void A_SetFuse();
|
||||
void A_CrawlaCommanderThink(); // Crawla Commander
|
||||
void A_SmokeTrailer();
|
||||
void A_RingExplode();
|
||||
void A_OldRingExplode();
|
||||
void A_MixUp();
|
||||
void A_RecyclePowers();
|
||||
void A_BossScream();
|
||||
void A_Boss2TakeDamage();
|
||||
void A_GoopSplat();
|
||||
void A_Boss2PogoSFX();
|
||||
void A_Boss2PogoTarget();
|
||||
void A_EggmanBox();
|
||||
void A_TurretFire();
|
||||
void A_SuperTurretFire();
|
||||
void A_TurretStop();
|
||||
void A_JetJawRoam();
|
||||
void A_JetJawChomp();
|
||||
void A_PointyThink();
|
||||
void A_CheckBuddy();
|
||||
void A_HoodFire();
|
||||
void A_HoodThink();
|
||||
void A_HoodFall();
|
||||
void A_ArrowBonks();
|
||||
void A_SnailerThink();
|
||||
void A_SharpChase();
|
||||
void A_SharpSpin();
|
||||
void A_SharpDecel();
|
||||
void A_CrushstaceanWalk();
|
||||
void A_CrushstaceanPunch();
|
||||
void A_CrushclawAim();
|
||||
void A_CrushclawLaunch();
|
||||
void A_VultureVtol();
|
||||
void A_VultureCheck();
|
||||
void A_VultureHover();
|
||||
void A_VultureBlast();
|
||||
void A_VultureFly();
|
||||
void A_SkimChase();
|
||||
void A_SkullAttack();
|
||||
void A_LobShot();
|
||||
void A_FireShot();
|
||||
void A_SuperFireShot();
|
||||
void A_BossFireShot();
|
||||
void A_Boss7FireMissiles();
|
||||
void A_Boss1Laser();
|
||||
void A_FocusTarget();
|
||||
void A_Boss4Reverse();
|
||||
void A_Boss4SpeedUp();
|
||||
void A_Boss4Raise();
|
||||
void A_SparkFollow();
|
||||
void A_BuzzFly();
|
||||
void A_GuardChase();
|
||||
void A_EggShield();
|
||||
void A_SetReactionTime();
|
||||
void A_Boss1Spikeballs();
|
||||
void A_Boss3TakeDamage();
|
||||
void A_Boss3Path();
|
||||
void A_Boss3ShockThink();
|
||||
void A_Shockwave();
|
||||
void A_LinedefExecute();
|
||||
void A_LinedefExecuteFromArg();
|
||||
void A_PlaySeeSound();
|
||||
void A_PlayAttackSound();
|
||||
void A_PlayActiveSound();
|
||||
void A_1upThinker();
|
||||
void A_BossZoom(); //Unused
|
||||
void A_Boss1Chase();
|
||||
void A_Boss2Chase();
|
||||
void A_Boss2Pogo();
|
||||
void A_Boss7Chase();
|
||||
void A_BossJetFume();
|
||||
void A_SpawnObjectAbsolute();
|
||||
void A_SpawnObjectRelative();
|
||||
void A_ChangeAngleRelative();
|
||||
void A_ChangeAngleAbsolute();
|
||||
void A_RollAngle();
|
||||
void A_ChangeRollAngleRelative();
|
||||
void A_ChangeRollAngleAbsolute();
|
||||
void A_PlaySound();
|
||||
void A_FindTarget();
|
||||
void A_FindTracer();
|
||||
void A_SetTics();
|
||||
void A_SetRandomTics();
|
||||
void A_ChangeColorRelative();
|
||||
void A_ChangeColorAbsolute();
|
||||
void A_Dye();
|
||||
void A_SetTranslation();
|
||||
void A_MoveRelative();
|
||||
void A_MoveAbsolute();
|
||||
void A_Thrust();
|
||||
void A_ZThrust();
|
||||
void A_SetTargetsTarget();
|
||||
void A_SetObjectFlags();
|
||||
void A_SetObjectFlags2();
|
||||
void A_RandomState();
|
||||
void A_RandomStateRange();
|
||||
void A_StateRangeByAngle();
|
||||
void A_StateRangeByParameter();
|
||||
void A_DualAction();
|
||||
void A_RemoteAction();
|
||||
void A_ToggleFlameJet();
|
||||
void A_OrbitNights();
|
||||
void A_GhostMe();
|
||||
void A_SetObjectState();
|
||||
void A_SetObjectTypeState();
|
||||
void A_KnockBack();
|
||||
void A_PushAway();
|
||||
void A_RingDrain();
|
||||
void A_SplitShot();
|
||||
void A_MissileSplit();
|
||||
void A_MultiShot();
|
||||
void A_InstaLoop();
|
||||
void A_Custom3DRotate();
|
||||
void A_SearchForPlayers();
|
||||
void A_CheckRandom();
|
||||
void A_CheckTargetRings();
|
||||
void A_CheckRings();
|
||||
void A_CheckTotalRings();
|
||||
void A_CheckHealth();
|
||||
void A_CheckRange();
|
||||
void A_CheckHeight();
|
||||
void A_CheckTrueRange();
|
||||
void A_CheckThingCount();
|
||||
void A_CheckAmbush();
|
||||
void A_CheckCustomValue();
|
||||
void A_CheckCusValMemo();
|
||||
void A_SetCustomValue();
|
||||
void A_UseCusValMemo();
|
||||
void A_RelayCustomValue();
|
||||
void A_CusValAction();
|
||||
void A_ForceStop();
|
||||
void A_ForceWin();
|
||||
void A_SpikeRetract();
|
||||
void A_InfoState();
|
||||
void A_Repeat();
|
||||
void A_SetScale();
|
||||
void A_RemoteDamage();
|
||||
void A_HomingChase();
|
||||
void A_TrapShot();
|
||||
void A_VileTarget();
|
||||
void A_VileAttack();
|
||||
void A_VileFire();
|
||||
void A_BrakChase();
|
||||
void A_BrakFireShot();
|
||||
void A_BrakLobShot();
|
||||
void A_NapalmScatter();
|
||||
void A_SpawnFreshCopy();
|
||||
void A_FlickySpawn();
|
||||
void A_FlickyCenter();
|
||||
void A_FlickyAim();
|
||||
void A_FlickyFly();
|
||||
void A_FlickySoar();
|
||||
void A_FlickyCoast();
|
||||
void A_FlickyHop();
|
||||
void A_FlickyFlounder();
|
||||
void A_FlickyCheck();
|
||||
void A_FlickyHeightCheck();
|
||||
void A_FlickyFlutter();
|
||||
void A_FlameParticle();
|
||||
void A_FadeOverlay();
|
||||
void A_Boss5Jump();
|
||||
void A_LightBeamReset();
|
||||
void A_MineExplode();
|
||||
void A_MineRange();
|
||||
void A_ConnectToGround();
|
||||
void A_SpawnParticleRelative();
|
||||
void A_MultiShotDist();
|
||||
void A_WhoCaresIfYourSonIsABee();
|
||||
void A_ParentTriesToSleep();
|
||||
void A_CryingToMomma();
|
||||
void A_CheckFlags2();
|
||||
void A_Boss5FindWaypoint();
|
||||
void A_DoNPCSkid();
|
||||
void A_DoNPCPain();
|
||||
void A_PrepareRepeat();
|
||||
void A_Boss5ExtraRepeat();
|
||||
void A_Boss5Calm();
|
||||
void A_Boss5CheckOnGround();
|
||||
void A_Boss5CheckFalling();
|
||||
void A_Boss5PinchShot();
|
||||
void A_Boss5MakeItRain();
|
||||
void A_Boss5MakeJunk();
|
||||
void A_LookForBetter();
|
||||
void A_Boss5BombExplode();
|
||||
void A_DustDevilThink();
|
||||
void A_TNTExplode();
|
||||
void A_DebrisRandom();
|
||||
void A_TrainCameo();
|
||||
void A_TrainCameo2();
|
||||
void A_CanarivoreGas();
|
||||
void A_KillSegments();
|
||||
void A_SnapperSpawn();
|
||||
void A_SnapperThinker();
|
||||
void A_SaloonDoorSpawn();
|
||||
void A_MinecartSparkThink();
|
||||
void A_ModuloToState();
|
||||
void A_LavafallRocks();
|
||||
void A_LavafallLava();
|
||||
void A_FallingLavaCheck();
|
||||
void A_FireShrink();
|
||||
void A_SpawnPterabytes();
|
||||
void A_PterabyteHover();
|
||||
void A_RolloutSpawn();
|
||||
void A_RolloutRock();
|
||||
void A_DragonbomberSpawn();
|
||||
void A_DragonWing();
|
||||
void A_DragonSegment();
|
||||
void A_ChangeHeight();
|
||||
void A_Explode(struct mobj_s *actor);
|
||||
void A_Pain(struct mobj_s *actor);
|
||||
void A_Fall(struct mobj_s *actor);
|
||||
void A_MonitorPop(struct mobj_s *actor);
|
||||
void A_GoldMonitorPop(struct mobj_s *actor);
|
||||
void A_GoldMonitorRestore(struct mobj_s *actor);
|
||||
void A_GoldMonitorSparkle(struct mobj_s *actor);
|
||||
void A_Look(struct mobj_s *actor);
|
||||
void A_Chase(struct mobj_s *actor);
|
||||
void A_FaceStabChase(struct mobj_s *actor);
|
||||
void A_FaceStabRev(struct mobj_s *actor);
|
||||
void A_FaceStabHurl(struct mobj_s *actor);
|
||||
void A_FaceStabMiss(struct mobj_s *actor);
|
||||
void A_StatueBurst(struct mobj_s *actor);
|
||||
void A_FaceTarget(struct mobj_s *actor);
|
||||
void A_FaceTracer(struct mobj_s *actor);
|
||||
void A_Scream(struct mobj_s *actor);
|
||||
void A_BossDeath(struct mobj_s *actor);
|
||||
void A_SetShadowScale(struct mobj_s *actor);
|
||||
void A_ShadowScream(struct mobj_s *actor); // MARIA!!!!!!
|
||||
void A_CustomPower(struct mobj_s *actor); // Use this for a custom power
|
||||
void A_GiveWeapon(struct mobj_s *actor); // Gives the player weapon(s)
|
||||
void A_RingBox(struct mobj_s *actor); // Obtained Ring Box Tails
|
||||
void A_Invincibility(struct mobj_s *actor); // Obtained Invincibility Box
|
||||
void A_SuperSneakers(struct mobj_s *actor); // Obtained Super Sneakers Box
|
||||
void A_BunnyHop(struct mobj_s *actor); // have bunny hop tails
|
||||
void A_BubbleSpawn(struct mobj_s *actor); // Randomly spawn bubbles
|
||||
void A_FanBubbleSpawn(struct mobj_s *actor);
|
||||
void A_BubbleRise(struct mobj_s *actor); // Bubbles float to surface
|
||||
void A_BubbleCheck(struct mobj_s *actor); // Don't draw if not underwater
|
||||
void A_AwardScore(struct mobj_s *actor);
|
||||
void A_ExtraLife(struct mobj_s *actor); // Extra Life
|
||||
void A_GiveShield(struct mobj_s *actor); // Obtained Shield
|
||||
void A_GravityBox(struct mobj_s *actor);
|
||||
void A_ScoreRise(struct mobj_s *actor); // Rise the score logo
|
||||
void A_AttractChase(struct mobj_s *actor); // Ring Chase
|
||||
void A_DropMine(struct mobj_s *actor); // Drop Mine from Skim or Jetty-Syn Bomber
|
||||
void A_FishJump(struct mobj_s *actor); // Fish Jump
|
||||
void A_ThrownRing(struct mobj_s *actor); // Sparkle trail for red ring
|
||||
void A_SetSolidSteam(struct mobj_s *actor);
|
||||
void A_UnsetSolidSteam(struct mobj_s *actor);
|
||||
void A_SignSpin(struct mobj_s *actor);
|
||||
void A_SignPlayer(struct mobj_s *actor);
|
||||
void A_OverlayThink(struct mobj_s *actor);
|
||||
void A_JetChase(struct mobj_s *actor);
|
||||
void A_JetbThink(struct mobj_s *actor); // Jetty-Syn Bomber Thinker
|
||||
void A_JetgThink(struct mobj_s *actor); // Jetty-Syn Gunner Thinker
|
||||
void A_JetgShoot(struct mobj_s *actor); // Jetty-Syn Shoot Function
|
||||
void A_ShootBullet(struct mobj_s *actor); // JetgShoot without reactiontime setting
|
||||
void A_MinusDigging(struct mobj_s *actor);
|
||||
void A_MinusPopup(struct mobj_s *actor);
|
||||
void A_MinusCheck(struct mobj_s *actor);
|
||||
void A_ChickenCheck(struct mobj_s *actor);
|
||||
void A_MouseThink(struct mobj_s *actor); // Mouse Thinker
|
||||
void A_DetonChase(struct mobj_s *actor); // Deton Chaser
|
||||
void A_CapeChase(struct mobj_s *actor); // Fake little Super Sonic cape
|
||||
void A_RotateSpikeBall(struct mobj_s *actor); // Spike ball rotation
|
||||
void A_SlingAppear(struct mobj_s *actor);
|
||||
void A_UnidusBall(struct mobj_s *actor);
|
||||
void A_RockSpawn(struct mobj_s *actor);
|
||||
void A_SetFuse(struct mobj_s *actor);
|
||||
void A_CrawlaCommanderThink(struct mobj_s *actor); // Crawla Commander
|
||||
void A_SmokeTrailer(struct mobj_s *actor);
|
||||
void A_RingExplode(struct mobj_s *actor);
|
||||
void A_OldRingExplode(struct mobj_s *actor);
|
||||
void A_MixUp(struct mobj_s *actor);
|
||||
void A_RecyclePowers(struct mobj_s *actor);
|
||||
void A_BossScream(struct mobj_s *actor);
|
||||
void A_Boss2TakeDamage(struct mobj_s *actor);
|
||||
void A_GoopSplat(struct mobj_s *actor);
|
||||
void A_Boss2PogoSFX(struct mobj_s *actor);
|
||||
void A_Boss2PogoTarget(struct mobj_s *actor);
|
||||
void A_EggmanBox(struct mobj_s *actor);
|
||||
void A_TurretFire(struct mobj_s *actor);
|
||||
void A_SuperTurretFire(struct mobj_s *actor);
|
||||
void A_TurretStop(struct mobj_s *actor);
|
||||
void A_JetJawRoam(struct mobj_s *actor);
|
||||
void A_JetJawChomp(struct mobj_s *actor);
|
||||
void A_PointyThink(struct mobj_s *actor);
|
||||
void A_CheckBuddy(struct mobj_s *actor);
|
||||
void A_HoodFire(struct mobj_s *actor);
|
||||
void A_HoodThink(struct mobj_s *actor);
|
||||
void A_HoodFall(struct mobj_s *actor);
|
||||
void A_ArrowBonks(struct mobj_s *actor);
|
||||
void A_SnailerThink(struct mobj_s *actor);
|
||||
void A_SharpChase(struct mobj_s *actor);
|
||||
void A_SharpSpin(struct mobj_s *actor);
|
||||
void A_SharpDecel(struct mobj_s *actor);
|
||||
void A_CrushstaceanWalk(struct mobj_s *actor);
|
||||
void A_CrushstaceanPunch(struct mobj_s *actor);
|
||||
void A_CrushclawAim(struct mobj_s *actor);
|
||||
void A_CrushclawLaunch(struct mobj_s *actor);
|
||||
void A_VultureVtol(struct mobj_s *actor);
|
||||
void A_VultureCheck(struct mobj_s *actor);
|
||||
void A_VultureHover(struct mobj_s *actor);
|
||||
void A_VultureBlast(struct mobj_s *actor);
|
||||
void A_VultureFly(struct mobj_s *actor);
|
||||
void A_SkimChase(struct mobj_s *actor);
|
||||
void A_SkullAttack(struct mobj_s *actor);
|
||||
void A_LobShot(struct mobj_s *actor);
|
||||
void A_FireShot(struct mobj_s *actor);
|
||||
void A_SuperFireShot(struct mobj_s *actor);
|
||||
void A_BossFireShot(struct mobj_s *actor);
|
||||
void A_Boss7FireMissiles(struct mobj_s *actor);
|
||||
void A_Boss1Laser(struct mobj_s *actor);
|
||||
void A_FocusTarget(struct mobj_s *actor);
|
||||
void A_Boss4Reverse(struct mobj_s *actor);
|
||||
void A_Boss4SpeedUp(struct mobj_s *actor);
|
||||
void A_Boss4Raise(struct mobj_s *actor);
|
||||
void A_SparkFollow(struct mobj_s *actor);
|
||||
void A_BuzzFly(struct mobj_s *actor);
|
||||
void A_GuardChase(struct mobj_s *actor);
|
||||
void A_EggShield(struct mobj_s *actor);
|
||||
void A_SetReactionTime(struct mobj_s *actor);
|
||||
void A_Boss1Spikeballs(struct mobj_s *actor);
|
||||
void A_Boss3TakeDamage(struct mobj_s *actor);
|
||||
void A_Boss3Path(struct mobj_s *actor);
|
||||
void A_Boss3ShockThink(struct mobj_s *actor);
|
||||
void A_Shockwave(struct mobj_s *actor);
|
||||
void A_LinedefExecute(struct mobj_s *actor);
|
||||
void A_LinedefExecuteFromArg(struct mobj_s *actor);
|
||||
void A_PlaySeeSound(struct mobj_s *actor);
|
||||
void A_PlayAttackSound(struct mobj_s *actor);
|
||||
void A_PlayActiveSound(struct mobj_s *actor);
|
||||
void A_1upThinker(struct mobj_s *actor);
|
||||
void A_BossZoom(struct mobj_s *actor); //Unused
|
||||
void A_Boss1Chase(struct mobj_s *actor);
|
||||
void A_Boss2Chase(struct mobj_s *actor);
|
||||
void A_Boss2Pogo(struct mobj_s *actor);
|
||||
void A_Boss7Chase(struct mobj_s *actor);
|
||||
void A_BossJetFume(struct mobj_s *actor);
|
||||
void A_SpawnObjectAbsolute(struct mobj_s *actor);
|
||||
void A_SpawnObjectRelative(struct mobj_s *actor);
|
||||
void A_ChangeAngleRelative(struct mobj_s *actor);
|
||||
void A_ChangeAngleAbsolute(struct mobj_s *actor);
|
||||
void A_RollAngle(struct mobj_s *actor);
|
||||
void A_ChangeRollAngleRelative(struct mobj_s *actor);
|
||||
void A_ChangeRollAngleAbsolute(struct mobj_s *actor);
|
||||
void A_PlaySound(struct mobj_s *actor);
|
||||
void A_FindTarget(struct mobj_s *actor);
|
||||
void A_FindTracer(struct mobj_s *actor);
|
||||
void A_SetTics(struct mobj_s *actor);
|
||||
void A_SetRandomTics(struct mobj_s *actor);
|
||||
void A_ChangeColorRelative(struct mobj_s *actor);
|
||||
void A_ChangeColorAbsolute(struct mobj_s *actor);
|
||||
void A_Dye(struct mobj_s *actor);
|
||||
void A_SetTranslation(struct mobj_s *actor);
|
||||
void A_MoveRelative(struct mobj_s *actor);
|
||||
void A_MoveAbsolute(struct mobj_s *actor);
|
||||
void A_Thrust(struct mobj_s *actor);
|
||||
void A_ZThrust(struct mobj_s *actor);
|
||||
void A_SetTargetsTarget(struct mobj_s *actor);
|
||||
void A_SetObjectFlags(struct mobj_s *actor);
|
||||
void A_SetObjectFlags2(struct mobj_s *actor);
|
||||
void A_RandomState(struct mobj_s *actor);
|
||||
void A_RandomStateRange(struct mobj_s *actor);
|
||||
void A_StateRangeByAngle(struct mobj_s *actor);
|
||||
void A_StateRangeByParameter(struct mobj_s *actor);
|
||||
void A_DualAction(struct mobj_s *actor);
|
||||
void A_RemoteAction(struct mobj_s *actor);
|
||||
void A_ToggleFlameJet(struct mobj_s *actor);
|
||||
void A_OrbitNights(struct mobj_s *actor);
|
||||
void A_GhostMe(struct mobj_s *actor);
|
||||
void A_SetObjectState(struct mobj_s *actor);
|
||||
void A_SetObjectTypeState(struct mobj_s *actor);
|
||||
void A_KnockBack(struct mobj_s *actor);
|
||||
void A_PushAway(struct mobj_s *actor);
|
||||
void A_RingDrain(struct mobj_s *actor);
|
||||
void A_SplitShot(struct mobj_s *actor);
|
||||
void A_MissileSplit(struct mobj_s *actor);
|
||||
void A_MultiShot(struct mobj_s *actor);
|
||||
void A_InstaLoop(struct mobj_s *actor);
|
||||
void A_Custom3DRotate(struct mobj_s *actor);
|
||||
void A_SearchForPlayers(struct mobj_s *actor);
|
||||
void A_CheckRandom(struct mobj_s *actor);
|
||||
void A_CheckTargetRings(struct mobj_s *actor);
|
||||
void A_CheckRings(struct mobj_s *actor);
|
||||
void A_CheckTotalRings(struct mobj_s *actor);
|
||||
void A_CheckHealth(struct mobj_s *actor);
|
||||
void A_CheckRange(struct mobj_s *actor);
|
||||
void A_CheckHeight(struct mobj_s *actor);
|
||||
void A_CheckTrueRange(struct mobj_s *actor);
|
||||
void A_CheckThingCount(struct mobj_s *actor);
|
||||
void A_CheckAmbush(struct mobj_s *actor);
|
||||
void A_CheckCustomValue(struct mobj_s *actor);
|
||||
void A_CheckCusValMemo(struct mobj_s *actor);
|
||||
void A_SetCustomValue(struct mobj_s *actor);
|
||||
void A_UseCusValMemo(struct mobj_s *actor);
|
||||
void A_RelayCustomValue(struct mobj_s *actor);
|
||||
void A_CusValAction(struct mobj_s *actor);
|
||||
void A_ForceStop(struct mobj_s *actor);
|
||||
void A_ForceWin(struct mobj_s *actor);
|
||||
void A_SpikeRetract(struct mobj_s *actor);
|
||||
void A_InfoState(struct mobj_s *actor);
|
||||
void A_Repeat(struct mobj_s *actor);
|
||||
void A_SetScale(struct mobj_s *actor);
|
||||
void A_RemoteDamage(struct mobj_s *actor);
|
||||
void A_HomingChase(struct mobj_s *actor);
|
||||
void A_TrapShot(struct mobj_s *actor);
|
||||
void A_VileTarget(struct mobj_s *actor);
|
||||
void A_VileAttack(struct mobj_s *actor);
|
||||
void A_VileFire(struct mobj_s *actor);
|
||||
void A_BrakChase(struct mobj_s *actor);
|
||||
void A_BrakFireShot(struct mobj_s *actor);
|
||||
void A_BrakLobShot(struct mobj_s *actor);
|
||||
void A_NapalmScatter(struct mobj_s *actor);
|
||||
void A_SpawnFreshCopy(struct mobj_s *actor);
|
||||
void A_FlickySpawn(struct mobj_s *actor);
|
||||
void A_FlickyCenter(struct mobj_s *actor);
|
||||
void A_FlickyAim(struct mobj_s *actor);
|
||||
void A_FlickyFly(struct mobj_s *actor);
|
||||
void A_FlickySoar(struct mobj_s *actor);
|
||||
void A_FlickyCoast(struct mobj_s *actor);
|
||||
void A_FlickyHop(struct mobj_s *actor);
|
||||
void A_FlickyFlounder(struct mobj_s *actor);
|
||||
void A_FlickyCheck(struct mobj_s *actor);
|
||||
void A_FlickyHeightCheck(struct mobj_s *actor);
|
||||
void A_FlickyFlutter(struct mobj_s *actor);
|
||||
void A_FlameParticle(struct mobj_s *actor);
|
||||
void A_FadeOverlay(struct mobj_s *actor);
|
||||
void A_Boss5Jump(struct mobj_s *actor);
|
||||
void A_LightBeamReset(struct mobj_s *actor);
|
||||
void A_MineExplode(struct mobj_s *actor);
|
||||
void A_MineRange(struct mobj_s *actor);
|
||||
void A_ConnectToGround(struct mobj_s *actor);
|
||||
void A_SpawnParticleRelative(struct mobj_s *actor);
|
||||
void A_MultiShotDist(struct mobj_s *actor);
|
||||
void A_WhoCaresIfYourSonIsABee(struct mobj_s *actor);
|
||||
void A_ParentTriesToSleep(struct mobj_s *actor);
|
||||
void A_CryingToMomma(struct mobj_s *actor);
|
||||
void A_CheckFlags2(struct mobj_s *actor);
|
||||
void A_Boss5FindWaypoint(struct mobj_s *actor);
|
||||
void A_DoNPCSkid(struct mobj_s *actor);
|
||||
void A_DoNPCPain(struct mobj_s *actor);
|
||||
void A_PrepareRepeat(struct mobj_s *actor);
|
||||
void A_Boss5ExtraRepeat(struct mobj_s *actor);
|
||||
void A_Boss5Calm(struct mobj_s *actor);
|
||||
void A_Boss5CheckOnGround(struct mobj_s *actor);
|
||||
void A_Boss5CheckFalling(struct mobj_s *actor);
|
||||
void A_Boss5PinchShot(struct mobj_s *actor);
|
||||
void A_Boss5MakeItRain(struct mobj_s *actor);
|
||||
void A_Boss5MakeJunk(struct mobj_s *actor);
|
||||
void A_LookForBetter(struct mobj_s *actor);
|
||||
void A_Boss5BombExplode(struct mobj_s *actor);
|
||||
void A_DustDevilThink(struct mobj_s *actor);
|
||||
void A_TNTExplode(struct mobj_s *actor);
|
||||
void A_DebrisRandom(struct mobj_s *actor);
|
||||
void A_TrainCameo(struct mobj_s *actor);
|
||||
void A_TrainCameo2(struct mobj_s *actor);
|
||||
void A_CanarivoreGas(struct mobj_s *actor);
|
||||
void A_KillSegments(struct mobj_s *actor);
|
||||
void A_SnapperSpawn(struct mobj_s *actor);
|
||||
void A_SnapperThinker(struct mobj_s *actor);
|
||||
void A_SaloonDoorSpawn(struct mobj_s *actor);
|
||||
void A_MinecartSparkThink(struct mobj_s *actor);
|
||||
void A_ModuloToState(struct mobj_s *actor);
|
||||
void A_LavafallRocks(struct mobj_s *actor);
|
||||
void A_LavafallLava(struct mobj_s *actor);
|
||||
void A_FallingLavaCheck(struct mobj_s *actor);
|
||||
void A_FireShrink(struct mobj_s *actor);
|
||||
void A_SpawnPterabytes(struct mobj_s *actor);
|
||||
void A_PterabyteHover(struct mobj_s *actor);
|
||||
void A_RolloutSpawn(struct mobj_s *actor);
|
||||
void A_RolloutRock(struct mobj_s *actor);
|
||||
void A_DragonbomberSpawn(struct mobj_s *actor);
|
||||
void A_DragonWing(struct mobj_s *actor);
|
||||
void A_DragonSegment(struct mobj_s *actor);
|
||||
void A_ChangeHeight(struct mobj_s *actor);
|
||||
|
||||
extern int actionsoverridden[NUMACTIONS][MAX_ACTION_RECURSION];
|
||||
|
||||
|
|
|
@ -184,8 +184,10 @@ static const struct {
|
|||
{META_SKIN, "skin_t"},
|
||||
{META_POWERS, "player_t.powers"},
|
||||
{META_SOUNDSID, "skin_t.soundsid"},
|
||||
{META_SKINSPRITES, "skin_t.sprites"},
|
||||
{META_SKINSPRITESLIST, "skin_t.sprites[]"},
|
||||
|
||||
{META_SKINSPRITES, "skin_t.skinsprites"},
|
||||
{META_SKINSPRITESLIST, "skin_t.skinsprites[]"},
|
||||
{META_SKINSPRITESCOMPAT, "skin_t.sprites"}, // TODO: 2.3: Delete
|
||||
|
||||
{META_VERTEX, "vertex_t"},
|
||||
{META_LINE, "line_t"},
|
||||
|
@ -653,7 +655,7 @@ static int lib_pSpawnMobj(lua_State *L)
|
|||
NOHUD
|
||||
INLEVEL
|
||||
NOSPAWNNULL
|
||||
LUA_PushUserdata(L, P_SpawnMobj(x, y, z, type), META_MOBJ);
|
||||
LUA_PushUserdata(L, P_SpawnMobj(x, y, z, type, NULL), META_MOBJ);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -3876,7 +3878,7 @@ static int lib_gAddPlayer(lua_State *L)
|
|||
player_t *newplayer;
|
||||
SINT8 skinnum = 0, bot;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
for (i = 1; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i])
|
||||
break;
|
||||
|
|
|
@ -42,8 +42,9 @@ extern boolean ignoregameinputs;
|
|||
#define META_SKIN "SKIN_T*"
|
||||
#define META_POWERS "PLAYER_T*POWERS"
|
||||
#define META_SOUNDSID "SKIN_T*SOUNDSID"
|
||||
#define META_SKINSPRITES "SKIN_T*SPRITES"
|
||||
#define META_SKINSPRITESLIST "SKIN_T*SPRITES[]"
|
||||
#define META_SKINSPRITES "SKIN_T*SKINSPRITES"
|
||||
#define META_SKINSPRITESLIST "SKIN_T*SKINSPRITES[]"
|
||||
#define META_SKINSPRITESCOMPAT "SKIN_T*SPRITES" // TODO: 2.3: Delete
|
||||
|
||||
#define META_VERTEX "VERTEX_T*"
|
||||
#define META_LINE "LINE_T*"
|
||||
|
|
|
@ -213,6 +213,14 @@ enum side_e {
|
|||
side_sector,
|
||||
side_special,
|
||||
side_repeatcnt,
|
||||
side_light,
|
||||
side_light_top,
|
||||
side_light_mid,
|
||||
side_light_bottom,
|
||||
side_lightabsolute,
|
||||
side_lightabsolute_top,
|
||||
side_lightabsolute_mid,
|
||||
side_lightabsolute_bottom,
|
||||
side_text
|
||||
};
|
||||
|
||||
|
@ -241,6 +249,14 @@ static const char *const side_opt[] = {
|
|||
"sector",
|
||||
"special",
|
||||
"repeatcnt",
|
||||
"light",
|
||||
"light_top",
|
||||
"light_mid",
|
||||
"light_bottom",
|
||||
"lightabsolute",
|
||||
"lightabsolute_top",
|
||||
"lightabsolute_mid",
|
||||
"lightabsolute_bottom",
|
||||
"text",
|
||||
NULL};
|
||||
|
||||
|
@ -1311,6 +1327,30 @@ static int side_get(lua_State *L)
|
|||
case side_repeatcnt:
|
||||
lua_pushinteger(L, side->repeatcnt);
|
||||
return 1;
|
||||
case side_light:
|
||||
lua_pushinteger(L, side->light);
|
||||
return 1;
|
||||
case side_light_top:
|
||||
lua_pushinteger(L, side->light_top);
|
||||
return 1;
|
||||
case side_light_mid:
|
||||
lua_pushinteger(L, side->light_mid);
|
||||
return 1;
|
||||
case side_light_bottom:
|
||||
lua_pushinteger(L, side->light_bottom);
|
||||
return 1;
|
||||
case side_lightabsolute:
|
||||
lua_pushboolean(L, side->lightabsolute);
|
||||
return 1;
|
||||
case side_lightabsolute_top:
|
||||
lua_pushboolean(L, side->lightabsolute_top);
|
||||
return 1;
|
||||
case side_lightabsolute_mid:
|
||||
lua_pushboolean(L, side->lightabsolute_mid);
|
||||
return 1;
|
||||
case side_lightabsolute_bottom:
|
||||
lua_pushboolean(L, side->lightabsolute_bottom);
|
||||
return 1;
|
||||
// TODO: 2.3: Delete
|
||||
case side_text:
|
||||
{
|
||||
|
@ -1413,6 +1453,30 @@ static int side_set(lua_State *L)
|
|||
case side_repeatcnt:
|
||||
side->repeatcnt = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case side_light:
|
||||
side->light = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case side_light_top:
|
||||
side->light_top = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case side_light_mid:
|
||||
side->light_mid = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case side_light_bottom:
|
||||
side->light_bottom = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case side_lightabsolute:
|
||||
side->lightabsolute = luaL_checkboolean(L, 3);
|
||||
break;
|
||||
case side_lightabsolute_top:
|
||||
side->lightabsolute_top = luaL_checkboolean(L, 3);
|
||||
break;
|
||||
case side_lightabsolute_mid:
|
||||
side->lightabsolute_mid = luaL_checkboolean(L, 3);
|
||||
break;
|
||||
case side_lightabsolute_bottom:
|
||||
side->lightabsolute_bottom = luaL_checkboolean(L, 3);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -69,6 +69,7 @@ enum mobj_e {
|
|||
mobj_color,
|
||||
mobj_translation,
|
||||
mobj_blendmode,
|
||||
mobj_alpha,
|
||||
mobj_bnext,
|
||||
mobj_bprev,
|
||||
mobj_hnext,
|
||||
|
@ -150,6 +151,7 @@ static const char *const mobj_opt[] = {
|
|||
"color",
|
||||
"translation",
|
||||
"blendmode",
|
||||
"alpha",
|
||||
"bnext",
|
||||
"bprev",
|
||||
"hnext",
|
||||
|
@ -354,6 +356,9 @@ static int mobj_get(lua_State *L)
|
|||
case mobj_blendmode:
|
||||
lua_pushinteger(L, mo->blendmode);
|
||||
break;
|
||||
case mobj_alpha:
|
||||
lua_pushfixed(L, mo->alpha);
|
||||
break;
|
||||
case mobj_bnext:
|
||||
if (mo->blocknode && mo->blocknode->bnext) {
|
||||
LUA_PushUserdata(L, mo->blocknode->bnext->mobj, META_MOBJ);
|
||||
|
@ -733,6 +738,16 @@ static int mobj_set(lua_State *L)
|
|||
mo->blendmode = blendmode;
|
||||
break;
|
||||
}
|
||||
case mobj_alpha:
|
||||
{
|
||||
fixed_t alpha = luaL_checkfixed(L, 3);
|
||||
if (alpha < 0)
|
||||
alpha = 0;
|
||||
else if (alpha > FRACUNIT)
|
||||
alpha = FRACUNIT;
|
||||
mo->alpha = alpha;
|
||||
break;
|
||||
}
|
||||
case mobj_bnext:
|
||||
return NOSETPOS;
|
||||
case mobj_bprev:
|
||||
|
|
|
@ -54,7 +54,8 @@ enum skin {
|
|||
skin_contspeed,
|
||||
skin_contangle,
|
||||
skin_soundsid,
|
||||
skin_sprites,
|
||||
skin_sprites, // TODO: 2.3: Delete
|
||||
skin_skinsprites,
|
||||
skin_supersprites,
|
||||
skin_natkcolor
|
||||
};
|
||||
|
@ -95,7 +96,8 @@ static const char *const skin_opt[] = {
|
|||
"contspeed",
|
||||
"contangle",
|
||||
"soundsid",
|
||||
"sprites",
|
||||
"sprites", // TODO: 2.3: Delete
|
||||
"skinsprites",
|
||||
"supersprites",
|
||||
"natkcolor",
|
||||
NULL};
|
||||
|
@ -219,7 +221,10 @@ static int skin_get(lua_State *L)
|
|||
case skin_soundsid:
|
||||
LUA_PushUserdata(L, skin->soundsid, META_SOUNDSID);
|
||||
break;
|
||||
case skin_sprites:
|
||||
case skin_sprites: // TODO: 2.3: Delete
|
||||
LUA_PushUserdata(L, skin->sprites_compat, META_SKINSPRITESCOMPAT);
|
||||
break;
|
||||
case skin_skinsprites:
|
||||
LUA_PushUserdata(L, skin->sprites, META_SKINSPRITES);
|
||||
break;
|
||||
case skin_supersprites:
|
||||
|
@ -338,15 +343,7 @@ static int soundsid_num(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
enum spritesopt {
|
||||
numframes = 0
|
||||
};
|
||||
|
||||
static const char *const sprites_opt[] = {
|
||||
"numframes",
|
||||
NULL};
|
||||
|
||||
// skin.sprites[i] -> sprites[i]
|
||||
// skin.skinsprites[i] -> sprites[i]
|
||||
static int lib_getSkinSprite(lua_State *L)
|
||||
{
|
||||
spritedef_t *sksprites = *(spritedef_t **)luaL_checkudata(L, 1, META_SKINSPRITES);
|
||||
|
@ -359,13 +356,43 @@ static int lib_getSkinSprite(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
// #skin.sprites -> NUMPLAYERSPRITES
|
||||
// #skin.skinsprites -> NUMPLAYERSPRITES
|
||||
static int lib_numSkinsSprites(lua_State *L)
|
||||
{
|
||||
lua_pushinteger(L, NUMPLAYERSPRITES);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// TODO: 2.3: Delete
|
||||
// skin.sprites[i] -> sprites[i]
|
||||
static int lib_getSkinSpriteCompat(lua_State *L)
|
||||
{
|
||||
spritedef_t *sksprites = *(spritedef_t **)luaL_checkudata(L, 1, META_SKINSPRITESCOMPAT);
|
||||
playersprite_t i = luaL_checkinteger(L, 2);
|
||||
|
||||
if (i < 0 || i >= NUMPLAYERSPRITES*2)
|
||||
return luaL_error(L, "skin sprites index %d out of range (0 - %d)", i, (NUMPLAYERSPRITES*2)-1);
|
||||
|
||||
LUA_PushUserdata(L, &sksprites[i], META_SKINSPRITESLIST);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// TODO: 2.3: Delete
|
||||
// #skin.sprites -> NUMPLAYERSPRITES*2
|
||||
static int lib_numSkinsSpritesCompat(lua_State *L)
|
||||
{
|
||||
lua_pushinteger(L, NUMPLAYERSPRITES*2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
enum spritesopt {
|
||||
numframes = 0
|
||||
};
|
||||
|
||||
static const char *const sprites_opt[] = {
|
||||
"numframes",
|
||||
NULL};
|
||||
|
||||
static int sprite_get(lua_State *L)
|
||||
{
|
||||
spritedef_t *sprite = *(spritedef_t **)luaL_checkudata(L, 1, META_SKINSPRITESLIST);
|
||||
|
@ -387,6 +414,7 @@ int LUA_SkinLib(lua_State *L)
|
|||
LUA_RegisterUserdataMetatable(L, META_SOUNDSID, soundsid_get, NULL, soundsid_num);
|
||||
LUA_RegisterUserdataMetatable(L, META_SKINSPRITES, lib_getSkinSprite, NULL, lib_numSkinsSprites);
|
||||
LUA_RegisterUserdataMetatable(L, META_SKINSPRITESLIST, sprite_get, NULL, NULL);
|
||||
LUA_RegisterUserdataMetatable(L, META_SKINSPRITESCOMPAT, lib_getSkinSpriteCompat, NULL, lib_numSkinsSpritesCompat); // TODO: 2.3: Delete
|
||||
|
||||
skin_fields_ref = Lua_CreateFieldTable(L, skin_opt);
|
||||
|
||||
|
|
|
@ -494,6 +494,12 @@ UINT8 M_MapLocked(INT32 mapnum, gamedata_t *data)
|
|||
|
||||
UINT8 M_CampaignWarpIsCheat(INT32 gt, INT32 mapnum, gamedata_t *data)
|
||||
{
|
||||
if (dedicated)
|
||||
{
|
||||
// See M_MapLocked; don't make dedicated servers annoying.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (M_MapLocked(mapnum, data) == true)
|
||||
{
|
||||
// Warping to locked maps is definitely always a cheat
|
||||
|
|
259
src/m_menu.c
259
src/m_menu.c
|
@ -140,6 +140,7 @@ static char *char_notes = NULL;
|
|||
|
||||
boolean menuactive = false;
|
||||
boolean fromlevelselect = false;
|
||||
tic_t shieldprompt_timer = 0; // Show a prompt about the new Shield button for old configs // TODO: 2.3: Remove
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
@ -3161,6 +3162,7 @@ static void Command_Manual_f(void)
|
|||
if (modeattacking)
|
||||
return;
|
||||
M_StartControlPanel();
|
||||
if (shieldprompt_timer) return; // TODO: 2.3: Delete this line
|
||||
currentMenu = &MISC_HelpDef;
|
||||
itemOn = 0;
|
||||
}
|
||||
|
@ -3340,6 +3342,7 @@ boolean M_Responder(event_t *ev)
|
|||
if (modeattacking)
|
||||
return true;
|
||||
M_StartControlPanel();
|
||||
if (shieldprompt_timer) return true; // TODO: 2.3: Delete this line
|
||||
M_Options(0);
|
||||
// Uncomment the below if you want the menu to reset to the top each time like before. M_SetupNextMenu will fix it automatically.
|
||||
//OP_SoundOptionsDef.lastOn = 0;
|
||||
|
@ -3350,6 +3353,7 @@ boolean M_Responder(event_t *ev)
|
|||
if (modeattacking)
|
||||
return true;
|
||||
M_StartControlPanel();
|
||||
if (shieldprompt_timer) return true; // TODO: 2.3: Delete this line
|
||||
M_Options(0);
|
||||
M_VideoModeMenu(0);
|
||||
return true;
|
||||
|
@ -3361,6 +3365,7 @@ boolean M_Responder(event_t *ev)
|
|||
if (modeattacking)
|
||||
return true;
|
||||
M_StartControlPanel();
|
||||
if (shieldprompt_timer) return true; // TODO: 2.3: Delete this line
|
||||
M_Options(0);
|
||||
M_SetupNextMenu(&OP_MainDef);
|
||||
return true;
|
||||
|
@ -3631,6 +3636,230 @@ void M_Drawer(void)
|
|||
}
|
||||
}
|
||||
|
||||
// Handle the "Do you want to assign Shield Ability now?" pop-up for old configs // TODO: 2.3: Remove this line...
|
||||
static UINT8 shieldprompt_currentchoice = 0; // ...and this line...
|
||||
|
||||
static void M_ShieldPromptUseDefaults(void) // ...and this function
|
||||
{
|
||||
// With a default config from v2.2.10 to v2.2.13, the B button will be set to Custom 1,
|
||||
// and Controls per Key defaults to "One", so it will override the default Shield button.
|
||||
// A default config from v2.2.0 to v2.2.9 has Next Weapon on B, so it suffers from this too.
|
||||
|
||||
// So for "Use default Shield Ability buttons", we should update old configs to mitigate gamepad conflicts
|
||||
// (even with "Several" Controls per Key!), and show a message with the default bindings
|
||||
|
||||
for (setupcontrols = gamecontrol; true; setupcontrols = gamecontrolbis) // Do stuff for both P1 and P2
|
||||
{
|
||||
INT32 JOY1 = (setupcontrols == gamecontrol) ? KEY_JOY1 : KEY_2JOY1; // Is this for P1 or for P2?
|
||||
|
||||
if ((setupcontrols[GC_CUSTOM1][0] == JOY1+1 || setupcontrols[GC_CUSTOM1][1] == JOY1+1)
|
||||
&& (setupcontrols[GC_CUSTOM2][0] == JOY1+3 || setupcontrols[GC_CUSTOM2][1] == JOY1+3)
|
||||
&& (setupcontrols[GC_CUSTOM3][0] == JOY1+8 || setupcontrols[GC_CUSTOM3][1] == JOY1+8))
|
||||
{
|
||||
// If the player has v2.2.13's default gamepad Custom 1/2/3 buttons,
|
||||
// shuffle Custom 1/2/3 around to make room for Shield Ability on B
|
||||
UINT8 shield_slot = (setupcontrols[GC_SHIELD ][0] == KEY_NULL ) ? 0 : 1;
|
||||
UINT8 custom1_slot = (setupcontrols[GC_CUSTOM1][0] == JOY1+1) ? 0 : 1;
|
||||
UINT8 custom2_slot = (setupcontrols[GC_CUSTOM2][0] == JOY1+3) ? 0 : 1;
|
||||
UINT8 custom3_slot = (setupcontrols[GC_CUSTOM3][0] == JOY1+8) ? 0 : 1;
|
||||
|
||||
setupcontrols[GC_SHIELD ][shield_slot ] = JOY1+1; // Assign Shield Ability to B
|
||||
setupcontrols[GC_CUSTOM1][custom1_slot] = JOY1+3; // Move Custom 1 from B to Y
|
||||
setupcontrols[GC_CUSTOM2][custom2_slot] = JOY1+8; // Move Custom 2 from Y to LS
|
||||
setupcontrols[GC_CUSTOM3][custom3_slot] = KEY_NULL; // Unassign Custom 3 from LS...
|
||||
// (The alternative would be to check and update the ENTIRE gamepad layout.
|
||||
// That'd be nice, but it would mess with people that are used to the old defaults.)
|
||||
}
|
||||
else if ((setupcontrols[GC_WEAPONNEXT][0] == JOY1+1 || setupcontrols[GC_WEAPONNEXT][1] == JOY1+1)
|
||||
&& (setupcontrols[GC_WEAPONPREV][0] == JOY1+2 || setupcontrols[GC_WEAPONPREV][1] == JOY1+2))
|
||||
{
|
||||
// Or if the user has a default config from v2.2.0 to v2.2.9,
|
||||
// the B button will be Next Weapon, and X will be Previous Weapon.
|
||||
// It's "safe" to discard one of them, you just have to press X multiple times to select in the other direction
|
||||
UINT8 shield_slot = (setupcontrols[GC_SHIELD ][0] == KEY_NULL ) ? 0 : 1;
|
||||
UINT8 nweapon_slot = (setupcontrols[GC_WEAPONNEXT][0] == JOY1+1) ? 0 : 1;
|
||||
UINT8 pweapon_slot = (setupcontrols[GC_WEAPONPREV][0] == JOY1+2) ? 0 : 1;
|
||||
|
||||
setupcontrols[GC_SHIELD ][shield_slot ] = JOY1+1; // Assign Shield Ability to B
|
||||
setupcontrols[GC_WEAPONNEXT][nweapon_slot] = JOY1+3; // Move Next Weapon from B to X
|
||||
setupcontrols[GC_WEAPONPREV][pweapon_slot] = KEY_NULL; // Unassign Previous Weapon from X
|
||||
}
|
||||
|
||||
if (setupcontrols == gamecontrolbis) // If we've already updated both players, break out
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// Now, show a message about the default Shield Ability bindings
|
||||
if ((gamecontrol[GC_SHIELD][0] == KEY_LALT && gamecontrol[GC_SHIELD][1] == KEY_JOY1+1)
|
||||
|| (gamecontrol[GC_SHIELD][0] == KEY_JOY1+1 && gamecontrol[GC_SHIELD][1] == KEY_LALT))
|
||||
{
|
||||
// Left Alt and the B button are both assigned
|
||||
M_StartMessage(M_GetText("Shield Ability defaults to\nthe \x82""Left Alt\x80"" key on keyboard,\nand the \x85""B button\x80"" on gamepads."
|
||||
"\n\nYou can always reassign it\nin the Options menu later."
|
||||
"\n\n\nPress 'Enter' to continue\n"),
|
||||
NULL, MM_NOTHING);
|
||||
MessageDef.x = 43; // Change the pop-up message's background position/width
|
||||
MessageDef.lastOn = (MessageDef.lastOn & ~0xFF) | 27;
|
||||
}
|
||||
else if (gamecontrol[GC_SHIELD][0] == KEY_LALT || gamecontrol[GC_SHIELD][1] == KEY_LALT)
|
||||
{
|
||||
// Left Alt is assigned, but the B button isn't.
|
||||
M_StartMessage(M_GetText("Shield Ability defaults to\nthe \x82""Left Alt\x80"" key on keyboard.\nThe \x85""B button\x80"" on gamepads was taken."
|
||||
"\n\nYou can always reassign it\nin the Options menu later."
|
||||
"\n\n\nPress 'Enter' to continue\n"),
|
||||
NULL, MM_NOTHING);
|
||||
MessageDef.x = 24; // Change the pop-up message's background position/width
|
||||
MessageDef.lastOn = (MessageDef.lastOn & ~0xFF) | 32;
|
||||
}
|
||||
else if (gamecontrol[GC_SHIELD][0] == KEY_JOY1+1 || gamecontrol[GC_SHIELD][1] == KEY_JOY1+1)
|
||||
{
|
||||
// The B button is assigned, but Left Alt isn't
|
||||
M_StartMessage(M_GetText("Shield Ability defaults to\nthe \x85""B button\x80"" on gamepads.\nThe \x82""Left Alt\x80"" key on keyboard was taken."
|
||||
"\n\nYou can always reassign it\nin the Options menu later."
|
||||
"\n\n\nPress 'Enter' to continue\n"),
|
||||
NULL, MM_NOTHING);
|
||||
MessageDef.x = 8; // Change the pop-up message's background position/width
|
||||
MessageDef.lastOn = (MessageDef.lastOn & ~0xFF) | 36;
|
||||
}
|
||||
else if (gamecontrol[GC_SHIELD][0] == KEY_NULL && gamecontrol[GC_SHIELD][1] == KEY_NULL)
|
||||
{
|
||||
// Neither Left Alt nor the B button are assigned
|
||||
M_StartMessage(M_GetText("Shield Ability is unassigned!\nThe \x82""Left Alt\x80"" key on keyboard and\nthe \x85""B button\x80"" on gamepads were taken."
|
||||
"\n\nYou should assign Shield Ability\nin the Options menu later."
|
||||
"\n\n\nPress 'Enter' to continue\n"),
|
||||
NULL, MM_NOTHING);
|
||||
MessageDef.x = 19; // Change the pop-up message's background position/width
|
||||
MessageDef.lastOn = (MessageDef.lastOn & ~0xFF) | 33;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Neither Left Alt nor the B button are assigned... but something else is???
|
||||
// (This can technically happen if you edit your config or use setcontrol in the console before opening the menu)
|
||||
char keystr[16+16+2+7+1]; // Two 16-char keys + two colour codes + "' and '" + null
|
||||
|
||||
if (gamecontrol[GC_SHIELD][0] != KEY_NULL && gamecontrol[GC_SHIELD][1] != KEY_NULL)
|
||||
STRBUFCPY(keystr, va("%s\x80""' and '\x82""%s",
|
||||
G_KeyNumToName(gamecontrol[GC_SHIELD][0]),
|
||||
G_KeyNumToName(gamecontrol[GC_SHIELD][1])));
|
||||
else if (gamecontrol[GC_SHIELD][0] != KEY_NULL)
|
||||
STRBUFCPY(keystr, G_KeyNumToName(gamecontrol[GC_SHIELD][0]));
|
||||
else //if (gamecontrol[GC_SHIELD][1] != KEY_NULL)
|
||||
STRBUFCPY(keystr, G_KeyNumToName(gamecontrol[GC_SHIELD][1]));
|
||||
|
||||
M_StartMessage(va("Shield Ability is assigned to\n'\x82""%s\x80""'."
|
||||
"\n\nYou can always reassign it\nin the Options menu later."
|
||||
"\n\n\nPress 'Enter' to continue\n",
|
||||
keystr), NULL, MM_NOTHING);
|
||||
MessageDef.x = 23; // Change the pop-up message's background position/width
|
||||
MessageDef.lastOn = (MessageDef.lastOn & ~0xFF) | 32;
|
||||
}
|
||||
}
|
||||
|
||||
static void M_HandleShieldPromptMenu(INT32 choice) // TODO: 2.3: Remove
|
||||
{
|
||||
switch (choice)
|
||||
{
|
||||
case KEY_ESCAPE:
|
||||
if (I_GetTime() <= shieldprompt_timer) // Don't mash past the pop-up by accident!
|
||||
break;
|
||||
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
noFurtherInput = true;
|
||||
shieldprompt_timer = 0;
|
||||
M_ShieldPromptUseDefaults();
|
||||
break;
|
||||
|
||||
case KEY_ENTER:
|
||||
if (I_GetTime() <= shieldprompt_timer) // Don't mash past the pop-up by accident!
|
||||
break;
|
||||
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
noFurtherInput = true;
|
||||
shieldprompt_timer = 0;
|
||||
|
||||
if (shieldprompt_currentchoice == 0)
|
||||
{
|
||||
OP_ChangeControlsDef.lastOn = 8; // Highlight Shield Ability in the controls menu
|
||||
M_Setup1PControlsMenu(0); // Set up P1's controls menu and call M_SetupNextMenu
|
||||
}
|
||||
else if (shieldprompt_currentchoice == 1) // Copy the Spin buttons to the Shield buttons
|
||||
{
|
||||
CV_SetValue(&cv_controlperkey, 2); // Make sure that Controls per Key is "Several"
|
||||
|
||||
gamecontrol [GC_SHIELD][0] = gamecontrol [GC_SPIN][0];
|
||||
gamecontrol [GC_SHIELD][1] = gamecontrol [GC_SPIN][1];
|
||||
gamecontrolbis[GC_SHIELD][0] = gamecontrolbis[GC_SPIN][0];
|
||||
gamecontrolbis[GC_SHIELD][1] = gamecontrolbis[GC_SPIN][1];
|
||||
CV_SetValue(&cv_shieldaxis, cv_spinaxis.value);
|
||||
CV_SetValue(&cv_shieldaxis2, cv_spinaxis2.value);
|
||||
|
||||
M_StartMessage(M_GetText("Spin and Shield Ability are now\nthe same button."
|
||||
"\n\nYou can always reassign them\nin the Options menu later."
|
||||
"\n\n\nPress 'Enter' to continue\n"),
|
||||
NULL, MM_NOTHING);
|
||||
MessageDef.x = 36; // Change the pop-up message's background position/width
|
||||
MessageDef.lastOn = (MessageDef.lastOn & ~0xFF) | 29;
|
||||
}
|
||||
else
|
||||
M_ShieldPromptUseDefaults();
|
||||
break;
|
||||
|
||||
case KEY_UPARROW:
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
shieldprompt_currentchoice = (shieldprompt_currentchoice+2)%3;
|
||||
break;
|
||||
|
||||
case KEY_DOWNARROW:
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
shieldprompt_currentchoice = (shieldprompt_currentchoice+1)%3;
|
||||
break;
|
||||
}
|
||||
|
||||
MessageDef.prevMenu = &MainDef;
|
||||
}
|
||||
|
||||
static void M_DrawShieldPromptMenu(void) // TODO: 2.3: Remove
|
||||
{
|
||||
INT16 cursorx = (BASEVIDWIDTH/2) - 24;
|
||||
|
||||
V_DrawFill(10-3, 68-3, 300+6, 40+6, 159);
|
||||
// V_DrawCenteredString doesn't centre newlines, so we have to draw each line separately
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 68, V_ALLOWLOWERCASE, "Welcome back! Since you last played,");
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 76, V_ALLOWLOWERCASE, "Spin has been split into separate");
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 84, V_ALLOWLOWERCASE, "\"Spin\" and \"Shield Ability\" controls.");
|
||||
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 98, V_ALLOWLOWERCASE, "Do you want to assign Shield Ability now?");
|
||||
|
||||
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 164,
|
||||
(shieldprompt_currentchoice == 0) ? V_YELLOWMAP : 0, "Open Control Setup");
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 172,
|
||||
(shieldprompt_currentchoice == 1) ? V_YELLOWMAP : 0, "Keep the old behaviour");
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 180,
|
||||
(shieldprompt_currentchoice == 2) ? V_YELLOWMAP : 0, "Use default Shield Ability buttons");
|
||||
|
||||
switch (shieldprompt_currentchoice)
|
||||
{
|
||||
case 0: cursorx -= V_StringWidth("Open Control Setup", 0)/2; break;
|
||||
case 1: cursorx -= V_StringWidth("Keep the old behaviour", 0)/2; break;
|
||||
default: cursorx -= V_StringWidth("Use default Shield Ability buttons", 0)/2; break;
|
||||
}
|
||||
V_DrawScaledPatch(cursorx, 164 + (shieldprompt_currentchoice*8), 0, W_CachePatchName("M_CURSOR", PU_PATCH));
|
||||
}
|
||||
|
||||
static menuitem_t OP_ShieldPromptMenu[] = {{IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandleShieldPromptMenu, 0}}; // TODO: 2.3: Remove
|
||||
|
||||
menu_t OP_ShieldPromptDef = { // TODO: 2.3: Remove
|
||||
MN_SPECIAL,
|
||||
NULL,
|
||||
1,
|
||||
&MainDef,
|
||||
OP_ShieldPromptMenu,
|
||||
M_DrawShieldPromptMenu,
|
||||
0, 0, 0, NULL
|
||||
};
|
||||
|
||||
//
|
||||
// M_StartControlPanel
|
||||
//
|
||||
|
@ -3662,6 +3891,15 @@ void M_StartControlPanel(void)
|
|||
currentMenu = &MainDef;
|
||||
itemOn = singleplr;
|
||||
M_UpdateItemOn();
|
||||
|
||||
if (shieldprompt_timer) // For old configs, show a pop-up about the new Shield button // TODO: 2.3: Remove
|
||||
{
|
||||
S_StartSound(NULL, sfx_strpst);
|
||||
noFurtherInput = true;
|
||||
shieldprompt_timer = I_GetTime() + TICRATE; // Don't mash past the pop-up by accident!
|
||||
|
||||
M_SetupNextMenu(&OP_ShieldPromptDef);
|
||||
}
|
||||
}
|
||||
else if (modeattacking)
|
||||
{
|
||||
|
@ -8372,7 +8610,7 @@ static void M_DrawLoadGameData(void)
|
|||
if (savegameinfo[savetodraw].lives == -42)
|
||||
col = 26;
|
||||
else if (savegameinfo[savetodraw].botskin == 3) // & knuckles
|
||||
col = 105;
|
||||
col = 106;
|
||||
else if (savegameinfo[savetodraw].botskin) // tailsbot or custom
|
||||
col = 134;
|
||||
else
|
||||
|
@ -8432,7 +8670,17 @@ static void M_DrawLoadGameData(void)
|
|||
if (savegameinfo[savetodraw].lives == -42)
|
||||
V_DrawRightAlignedThinString(x + 79, y, V_GRAYMAP, "NEW GAME");
|
||||
else if (savegameinfo[savetodraw].lives == -666)
|
||||
V_DrawRightAlignedThinString(x + 79, y, V_REDMAP, "CAN'T LOAD!");
|
||||
{
|
||||
if (savegameinfo[savetodraw].continuescore == -62)
|
||||
{
|
||||
V_DrawRightAlignedThinString(x + 79, y, V_REDMAP, "ADDON NOT LOADED");
|
||||
V_DrawRightAlignedThinString(x + 79, y-10, V_REDMAP, savegameinfo[savetodraw].skinname);
|
||||
}
|
||||
else
|
||||
{
|
||||
V_DrawRightAlignedThinString(x + 79, y, V_REDMAP, "CAN'T LOAD!");
|
||||
}
|
||||
}
|
||||
else if (savegameinfo[savetodraw].gamemap & 8192)
|
||||
V_DrawRightAlignedThinString(x + 79, y, V_GREENMAP, "CLEAR!");
|
||||
else
|
||||
|
@ -8665,6 +8913,7 @@ static void M_LoadSelect(INT32 choice)
|
|||
}
|
||||
|
||||
#define VERSIONSIZE 16
|
||||
#define MISSING { savegameinfo[slot].continuescore = -62; savegameinfo[slot].lives = -666; Z_Free(savebuffer); return; }
|
||||
#define BADSAVE { savegameinfo[slot].lives = -666; Z_Free(savebuffer); return; }
|
||||
#define CHECKPOS if (sav_p >= end_p) BADSAVE
|
||||
// Reads the save file to list lives, level, player, etc.
|
||||
|
@ -8761,10 +9010,11 @@ static void M_ReadSavegameInfo(UINT32 slot)
|
|||
CHECKPOS
|
||||
READSTRINGN(sav_p, ourSkinName, SKINNAMESIZE);
|
||||
savegameinfo[slot].skinnum = R_SkinAvailable(ourSkinName);
|
||||
STRBUFCPY(savegameinfo[slot].skinname, ourSkinName);
|
||||
|
||||
if (savegameinfo[slot].skinnum >= numskins
|
||||
|| !R_SkinUsable(-1, savegameinfo[slot].skinnum))
|
||||
BADSAVE
|
||||
MISSING
|
||||
|
||||
CHECKPOS
|
||||
READSTRINGN(sav_p, botSkinName, SKINNAMESIZE);
|
||||
|
@ -8772,7 +9022,7 @@ static void M_ReadSavegameInfo(UINT32 slot)
|
|||
|
||||
if (savegameinfo[slot].botskin-1 >= numskins
|
||||
|| !R_SkinUsable(-1, savegameinfo[slot].botskin-1))
|
||||
BADSAVE
|
||||
MISSING
|
||||
}
|
||||
|
||||
CHECKPOS
|
||||
|
@ -8817,6 +9067,7 @@ static void M_ReadSavegameInfo(UINT32 slot)
|
|||
}
|
||||
#undef CHECKPOS
|
||||
#undef BADSAVE
|
||||
#undef MISSING
|
||||
|
||||
//
|
||||
// M_ReadSaveStrings
|
||||
|
|
|
@ -176,6 +176,7 @@ typedef struct
|
|||
extern menupres_t menupres[NUMMENUTYPES];
|
||||
extern UINT32 prevMenuId;
|
||||
extern UINT32 activeMenuId;
|
||||
extern tic_t shieldprompt_timer; // Show a prompt about the new Shield button for old configs // TODO: 2.3: Remove
|
||||
|
||||
void M_InitMenuPresTables(void);
|
||||
UINT8 M_GetYoungestChildMenu(void);
|
||||
|
@ -421,6 +422,7 @@ typedef struct
|
|||
{
|
||||
char levelname[32];
|
||||
UINT8 skinnum;
|
||||
char skinname [SKINNAMESIZE+1];
|
||||
UINT8 botskin;
|
||||
UINT8 numemeralds;
|
||||
UINT8 numgameovers;
|
||||
|
|
|
@ -560,6 +560,11 @@ void M_FirstLoadConfig(void)
|
|||
COM_BufInsertText(va("exec \"%s\"\n", configfile));
|
||||
// no COM_BufExecute() needed; that does it right away
|
||||
|
||||
// For configs loaded at startup only, check for pre-Shield-button configs // TODO: 2.3: Remove
|
||||
if (GETMAJOREXECVERSION(cv_execversion.value) < 55 // Pre-v2.2.14 configs
|
||||
&& cv_execversion.value != 25) // Make sure that the config exists, too
|
||||
shieldprompt_timer = 1;
|
||||
|
||||
// don't filter anymore vars and don't let this convsvar be changed
|
||||
COM_BufInsertText(va("%s \"%d\"\n", cv_execversion.name, EXECVERSION));
|
||||
CV_ToggleExecVersion(false);
|
||||
|
|
|
@ -21,6 +21,32 @@ void DVector3_Load(dvector3_t *vec, double x, double y, double z)
|
|||
vec->z = z;
|
||||
}
|
||||
|
||||
void DVector3_Copy(dvector3_t *a_o, const dvector3_t *a_i)
|
||||
{
|
||||
memcpy(a_o, a_i, sizeof(dvector3_t));
|
||||
}
|
||||
|
||||
void DVector3_Add(const dvector3_t *a_i, const dvector3_t *a_c, dvector3_t *a_o)
|
||||
{
|
||||
a_o->x = a_i->x + a_c->x;
|
||||
a_o->y = a_i->y + a_c->y;
|
||||
a_o->z = a_i->z + a_c->z;
|
||||
}
|
||||
|
||||
void DVector3_Subtract(const dvector3_t *a_i, const dvector3_t *a_c, dvector3_t *a_o)
|
||||
{
|
||||
a_o->x = a_i->x - a_c->x;
|
||||
a_o->y = a_i->y - a_c->y;
|
||||
a_o->z = a_i->z - a_c->z;
|
||||
}
|
||||
|
||||
void DVector3_Multiply(const dvector3_t *a_i, double a_c, dvector3_t *a_o)
|
||||
{
|
||||
a_o->x = a_i->x * a_c;
|
||||
a_o->y = a_i->y * a_c;
|
||||
a_o->z = a_i->z * a_c;
|
||||
}
|
||||
|
||||
double DVector3_Magnitude(const dvector3_t *a_normal)
|
||||
{
|
||||
double xs = a_normal->x * a_normal->x;
|
||||
|
|
|
@ -19,6 +19,10 @@ typedef struct
|
|||
} dvector3_t;
|
||||
|
||||
void DVector3_Load(dvector3_t *vec, double x, double y, double z);
|
||||
void DVector3_Copy(dvector3_t *a_o, const dvector3_t *a_i);
|
||||
void DVector3_Add(const dvector3_t *a_i, const dvector3_t *a_c, dvector3_t *a_o);
|
||||
void DVector3_Subtract(const dvector3_t *a_i, const dvector3_t *a_c, dvector3_t *a_o);
|
||||
void DVector3_Multiply(const dvector3_t *a_i, double a_c, dvector3_t *a_o);
|
||||
double DVector3_Magnitude(const dvector3_t *a_normal);
|
||||
double DVector3_Normalize(dvector3_t *a_normal);
|
||||
void DVector3_Negate(dvector3_t *a_o);
|
||||
|
|
|
@ -114,6 +114,7 @@ static CV_PossibleValue_t playbackspeed_cons_t[] = {{1, "MIN"}, {10, "MAX"}, {0,
|
|||
consvar_t cv_playbackspeed = CVAR_INIT ("playbackspeed", "1", 0, playbackspeed_cons_t, NULL);
|
||||
|
||||
consvar_t cv_idletime = CVAR_INIT ("idletime", "0", CV_SAVE, CV_Unsigned, NULL);
|
||||
consvar_t cv_idlespectate = CVAR_INIT ("idlespectate", "On", CV_SAVE, CV_OnOff, NULL);
|
||||
consvar_t cv_dedicatedidletime = CVAR_INIT ("dedicatedidletime", "10", CV_SAVE, CV_Unsigned, NULL);
|
||||
|
||||
consvar_t cv_httpsource = CVAR_INIT ("http_source", "", CV_SAVE, NULL, NULL);
|
||||
|
@ -1360,19 +1361,33 @@ static void IdleUpdate(void)
|
|||
if (!server || !netgame)
|
||||
return;
|
||||
|
||||
for (i = 1; i < MAXPLAYERS; i++)
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (cv_idletime.value && playeringame[i] && playernode[i] != UINT8_MAX && !players[i].quittime && !players[i].spectator && !players[i].bot && !IsPlayerAdmin(i) && i != serverplayer && gamestate == GS_LEVEL)
|
||||
if (playeringame[i] && playernode[i] != UINT8_MAX && !players[i].quittime && !players[i].spectator && !players[i].bot && gamestate == GS_LEVEL)
|
||||
{
|
||||
if (players[i].cmd.forwardmove || players[i].cmd.sidemove || players[i].cmd.buttons)
|
||||
players[i].lastinputtime = 0;
|
||||
else
|
||||
players[i].lastinputtime++;
|
||||
|
||||
if (players[i].lastinputtime > (tic_t)cv_idletime.value * TICRATE * 60)
|
||||
if (cv_idletime.value && !IsPlayerAdmin(i) && i != serverplayer && !(players[i].pflags & PF_FINISHED) && players[i].lastinputtime > (tic_t)cv_idletime.value * TICRATE * 60)
|
||||
{
|
||||
players[i].lastinputtime = 0;
|
||||
SendKick(i, KICK_MSG_IDLE | KICK_MSG_KEEP_BODY);
|
||||
if (cv_idlespectate.value && G_GametypeHasSpectators())
|
||||
{
|
||||
changeteam_union NetPacket;
|
||||
UINT16 usvalue;
|
||||
NetPacket.value.l = NetPacket.value.b = 0;
|
||||
NetPacket.packet.newteam = 0;
|
||||
NetPacket.packet.playernum = i;
|
||||
NetPacket.packet.verification = true; // This signals that it's a server change
|
||||
usvalue = SHORT(NetPacket.value.l|NetPacket.value.b);
|
||||
SendNetXCmd(XD_TEAMCHANGE, &usvalue, sizeof(usvalue));
|
||||
}
|
||||
else
|
||||
{
|
||||
SendKick(i, KICK_MSG_IDLE | KICK_MSG_KEEP_BODY);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -73,7 +73,7 @@ extern UINT32 realpingtable[MAXPLAYERS];
|
|||
extern UINT32 playerpingtable[MAXPLAYERS];
|
||||
extern tic_t servermaxping;
|
||||
|
||||
extern consvar_t cv_netticbuffer, cv_resynchattempts, cv_blamecfail, cv_playbackspeed, cv_idletime, cv_dedicatedidletime;
|
||||
extern consvar_t cv_netticbuffer, cv_resynchattempts, cv_blamecfail, cv_playbackspeed, cv_idletime, cv_idlespectate, cv_dedicatedidletime;
|
||||
extern consvar_t cv_httpsource;
|
||||
|
||||
// Used in d_net, the only dependence
|
||||
|
|
|
@ -620,6 +620,7 @@ void D_RegisterServerCommands(void)
|
|||
CV_RegisterVar(&cv_blamecfail);
|
||||
CV_RegisterVar(&cv_dedicatedidletime);
|
||||
CV_RegisterVar(&cv_idletime);
|
||||
CV_RegisterVar(&cv_idlespectate);
|
||||
CV_RegisterVar(&cv_httpsource);
|
||||
|
||||
COM_AddCommand("ping", Command_Ping_f, COM_LUA);
|
||||
|
@ -2510,11 +2511,11 @@ static void MutePlayer(boolean mute)
|
|||
|
||||
if (COM_Argc() < 2)
|
||||
{
|
||||
CONS_Printf(M_GetText("muteplayer <playernum>: mute a player\n"));
|
||||
CONS_Printf(M_GetText("muteplayer <playername/playernum>: mute a player\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
data[0] = atoi(COM_Argv(1));
|
||||
data[0] = nametonum(COM_Argv(1));
|
||||
if (data[0] >= MAXPLAYERS || !playeringame[data[0]])
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("There is no player %u!\n"), (unsigned int)data[0]);
|
||||
|
@ -2603,11 +2604,11 @@ static void Command_ServerTeamChange_f(void)
|
|||
if (COM_Argc() < 3)
|
||||
{
|
||||
if (G_TagGametype())
|
||||
CONS_Printf(M_GetText("serverchangeteam <playernum> <team>: switch player to a new team (%s)\n"), "it, notit, playing, or spectator");
|
||||
CONS_Printf(M_GetText("serverchangeteam <playername/playernum> <team>: switch player to a new team (%s)\n"), "it, notit, playing, or spectator");
|
||||
else if (G_GametypeHasTeams())
|
||||
CONS_Printf(M_GetText("serverchangeteam <playernum> <team>: switch player to a new team (%s)\n"), "red, blue or spectator");
|
||||
CONS_Printf(M_GetText("serverchangeteam <playername/playernum> <team>: switch player to a new team (%s)\n"), "red, blue or spectator");
|
||||
else if (G_GametypeHasSpectators())
|
||||
CONS_Printf(M_GetText("serverchangeteam <playernum> <team>: switch player to a new team (%s)\n"), "spectator or playing");
|
||||
CONS_Printf(M_GetText("serverchangeteam <playername/playernum> <team>: switch player to a new team (%s)\n"), "spectator or playing");
|
||||
else
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("This command cannot be used in this gametype.\n"));
|
||||
return;
|
||||
|
@ -2655,19 +2656,19 @@ static void Command_ServerTeamChange_f(void)
|
|||
if (error)
|
||||
{
|
||||
if (G_TagGametype())
|
||||
CONS_Printf(M_GetText("serverchangeteam <playernum> <team>: switch player to a new team (%s)\n"), "it, notit, playing, or spectator");
|
||||
CONS_Printf(M_GetText("serverchangeteam <playername/playernum> <team>: switch player to a new team (%s)\n"), "it, notit, playing, or spectator");
|
||||
else if (G_GametypeHasTeams())
|
||||
CONS_Printf(M_GetText("serverchangeteam <playernum> <team>: switch player to a new team (%s)\n"), "red, blue or spectator");
|
||||
CONS_Printf(M_GetText("serverchangeteam <playername/playernum> <team>: switch player to a new team (%s)\n"), "red, blue or spectator");
|
||||
else if (G_GametypeHasSpectators())
|
||||
CONS_Printf(M_GetText("serverchangeteam <playernum> <team>: switch player to a new team (%s)\n"), "spectator or playing");
|
||||
CONS_Printf(M_GetText("serverchangeteam <playername/playernum> <team>: switch player to a new team (%s)\n"), "spectator or playing");
|
||||
return;
|
||||
}
|
||||
|
||||
NetPacket.packet.playernum = atoi(COM_Argv(1));
|
||||
NetPacket.packet.playernum = nametonum(COM_Argv(1));
|
||||
|
||||
if (!playeringame[NetPacket.packet.playernum])
|
||||
if (NetPacket.packet.playernum == -1 || !playeringame[NetPacket.packet.playernum])
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("There is no player %d!\n"), NetPacket.packet.playernum);
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("There is no player %s!\n"), COM_Argv(1));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3106,13 +3107,16 @@ static void Command_Verify_f(void)
|
|||
|
||||
if (COM_Argc() != 2)
|
||||
{
|
||||
CONS_Printf(M_GetText("promote <playernum>: give admin privileges to a player\n"));
|
||||
CONS_Printf(M_GetText("promote <playername/playernum>: give admin privileges to a player\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
strlcpy(buf, COM_Argv(1), sizeof (buf));
|
||||
|
||||
playernum = atoi(buf);
|
||||
playernum = nametonum(COM_Argv(1));
|
||||
if (playernum == -1)
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("There is no player %s!\n"), COM_Argv(1));
|
||||
return;
|
||||
}
|
||||
|
||||
temp = buf;
|
||||
|
||||
|
@ -3156,13 +3160,16 @@ static void Command_RemoveAdmin_f(void)
|
|||
|
||||
if (COM_Argc() != 2)
|
||||
{
|
||||
CONS_Printf(M_GetText("demote <playernum>: remove admin privileges from a player\n"));
|
||||
CONS_Printf(M_GetText("demote <playername/playernum>: remove admin privileges from a player\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
strlcpy(buf, COM_Argv(1), sizeof(buf));
|
||||
|
||||
playernum = atoi(buf);
|
||||
playernum = nametonum(COM_Argv(1));
|
||||
if (playernum == -1)
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("There is no player %s!\n"), COM_Argv(1));
|
||||
return;
|
||||
}
|
||||
|
||||
temp = buf;
|
||||
|
||||
|
|
|
@ -317,7 +317,11 @@ init_upnpc_once(struct upnpdata *upnpuserdata)
|
|||
I_OutputMsg(M_GetText("Found UPnP device:\n desc: %s\n st: %s\n"),
|
||||
dev->descURL, dev->st);
|
||||
|
||||
#if (MINIUPNPC_API_VERSION >= 18)
|
||||
UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr), NULL, 0);
|
||||
#else
|
||||
UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
|
||||
#endif
|
||||
I_OutputMsg(M_GetText("Local LAN IP address: %s\n"), lanaddr);
|
||||
descXML = miniwget(dev->descURL, &descXMLsize, scope_id, &status_code);
|
||||
if (descXML)
|
||||
|
|
|
@ -50,6 +50,8 @@ static void Command_Listserv_f(void);
|
|||
|
||||
#endif/*MASTERSERVER*/
|
||||
|
||||
static boolean ServerName_CanChange (const char*);
|
||||
|
||||
static void Update_parameters (void);
|
||||
|
||||
static void MasterServer_OnChange(void);
|
||||
|
@ -61,7 +63,7 @@ static CV_PossibleValue_t masterserver_update_rate_cons_t[] = {
|
|||
};
|
||||
|
||||
consvar_t cv_masterserver = CVAR_INIT ("masterserver", "https://ds.ms.srb2.org/MS/0", CV_SAVE|CV_CALL, NULL, MasterServer_OnChange);
|
||||
consvar_t cv_servername = CVAR_INIT ("servername", "SRB2 server", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT|CV_ALLOWLUA, NULL, Update_parameters);
|
||||
consvar_t cv_servername = CVAR_INIT_WITH_CALLBACKS ("servername", "SRB2 server", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT|CV_ALLOWLUA, NULL, Update_parameters, ServerName_CanChange);
|
||||
|
||||
consvar_t cv_masterserver_update_rate = CVAR_INIT ("masterserver_update_rate", "15", CV_SAVE|CV_CALL|CV_NOINIT, masterserver_update_rate_cons_t, Update_parameters);
|
||||
|
||||
|
@ -497,6 +499,15 @@ Set_api (const char *api)
|
|||
|
||||
#endif/*MASTERSERVER*/
|
||||
|
||||
static boolean ServerName_CanChange(const char* newvalue)
|
||||
{
|
||||
if (strlen(newvalue) < MAXSERVERNAME)
|
||||
return true;
|
||||
|
||||
CONS_Alert(CONS_NOTICE, "The server name must be shorter than %d characters\n", MAXSERVERNAME);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
Update_parameters (void)
|
||||
{
|
||||
|
|
270
src/p_enemy.c
270
src/p_enemy.c
|
@ -54,276 +54,6 @@ static dirtype_t diags[] =
|
|||
DI_NORTHWEST, DI_NORTHEAST, DI_SOUTHWEST, DI_SOUTHEAST
|
||||
};
|
||||
|
||||
//Real Prototypes to A_*
|
||||
void A_Fall(mobj_t *actor);
|
||||
void A_Look(mobj_t *actor);
|
||||
void A_Chase(mobj_t *actor);
|
||||
void A_FaceStabChase(mobj_t *actor);
|
||||
void A_FaceStabRev(mobj_t *actor);
|
||||
void A_FaceStabHurl(mobj_t *actor);
|
||||
void A_FaceStabMiss(mobj_t *actor);
|
||||
void A_StatueBurst(mobj_t *actor);
|
||||
void A_JetJawRoam(mobj_t *actor);
|
||||
void A_JetJawChomp(mobj_t *actor);
|
||||
void A_PointyThink(mobj_t *actor);
|
||||
void A_CheckBuddy(mobj_t *actor);
|
||||
void A_HoodFire(mobj_t *actor);
|
||||
void A_HoodThink(mobj_t *actor);
|
||||
void A_HoodFall(mobj_t *actor);
|
||||
void A_ArrowBonks(mobj_t *actor);
|
||||
void A_SnailerThink(mobj_t *actor);
|
||||
void A_SharpChase(mobj_t *actor);
|
||||
void A_SharpSpin(mobj_t *actor);
|
||||
void A_SharpDecel(mobj_t *actor);
|
||||
void A_CrushstaceanWalk(mobj_t *actor);
|
||||
void A_CrushstaceanPunch(mobj_t *actor);
|
||||
void A_CrushclawAim(mobj_t *actor);
|
||||
void A_CrushclawLaunch(mobj_t *actor);
|
||||
void A_VultureVtol(mobj_t *actor);
|
||||
void A_VultureCheck(mobj_t *actor);
|
||||
void A_VultureHover(mobj_t *actor);
|
||||
void A_VultureBlast(mobj_t *actor);
|
||||
void A_VultureFly(mobj_t *actor);
|
||||
void A_SkimChase(mobj_t *actor);
|
||||
void A_FaceTarget(mobj_t *actor);
|
||||
void A_FaceTracer(mobj_t *actor);
|
||||
void A_LobShot(mobj_t *actor);
|
||||
void A_FireShot(mobj_t *actor);
|
||||
void A_SuperFireShot(mobj_t *actor);
|
||||
void A_BossFireShot(mobj_t *actor);
|
||||
void A_Boss7FireMissiles(mobj_t *actor);
|
||||
void A_Boss1Laser(mobj_t *actor);
|
||||
void A_FocusTarget(mobj_t *actor);
|
||||
void A_Boss4Reverse(mobj_t *actor);
|
||||
void A_Boss4SpeedUp(mobj_t *actor);
|
||||
void A_Boss4Raise(mobj_t *actor);
|
||||
void A_SkullAttack(mobj_t *actor);
|
||||
void A_BossZoom(mobj_t *actor);
|
||||
void A_BossScream(mobj_t *actor);
|
||||
void A_Scream(mobj_t *actor);
|
||||
void A_Pain(mobj_t *actor);
|
||||
void A_1upThinker(mobj_t *actor);
|
||||
void A_MonitorPop(mobj_t *actor);
|
||||
void A_GoldMonitorPop(mobj_t *actor);
|
||||
void A_GoldMonitorRestore(mobj_t *actor);
|
||||
void A_GoldMonitorSparkle(mobj_t *actor);
|
||||
void A_Explode(mobj_t *actor);
|
||||
void A_BossDeath(mobj_t *actor);
|
||||
void A_SetShadowScale(mobj_t *actor);
|
||||
void A_ShadowScream(mobj_t *actor);
|
||||
void A_CustomPower(mobj_t *actor);
|
||||
void A_GiveWeapon(mobj_t *actor);
|
||||
void A_RingBox(mobj_t *actor);
|
||||
void A_Invincibility(mobj_t *actor);
|
||||
void A_SuperSneakers(mobj_t *actor);
|
||||
void A_AwardScore(mobj_t *actor);
|
||||
void A_ExtraLife(mobj_t *actor);
|
||||
void A_GiveShield(mobj_t *actor);
|
||||
void A_GravityBox(mobj_t *actor);
|
||||
void A_ScoreRise(mobj_t *actor);
|
||||
void A_BunnyHop(mobj_t *actor);
|
||||
void A_BubbleSpawn(mobj_t *actor);
|
||||
void A_FanBubbleSpawn(mobj_t *actor);
|
||||
void A_BubbleRise(mobj_t *actor);
|
||||
void A_BubbleCheck(mobj_t *actor);
|
||||
void A_AttractChase(mobj_t *actor);
|
||||
void A_DropMine(mobj_t *actor);
|
||||
void A_FishJump(mobj_t *actor);
|
||||
void A_ThrownRing(mobj_t *actor);
|
||||
void A_SetSolidSteam(mobj_t *actor);
|
||||
void A_UnsetSolidSteam(mobj_t *actor);
|
||||
void A_SignSpin(mobj_t *actor);
|
||||
void A_SignPlayer(mobj_t *actor);
|
||||
void A_OverlayThink(mobj_t *actor);
|
||||
void A_JetChase(mobj_t *actor);
|
||||
void A_JetbThink(mobj_t *actor);
|
||||
void A_JetgShoot(mobj_t *actor);
|
||||
void A_JetgThink(mobj_t *actor);
|
||||
void A_ShootBullet(mobj_t *actor);
|
||||
void A_MinusDigging(mobj_t *actor);
|
||||
void A_MinusPopup(mobj_t *actor);
|
||||
void A_MinusCheck(mobj_t *actor);
|
||||
void A_ChickenCheck(mobj_t *actor);
|
||||
void A_MouseThink(mobj_t *actor);
|
||||
void A_DetonChase(mobj_t *actor);
|
||||
void A_CapeChase(mobj_t *actor);
|
||||
void A_RotateSpikeBall(mobj_t *actor);
|
||||
void A_SlingAppear(mobj_t *actor);
|
||||
void A_UnidusBall(mobj_t *actor);
|
||||
void A_RockSpawn(mobj_t *actor);
|
||||
void A_SetFuse(mobj_t *actor);
|
||||
void A_CrawlaCommanderThink(mobj_t *actor);
|
||||
void A_RingExplode(mobj_t *actor);
|
||||
void A_OldRingExplode(mobj_t *actor);
|
||||
void A_MixUp(mobj_t *actor);
|
||||
void A_RecyclePowers(mobj_t *actor);
|
||||
void A_Boss2TakeDamage(mobj_t *actor);
|
||||
void A_Boss7Chase(mobj_t *actor);
|
||||
void A_GoopSplat(mobj_t *actor);
|
||||
void A_Boss2PogoSFX(mobj_t *actor);
|
||||
void A_Boss2PogoTarget(mobj_t *actor);
|
||||
void A_EggmanBox(mobj_t *actor);
|
||||
void A_TurretFire(mobj_t *actor);
|
||||
void A_SuperTurretFire(mobj_t *actor);
|
||||
void A_TurretStop(mobj_t *actor);
|
||||
void A_SparkFollow(mobj_t *actor);
|
||||
void A_BuzzFly(mobj_t *actor);
|
||||
void A_GuardChase(mobj_t *actor);
|
||||
void A_EggShield(mobj_t *actor);
|
||||
void A_SetReactionTime(mobj_t *actor);
|
||||
void A_Boss1Spikeballs(mobj_t *actor);
|
||||
void A_Boss3TakeDamage(mobj_t *actor);
|
||||
void A_Boss3Path(mobj_t *actor);
|
||||
void A_Boss3ShockThink(mobj_t *actor);
|
||||
void A_Shockwave(mobj_t *actor);
|
||||
void A_LinedefExecute(mobj_t *actor);
|
||||
void A_LinedefExecuteFromArg(mobj_t *actor);
|
||||
void A_PlaySeeSound(mobj_t *actor);
|
||||
void A_PlayAttackSound(mobj_t *actor);
|
||||
void A_PlayActiveSound(mobj_t *actor);
|
||||
void A_SmokeTrailer(mobj_t *actor);
|
||||
void A_SpawnObjectAbsolute(mobj_t *actor);
|
||||
void A_SpawnObjectRelative(mobj_t *actor);
|
||||
void A_ChangeAngleRelative(mobj_t *actor);
|
||||
void A_ChangeAngleAbsolute(mobj_t *actor);
|
||||
void A_RollAngle(mobj_t *actor);
|
||||
void A_ChangeRollAngleRelative(mobj_t *actor);
|
||||
void A_ChangeRollAngleAbsolute(mobj_t *actor);
|
||||
void A_PlaySound(mobj_t *actor);
|
||||
void A_FindTarget(mobj_t *actor);
|
||||
void A_FindTracer(mobj_t *actor);
|
||||
void A_SetTics(mobj_t *actor);
|
||||
void A_SetRandomTics(mobj_t *actor);
|
||||
void A_ChangeColorRelative(mobj_t *actor);
|
||||
void A_ChangeColorAbsolute(mobj_t *actor);
|
||||
void A_Dye(mobj_t *actor);
|
||||
void A_SetTranslation(mobj_t *actor);
|
||||
void A_MoveRelative(mobj_t *actor);
|
||||
void A_MoveAbsolute(mobj_t *actor);
|
||||
void A_Thrust(mobj_t *actor);
|
||||
void A_ZThrust(mobj_t *actor);
|
||||
void A_SetTargetsTarget(mobj_t *actor);
|
||||
void A_SetObjectFlags(mobj_t *actor);
|
||||
void A_SetObjectFlags2(mobj_t *actor);
|
||||
void A_RandomState(mobj_t *actor);
|
||||
void A_RandomStateRange(mobj_t *actor);
|
||||
void A_StateRangeByAngle(mobj_t *actor);
|
||||
void A_StateRangeByParameter(mobj_t *actor);
|
||||
void A_DualAction(mobj_t *actor);
|
||||
void A_RemoteAction(mobj_t *actor);
|
||||
void A_ToggleFlameJet(mobj_t *actor);
|
||||
void A_OrbitNights(mobj_t *actor);
|
||||
void A_GhostMe(mobj_t *actor);
|
||||
void A_SetObjectState(mobj_t *actor);
|
||||
void A_SetObjectTypeState(mobj_t *actor);
|
||||
void A_KnockBack(mobj_t *actor);
|
||||
void A_PushAway(mobj_t *actor);
|
||||
void A_RingDrain(mobj_t *actor);
|
||||
void A_SplitShot(mobj_t *actor);
|
||||
void A_MissileSplit(mobj_t *actor);
|
||||
void A_MultiShot(mobj_t *actor);
|
||||
void A_InstaLoop(mobj_t *actor);
|
||||
void A_Custom3DRotate(mobj_t *actor);
|
||||
void A_SearchForPlayers(mobj_t *actor);
|
||||
void A_CheckRandom(mobj_t *actor);
|
||||
void A_CheckTargetRings(mobj_t *actor);
|
||||
void A_CheckRings(mobj_t *actor);
|
||||
void A_CheckTotalRings(mobj_t *actor);
|
||||
void A_CheckHealth(mobj_t *actor);
|
||||
void A_CheckRange(mobj_t *actor);
|
||||
void A_CheckHeight(mobj_t *actor);
|
||||
void A_CheckTrueRange(mobj_t *actor);
|
||||
void A_CheckThingCount(mobj_t *actor);
|
||||
void A_CheckAmbush(mobj_t *actor);
|
||||
void A_CheckCustomValue(mobj_t *actor);
|
||||
void A_CheckCusValMemo(mobj_t *actor);
|
||||
void A_SetCustomValue(mobj_t *actor);
|
||||
void A_UseCusValMemo(mobj_t *actor);
|
||||
void A_RelayCustomValue(mobj_t *actor);
|
||||
void A_CusValAction(mobj_t *actor);
|
||||
void A_ForceStop(mobj_t *actor);
|
||||
void A_ForceWin(mobj_t *actor);
|
||||
void A_SpikeRetract(mobj_t *actor);
|
||||
void A_InfoState(mobj_t *actor);
|
||||
void A_Repeat(mobj_t *actor);
|
||||
void A_SetScale(mobj_t *actor);
|
||||
void A_RemoteDamage(mobj_t *actor);
|
||||
void A_HomingChase(mobj_t *actor);
|
||||
void A_TrapShot(mobj_t *actor);
|
||||
void A_Boss1Chase(mobj_t *actor);
|
||||
void A_Boss2Chase(mobj_t *actor);
|
||||
void A_Boss2Pogo(mobj_t *actor);
|
||||
void A_BossJetFume(mobj_t *actor);
|
||||
void A_VileTarget(mobj_t *actor);
|
||||
void A_VileAttack(mobj_t *actor);
|
||||
void A_VileFire(mobj_t *actor);
|
||||
void A_BrakChase(mobj_t *actor);
|
||||
void A_BrakFireShot(mobj_t *actor);
|
||||
void A_BrakLobShot(mobj_t *actor);
|
||||
void A_NapalmScatter(mobj_t *actor);
|
||||
void A_SpawnFreshCopy(mobj_t *actor);
|
||||
void A_FlickySpawn(mobj_t *actor);
|
||||
void A_FlickyCenter(mobj_t *actor);
|
||||
void A_FlickyAim(mobj_t *actor);
|
||||
void A_FlickyFly(mobj_t *actor);
|
||||
void A_FlickySoar(mobj_t *actor);
|
||||
void A_FlickyCoast(mobj_t *actor);
|
||||
void A_FlickyHop(mobj_t *actor);
|
||||
void A_FlickyFlounder(mobj_t *actor);
|
||||
void A_FlickyCheck(mobj_t *actor);
|
||||
void A_FlickyHeightCheck(mobj_t *actor);
|
||||
void A_FlickyFlutter(mobj_t *actor);
|
||||
void A_FlameParticle(mobj_t *actor);
|
||||
void A_FadeOverlay(mobj_t *actor);
|
||||
void A_Boss5Jump(mobj_t *actor);
|
||||
void A_LightBeamReset(mobj_t *actor);
|
||||
void A_MineExplode(mobj_t *actor);
|
||||
void A_MineRange(mobj_t *actor);
|
||||
void A_ConnectToGround(mobj_t *actor);
|
||||
void A_SpawnParticleRelative(mobj_t *actor);
|
||||
void A_MultiShotDist(mobj_t *actor);
|
||||
void A_WhoCaresIfYourSonIsABee(mobj_t *actor);
|
||||
void A_ParentTriesToSleep(mobj_t *actor);
|
||||
void A_CryingToMomma(mobj_t *actor);
|
||||
void A_CheckFlags2(mobj_t *actor);
|
||||
void A_Boss5FindWaypoint(mobj_t *actor);
|
||||
void A_DoNPCSkid(mobj_t *actor);
|
||||
void A_DoNPCPain(mobj_t *actor);
|
||||
void A_PrepareRepeat(mobj_t *actor);
|
||||
void A_Boss5ExtraRepeat(mobj_t *actor);
|
||||
void A_Boss5Calm(mobj_t *actor);
|
||||
void A_Boss5CheckOnGround(mobj_t *actor);
|
||||
void A_Boss5CheckFalling(mobj_t *actor);
|
||||
void A_Boss5PinchShot(mobj_t *actor);
|
||||
void A_Boss5MakeItRain(mobj_t *actor);
|
||||
void A_Boss5MakeJunk(mobj_t *actor);
|
||||
void A_LookForBetter(mobj_t *actor);
|
||||
void A_Boss5BombExplode(mobj_t *actor);
|
||||
void A_DustDevilThink(mobj_t *actor);
|
||||
void A_TNTExplode(mobj_t *actor);
|
||||
void A_DebrisRandom(mobj_t *actor);
|
||||
void A_TrainCameo(mobj_t *actor);
|
||||
void A_TrainCameo2(mobj_t *actor);
|
||||
void A_CanarivoreGas(mobj_t *actor);
|
||||
void A_KillSegments(mobj_t *actor);
|
||||
void A_SnapperSpawn(mobj_t *actor);
|
||||
void A_SnapperThinker(mobj_t *actor);
|
||||
void A_SaloonDoorSpawn(mobj_t *actor);
|
||||
void A_MinecartSparkThink(mobj_t *actor);
|
||||
void A_ModuloToState(mobj_t *actor);
|
||||
void A_LavafallRocks(mobj_t *actor);
|
||||
void A_LavafallLava(mobj_t *actor);
|
||||
void A_FallingLavaCheck(mobj_t *actor);
|
||||
void A_FireShrink(mobj_t *actor);
|
||||
void A_SpawnPterabytes(mobj_t *actor);
|
||||
void A_PterabyteHover(mobj_t *actor);
|
||||
void A_RolloutSpawn(mobj_t *actor);
|
||||
void A_RolloutRock(mobj_t *actor);
|
||||
void A_DragonbomberSpawn(mobj_t *actor);
|
||||
void A_DragonWing(mobj_t *actor);
|
||||
void A_DragonSegment(mobj_t *actor);
|
||||
void A_ChangeHeight(mobj_t *actor);
|
||||
|
||||
//for p_enemy.c
|
||||
|
||||
//
|
||||
|
|
|
@ -3786,6 +3786,8 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
|
||||
if (player->powers[pw_carry] == CR_NIGHTSMODE) // NiGHTS damage handling
|
||||
{
|
||||
if (player->powers[pw_flashing])
|
||||
return false;
|
||||
if (!force)
|
||||
{
|
||||
if (source == target)
|
||||
|
@ -3803,6 +3805,10 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
|
||||
if (G_IsSpecialStage(gamemap) && !(damagetype & DMG_DEATHMASK))
|
||||
{
|
||||
if (player->powers[pw_flashing])
|
||||
return false;
|
||||
if (LUA_HookMobjDamage(target, inflictor, source, damage, damagetype))
|
||||
return true;
|
||||
P_SpecialStageDamage(player, inflictor, source);
|
||||
return true;
|
||||
}
|
||||
|
|
34
src/p_map.c
34
src/p_map.c
|
@ -1258,8 +1258,9 @@ static unsigned PIT_DoCheckThing(mobj_t *thing)
|
|||
|
||||
if (tmthing->type != MT_SHELL && tmthing->target && tmthing->target->type == thing->type)
|
||||
{
|
||||
// Don't hit same species as originator.
|
||||
if (thing == tmthing->target)
|
||||
// Don't hit yourself, and if a player, don't hit bots
|
||||
if (thing == tmthing->target
|
||||
|| (thing->player && tmthing->target->player && (thing->player->bot == BOT_2PAI || thing->player->bot == BOT_2PHUMAN)))
|
||||
return CHECKTHING_IGNORE;
|
||||
|
||||
if (thing->type != MT_PLAYER)
|
||||
|
@ -2501,6 +2502,9 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam)
|
|||
|
||||
floatok = false;
|
||||
|
||||
if (dedicated) // this crashes so don't even try it
|
||||
return false;
|
||||
|
||||
if (twodlevel
|
||||
|| (thiscam == &camera && players[displayplayer].mo && (players[displayplayer].mo->flags2 & MF2_TWOD))
|
||||
|| (thiscam == &camera2 && players[secondarydisplayplayer].mo && (players[secondarydisplayplayer].mo->flags2 & MF2_TWOD)))
|
||||
|
@ -3960,23 +3964,25 @@ papercollision:
|
|||
mo->momy = tmymove;
|
||||
}
|
||||
|
||||
const fixed_t tmradius = mo->radius > 8 ? mo->radius : 8;
|
||||
|
||||
do {
|
||||
if (tmxmove > mo->radius) {
|
||||
newx = mo->x + mo->radius;
|
||||
tmxmove -= mo->radius;
|
||||
} else if (tmxmove < -mo->radius) {
|
||||
newx = mo->x - mo->radius;
|
||||
tmxmove += mo->radius;
|
||||
if (tmxmove > tmradius) {
|
||||
newx = mo->x + tmradius;
|
||||
tmxmove -= tmradius;
|
||||
} else if (tmxmove < -tmradius) {
|
||||
newx = mo->x - tmradius;
|
||||
tmxmove += tmradius;
|
||||
} else {
|
||||
newx = mo->x + tmxmove;
|
||||
tmxmove = 0;
|
||||
}
|
||||
if (tmymove > mo->radius) {
|
||||
newy = mo->y + mo->radius;
|
||||
tmymove -= mo->radius;
|
||||
} else if (tmymove < -mo->radius) {
|
||||
newy = mo->y - mo->radius;
|
||||
tmymove += mo->radius;
|
||||
if (tmymove > tmradius) {
|
||||
newy = mo->y + tmradius;
|
||||
tmymove -= tmradius;
|
||||
} else if (tmymove < -tmradius) {
|
||||
newy = mo->y - tmradius;
|
||||
tmymove += tmradius;
|
||||
} else {
|
||||
newy = mo->y + tmymove;
|
||||
tmymove = 0;
|
||||
|
|
27
src/p_mobj.c
27
src/p_mobj.c
|
@ -2246,7 +2246,7 @@ boolean P_ZMovement(mobj_t *mo)
|
|||
else if (!onground)
|
||||
P_SlopeLaunch(mo);
|
||||
}
|
||||
|
||||
|
||||
if (!mo->player && P_CheckDeathPitCollide(mo) && mo->health
|
||||
&& !(mo->flags & MF_NOCLIPHEIGHT) && !(mo->flags2 & MF2_BOSSDEAD))
|
||||
{
|
||||
|
@ -2939,7 +2939,7 @@ boolean P_SceneryZMovement(mobj_t *mo)
|
|||
mo->eflags &= ~MFE_APPLYPMOMZ;
|
||||
}
|
||||
mo->z += mo->momz;
|
||||
|
||||
|
||||
if (!mo->player && P_CheckDeathPitCollide(mo) && mo->health
|
||||
&& !(mo->flags & MF_NOCLIPHEIGHT) && !(mo->flags2 & MF2_BOSSDEAD))
|
||||
{
|
||||
|
@ -3782,7 +3782,7 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
|
|||
|
||||
// always do the gravity bit now, that's simpler
|
||||
// BUT CheckPosition only if wasn't done before.
|
||||
if (!(mobj->eflags & MFE_ONGROUND) || mobj->momz
|
||||
if (mobj->momz
|
||||
|| ((mobj->eflags & MFE_VERTICALFLIP) && mobj->z + mobj->height != mobj->ceilingz)
|
||||
|| (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z != mobj->floorz)
|
||||
|| P_IsObjectInGoop(mobj))
|
||||
|
@ -3795,17 +3795,6 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
|
|||
}
|
||||
else
|
||||
{
|
||||
#if 0 // i don't know why this is here, it's causing a few undesired state glitches, and disabling it doesn't appear to negatively affect the game, but i don't want it gone permanently just in case some obscure bug crops up
|
||||
if (!(mobj->player->powers[pw_carry] == CR_NIGHTSMODE)) // used for drilling
|
||||
mobj->player->pflags &= ~PF_STARTJUMP;
|
||||
mobj->player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE);
|
||||
if (mobj->player->secondjump || mobj->player->powers[pw_tailsfly])
|
||||
{
|
||||
mobj->player->secondjump = 0;
|
||||
mobj->player->powers[pw_tailsfly] = 0;
|
||||
P_SetMobjState(mobj, S_PLAY_WALK);
|
||||
}
|
||||
#endif
|
||||
mobj->eflags &= ~MFE_JUSTHITFLOOR;
|
||||
}
|
||||
|
||||
|
@ -10355,6 +10344,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
case MT_GRENADEPICKUP:
|
||||
if (mobj->health == 0) // Fading tile
|
||||
{
|
||||
// TODO: Maybe use mobj->alpha instead of messing with frame flags
|
||||
INT32 value = mobj->info->damage/10;
|
||||
value = mobj->fuse/value;
|
||||
value = 10-value;
|
||||
|
@ -10700,6 +10690,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, ...)
|
|||
|
||||
// Sprite rendering
|
||||
mobj->blendmode = AST_TRANSLUCENT;
|
||||
mobj->alpha = FRACUNIT;
|
||||
mobj->spritexscale = mobj->spriteyscale = mobj->scale;
|
||||
mobj->spritexoffset = mobj->spriteyoffset = 0;
|
||||
mobj->floorspriteslope = NULL;
|
||||
|
@ -10744,7 +10735,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, ...)
|
|||
|
||||
// Set shadowscale here, before spawn hook so that Lua can change it
|
||||
mobj->shadowscale = P_DefaultMobjShadowScale(mobj);
|
||||
|
||||
|
||||
// A monitor can't respawn if we're not in multiplayer,
|
||||
// or if we're in co-op and it's score or a 1up
|
||||
if (mobj->flags & MF_MONITOR && (!(netgame || multiplayer)
|
||||
|
@ -10760,7 +10751,8 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, ...)
|
|||
// when spawning MT_PLAYER, set mobj->player before calling MobjSpawn hook to prevent P_RemoveMobj from succeeding on player mobj.
|
||||
va_start(args, type);
|
||||
mobj->player = va_arg(args, player_t *);
|
||||
mobj->player->mo = mobj;
|
||||
if (mobj->player)
|
||||
mobj->player->mo = mobj;
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
@ -14302,7 +14294,8 @@ mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zo
|
|||
yofs = FixedMul(yofs, mobj->scale);
|
||||
zofs = FixedMul(zofs, mobj->scale);
|
||||
|
||||
newmobj = P_SpawnMobj(mobj->x + xofs, mobj->y + yofs, mobj->z + zofs, type);
|
||||
newmobj = P_SpawnMobj(mobj->x + xofs, mobj->y + yofs, mobj->z + zofs, type, NULL);
|
||||
|
||||
if (!newmobj)
|
||||
return NULL;
|
||||
|
||||
|
|
|
@ -313,6 +313,7 @@ typedef struct mobj_s
|
|||
|
||||
UINT32 renderflags; // render flags
|
||||
INT32 blendmode; // blend mode
|
||||
fixed_t alpha; // alpha
|
||||
fixed_t spritexscale, spriteyscale;
|
||||
fixed_t spritexoffset, spriteyoffset;
|
||||
fixed_t old_spritexscale, old_spriteyscale, old_spritexscale2, old_spriteyscale2;
|
||||
|
@ -456,6 +457,7 @@ typedef struct precipmobj_s
|
|||
|
||||
UINT32 renderflags; // render flags
|
||||
INT32 blendmode; // blend mode
|
||||
fixed_t alpha; // alpha
|
||||
fixed_t spritexscale, spriteyscale;
|
||||
fixed_t spritexoffset, spriteyoffset;
|
||||
fixed_t old_spritexscale, old_spriteyscale, old_spritexscale2, old_spriteyscale2;
|
||||
|
|
|
@ -919,7 +919,11 @@ enum
|
|||
LD_SDMIDLIGHT = 1<<19,
|
||||
LD_SDBOTLIGHT = 1<<20,
|
||||
LD_SDREPEATCNT = 1<<21,
|
||||
LD_SDFLAGS = 1<<22
|
||||
LD_SDFLAGS = 1<<22,
|
||||
LD_SDLIGHTABS = 1<<23,
|
||||
LD_SDTOPLIGHTABS = 1<<24,
|
||||
LD_SDMIDLIGHTABS = 1<<25,
|
||||
LD_SDBOTLIGHTABS = 1<<26
|
||||
};
|
||||
|
||||
static boolean P_AreArgsEqual(const line_t *li, const line_t *spawnli)
|
||||
|
@ -1393,6 +1397,22 @@ static UINT32 GetSideDiff(const side_t *si, const side_t *spawnsi)
|
|||
diff |= LD_SDBOTSCALEY;
|
||||
if (si->repeatcnt != spawnsi->repeatcnt)
|
||||
diff |= LD_SDREPEATCNT;
|
||||
if (si->light != spawnsi->light)
|
||||
diff |= LD_SDLIGHT;
|
||||
if (si->light_top != spawnsi->light_top)
|
||||
diff |= LD_SDTOPLIGHT;
|
||||
if (si->light_mid != spawnsi->light_mid)
|
||||
diff |= LD_SDMIDLIGHT;
|
||||
if (si->light_bottom != spawnsi->light_bottom)
|
||||
diff |= LD_SDBOTLIGHT;
|
||||
if (si->lightabsolute != spawnsi->lightabsolute)
|
||||
diff |= LD_SDLIGHTABS;
|
||||
if (si->lightabsolute_top != spawnsi->lightabsolute_top)
|
||||
diff |= LD_SDTOPLIGHTABS;
|
||||
if (si->lightabsolute_mid != spawnsi->lightabsolute_mid)
|
||||
diff |= LD_SDMIDLIGHTABS;
|
||||
if (si->lightabsolute_bottom != spawnsi->lightabsolute_bottom)
|
||||
diff |= LD_SDBOTLIGHTABS;
|
||||
return diff;
|
||||
}
|
||||
|
||||
|
@ -1436,6 +1456,22 @@ static void ArchiveSide(const side_t *si, UINT32 diff)
|
|||
WRITEFIXED(save_p, si->scaley_bottom);
|
||||
if (diff & LD_SDREPEATCNT)
|
||||
WRITEINT16(save_p, si->repeatcnt);
|
||||
if (diff & LD_SDLIGHT)
|
||||
WRITEINT16(save_p, si->light);
|
||||
if (diff & LD_SDTOPLIGHT)
|
||||
WRITEINT16(save_p, si->light_top);
|
||||
if (diff & LD_SDMIDLIGHT)
|
||||
WRITEINT16(save_p, si->light_mid);
|
||||
if (diff & LD_SDBOTLIGHT)
|
||||
WRITEINT16(save_p, si->light_bottom);
|
||||
if (diff & LD_SDLIGHTABS)
|
||||
WRITEUINT8(save_p, si->lightabsolute);
|
||||
if (diff & LD_SDTOPLIGHTABS)
|
||||
WRITEUINT8(save_p, si->lightabsolute_top);
|
||||
if (diff & LD_SDMIDLIGHTABS)
|
||||
WRITEUINT8(save_p, si->lightabsolute_mid);
|
||||
if (diff & LD_SDBOTLIGHTABS)
|
||||
WRITEUINT8(save_p, si->lightabsolute_bottom);
|
||||
}
|
||||
|
||||
static void ArchiveLines(void)
|
||||
|
@ -1576,6 +1612,22 @@ static void UnArchiveSide(side_t *si)
|
|||
si->scaley_bottom = READFIXED(save_p);
|
||||
if (diff & LD_SDREPEATCNT)
|
||||
si->repeatcnt = READINT16(save_p);
|
||||
if (diff & LD_SDLIGHT)
|
||||
si->light = READINT16(save_p);
|
||||
if (diff & LD_SDTOPLIGHT)
|
||||
si->light_top = READINT16(save_p);
|
||||
if (diff & LD_SDMIDLIGHT)
|
||||
si->light_mid = READINT16(save_p);
|
||||
if (diff & LD_SDBOTLIGHT)
|
||||
si->light_bottom = READINT16(save_p);
|
||||
if (diff & LD_SDLIGHTABS)
|
||||
si->lightabsolute = READUINT8(save_p);
|
||||
if (diff & LD_SDTOPLIGHTABS)
|
||||
si->lightabsolute_top = READUINT8(save_p);
|
||||
if (diff & LD_SDMIDLIGHTABS)
|
||||
si->lightabsolute_mid = READUINT8(save_p);
|
||||
if (diff & LD_SDBOTLIGHTABS)
|
||||
si->lightabsolute_bottom = READUINT8(save_p);
|
||||
}
|
||||
|
||||
static void UnArchiveLines(void)
|
||||
|
@ -1746,7 +1798,8 @@ typedef enum
|
|||
MD2_DISPOFFSET = 1<<23,
|
||||
MD2_DRAWONLYFORPLAYER = 1<<24,
|
||||
MD2_DONTDRAWFORVIEWMOBJ = 1<<25,
|
||||
MD2_TRANSLATION = 1<<26
|
||||
MD2_TRANSLATION = 1<<26,
|
||||
MD2_ALPHA = 1<<27
|
||||
} mobj_diff2_t;
|
||||
|
||||
typedef enum
|
||||
|
@ -1989,6 +2042,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
|||
diff2 |= MD2_DONTDRAWFORVIEWMOBJ;
|
||||
if (mobj->dispoffset != mobj->info->dispoffset)
|
||||
diff2 |= MD2_DISPOFFSET;
|
||||
if (mobj->alpha != FRACUNIT)
|
||||
diff2 |= MD2_ALPHA;
|
||||
|
||||
if (diff2 != 0)
|
||||
diff |= MD_MORE;
|
||||
|
@ -2172,6 +2227,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
|||
WRITEINT32(save_p, mobj->dispoffset);
|
||||
if (diff2 & MD2_TRANSLATION)
|
||||
WRITEUINT16(save_p, mobj->translation);
|
||||
if (diff2 & MD2_ALPHA)
|
||||
WRITEFIXED(save_p, mobj->alpha);
|
||||
|
||||
WRITEUINT32(save_p, mobj->mobjnum);
|
||||
}
|
||||
|
@ -3238,6 +3295,10 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
|
|||
mobj->dispoffset = mobj->info->dispoffset;
|
||||
if (diff2 & MD2_TRANSLATION)
|
||||
mobj->translation = READUINT16(save_p);
|
||||
if (diff2 & MD2_ALPHA)
|
||||
mobj->alpha = READFIXED(save_p);
|
||||
else
|
||||
mobj->alpha = FRACUNIT;
|
||||
|
||||
if (diff & MD_REDFLAG)
|
||||
{
|
||||
|
|
174
src/p_setup.c
174
src/p_setup.c
|
@ -1367,6 +1367,9 @@ static void P_LoadSidedefs(UINT8 *data)
|
|||
sd->scalex_top = sd->scalex_mid = sd->scalex_bottom = FRACUNIT;
|
||||
sd->scaley_top = sd->scaley_mid = sd->scaley_bottom = FRACUNIT;
|
||||
|
||||
sd->light = sd->light_top = sd->light_mid = sd->light_bottom = 0;
|
||||
sd->lightabsolute = sd->lightabsolute_top = sd->lightabsolute_mid = sd->lightabsolute_bottom = false;
|
||||
|
||||
P_SetSidedefSector(i, (UINT16)SHORT(msd->sector));
|
||||
|
||||
// Special info stored in texture fields!
|
||||
|
@ -1554,11 +1557,41 @@ static void P_LoadThings(UINT8 *data)
|
|||
}
|
||||
|
||||
// Stores positions for relevant map data spread through a TEXTMAP.
|
||||
UINT32 mapthingsPos[UINT16_MAX];
|
||||
UINT32 linesPos[UINT16_MAX];
|
||||
UINT32 sidesPos[UINT16_MAX];
|
||||
UINT32 vertexesPos[UINT16_MAX];
|
||||
UINT32 sectorsPos[UINT16_MAX];
|
||||
typedef struct textmap_block_s
|
||||
{
|
||||
UINT32 *pos;
|
||||
size_t capacity;
|
||||
} textmap_block_t;
|
||||
|
||||
static textmap_block_t mapthingBlocks;
|
||||
static textmap_block_t linedefBlocks;
|
||||
static textmap_block_t sidedefBlocks;
|
||||
static textmap_block_t vertexBlocks;
|
||||
static textmap_block_t sectorBlocks;
|
||||
|
||||
static void TextmapStorePos(textmap_block_t *blocks, size_t *count)
|
||||
{
|
||||
size_t locCount = (*count) + 1;
|
||||
|
||||
if (blocks->pos == NULL)
|
||||
{
|
||||
// Initial capacity (half of the former one.)
|
||||
blocks->capacity = UINT16_MAX / 2;
|
||||
|
||||
Z_Calloc(sizeof(blocks->pos) * blocks->capacity, PU_LEVEL, &blocks->pos);
|
||||
}
|
||||
else if (locCount >= blocks->capacity)
|
||||
{
|
||||
// If we hit the list's capacity, make space for 1024 more blocks
|
||||
blocks->capacity += 1024;
|
||||
|
||||
Z_Realloc(blocks->pos, sizeof(blocks->pos) * blocks->capacity, PU_LEVEL, &blocks->pos);
|
||||
}
|
||||
|
||||
blocks->pos[locCount - 1] = M_TokenizerGetEndPos();
|
||||
|
||||
(*count) = locCount;
|
||||
}
|
||||
|
||||
// Determine total amount of map data in TEXTMAP.
|
||||
static boolean TextmapCount(size_t size)
|
||||
|
@ -1602,15 +1635,15 @@ static boolean TextmapCount(size_t size)
|
|||
brackets++;
|
||||
// Check for valid fields.
|
||||
else if (fastcmp(tkn, "thing"))
|
||||
mapthingsPos[nummapthings++] = M_TokenizerGetEndPos();
|
||||
TextmapStorePos(&mapthingBlocks, &nummapthings);
|
||||
else if (fastcmp(tkn, "linedef"))
|
||||
linesPos[numlines++] = M_TokenizerGetEndPos();
|
||||
TextmapStorePos(&linedefBlocks, &numlines);
|
||||
else if (fastcmp(tkn, "sidedef"))
|
||||
sidesPos[numsides++] = M_TokenizerGetEndPos();
|
||||
TextmapStorePos(&sidedefBlocks, &numsides);
|
||||
else if (fastcmp(tkn, "vertex"))
|
||||
vertexesPos[numvertexes++] = M_TokenizerGetEndPos();
|
||||
TextmapStorePos(&vertexBlocks, &numvertexes);
|
||||
else if (fastcmp(tkn, "sector"))
|
||||
sectorsPos[numsectors++] = M_TokenizerGetEndPos();
|
||||
TextmapStorePos(§orBlocks, &numsectors);
|
||||
else
|
||||
CONS_Alert(CONS_NOTICE, "Unknown field '%s'.\n", tkn);
|
||||
}
|
||||
|
@ -1947,6 +1980,22 @@ static void ParseTextmapSidedefParameter(UINT32 i, const char *param, const char
|
|||
P_SetSidedefSector(i, atol(val));
|
||||
else if (fastcmp(param, "repeatcnt"))
|
||||
sides[i].repeatcnt = atol(val);
|
||||
else if (fastcmp(param, "light"))
|
||||
sides[i].light = atol(val);
|
||||
else if (fastcmp(param, "light_top"))
|
||||
sides[i].light_top = atol(val);
|
||||
else if (fastcmp(param, "light_mid"))
|
||||
sides[i].light_mid = atol(val);
|
||||
else if (fastcmp(param, "light_bottom"))
|
||||
sides[i].light_bottom = atol(val);
|
||||
else if (fastcmp(param, "lightabsolute") && fastcmp("true", val))
|
||||
sides[i].lightabsolute = true;
|
||||
else if (fastcmp(param, "lightabsolute_top") && fastcmp("true", val))
|
||||
sides[i].lightabsolute_top = true;
|
||||
else if (fastcmp(param, "lightabsolute_mid") && fastcmp("true", val))
|
||||
sides[i].lightabsolute_mid = true;
|
||||
else if (fastcmp(param, "lightabsolute_bottom") && fastcmp("true", val))
|
||||
sides[i].lightabsolute_bottom = true;
|
||||
}
|
||||
|
||||
static void ParseTextmapLinedefParameter(UINT32 i, const char *param, const char *val)
|
||||
|
@ -2674,6 +2723,22 @@ static void P_WriteTextmap(void)
|
|||
fprintf(f, "texturemiddle = \"%.*s\";\n", 8, textures[wsides[i].midtexture]->name);
|
||||
if (wsides[i].repeatcnt != 0)
|
||||
fprintf(f, "repeatcnt = %d;\n", wsides[i].repeatcnt);
|
||||
if (wsides[i].light != 0)
|
||||
fprintf(f, "light = %d;\n", wsides[i].light);
|
||||
if (wsides[i].light_top != 0)
|
||||
fprintf(f, "light_top = %d;\n", wsides[i].light_top);
|
||||
if (wsides[i].light_mid != 0)
|
||||
fprintf(f, "light_mid = %d;\n", wsides[i].light_mid);
|
||||
if (wsides[i].light_bottom != 0)
|
||||
fprintf(f, "light_bottom = %d;\n", wsides[i].light_bottom);
|
||||
if (wsides[i].lightabsolute)
|
||||
fprintf(f, "lightabsolute = true;\n");
|
||||
if (wsides[i].lightabsolute_top)
|
||||
fprintf(f, "lightabsolute_top = true;\n");
|
||||
if (wsides[i].lightabsolute_mid)
|
||||
fprintf(f, "lightabsolute_mid = true;\n");
|
||||
if (wsides[i].lightabsolute_bottom)
|
||||
fprintf(f, "lightabsolute_bottom = true;\n");
|
||||
fprintf(f, "}\n");
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
|
@ -2944,7 +3009,7 @@ static void P_LoadTextmap(void)
|
|||
vt->floorzset = vt->ceilingzset = false;
|
||||
vt->floorz = vt->ceilingz = 0;
|
||||
|
||||
TextmapParse(vertexesPos[i], i, ParseTextmapVertexParameter);
|
||||
TextmapParse(vertexBlocks.pos[i], i, ParseTextmapVertexParameter);
|
||||
|
||||
if (vt->x == INT32_MAX)
|
||||
I_Error("P_LoadTextmap: vertex %s has no x value set!\n", sizeu1(i));
|
||||
|
@ -3001,7 +3066,7 @@ static void P_LoadTextmap(void)
|
|||
textmap_planefloor.defined = 0;
|
||||
textmap_planeceiling.defined = 0;
|
||||
|
||||
TextmapParse(sectorsPos[i], i, ParseTextmapSectorParameter);
|
||||
TextmapParse(sectorBlocks.pos[i], i, ParseTextmapSectorParameter);
|
||||
|
||||
P_InitializeSector(sc);
|
||||
if (textmap_colormap.used)
|
||||
|
@ -3050,7 +3115,7 @@ static void P_LoadTextmap(void)
|
|||
ld->sidenum[0] = NO_SIDEDEF;
|
||||
ld->sidenum[1] = NO_SIDEDEF;
|
||||
|
||||
TextmapParse(linesPos[i], i, ParseTextmapLinedefParameter);
|
||||
TextmapParse(linedefBlocks.pos[i], i, ParseTextmapLinedefParameter);
|
||||
|
||||
if (!ld->v1)
|
||||
I_Error("P_LoadTextmap: linedef %s has no v1 value set!\n", sizeu1(i));
|
||||
|
@ -3076,8 +3141,10 @@ static void P_LoadTextmap(void)
|
|||
sd->bottomtexture = R_TextureNumForName("-");
|
||||
sd->sector = NULL;
|
||||
sd->repeatcnt = 0;
|
||||
sd->light = sd->light_top = sd->light_mid = sd->light_bottom = 0;
|
||||
sd->lightabsolute = sd->lightabsolute_top = sd->lightabsolute_mid = sd->lightabsolute_bottom = false;
|
||||
|
||||
TextmapParse(sidesPos[i], i, ParseTextmapSidedefParameter);
|
||||
TextmapParse(sidedefBlocks.pos[i], i, ParseTextmapSidedefParameter);
|
||||
|
||||
if (!sd->sector)
|
||||
I_Error("P_LoadTextmap: sidedef %s has no sector value set!\n", sizeu1(i));
|
||||
|
@ -3101,7 +3168,7 @@ static void P_LoadTextmap(void)
|
|||
memset(mt->stringargs, 0x00, NUMMAPTHINGSTRINGARGS*sizeof(*mt->stringargs));
|
||||
mt->mobj = NULL;
|
||||
|
||||
TextmapParse(mapthingsPos[i], i, ParseTextmapThingParameter);
|
||||
TextmapParse(mapthingBlocks.pos[i], i, ParseTextmapThingParameter);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3419,13 +3486,13 @@ typedef enum {
|
|||
} nodetype_t;
|
||||
|
||||
// Find out the BSP format.
|
||||
static nodetype_t P_GetNodetype(const virtres_t *virt, UINT8 **nodedata)
|
||||
static nodetype_t P_GetNodetype(const virtres_t *virt, UINT8 **nodedata, char signature[4 + 1])
|
||||
{
|
||||
boolean supported[NUMNODETYPES] = {0};
|
||||
nodetype_t nodetype = NT_UNSUPPORTED;
|
||||
char signature[4 + 1];
|
||||
|
||||
*nodedata = NULL;
|
||||
signature[0] = signature[4] = '\0';
|
||||
|
||||
if (udmf)
|
||||
{
|
||||
|
@ -3434,7 +3501,7 @@ static nodetype_t P_GetNodetype(const virtres_t *virt, UINT8 **nodedata)
|
|||
if (virtznodes && virtznodes->size)
|
||||
{
|
||||
*nodedata = virtznodes->data;
|
||||
supported[NT_XGLN] = supported[NT_XGL3] = true;
|
||||
supported[NT_XGLN] = supported[NT_XGL2] = supported[NT_XGL3] = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -3456,9 +3523,9 @@ static nodetype_t P_GetNodetype(const virtres_t *virt, UINT8 **nodedata)
|
|||
virtssectors = vres_Find(virt, "SSECTORS");
|
||||
|
||||
if (virtssectors && virtssectors->size)
|
||||
{ // Possibly GL nodes: NODES ignored, SSECTORS takes precedence as nodes lump, (It is confusing yeah) and has a signature.
|
||||
{ // Possibly GL nodes: NODES ignored, SSECTORS takes precedence as nodes lump (it is confusing, yeah), and has a signature.
|
||||
*nodedata = virtssectors->data;
|
||||
supported[NT_XGLN] = supported[NT_ZGLN] = supported[NT_XGL3] = true;
|
||||
supported[NT_XGLN] = supported[NT_ZGLN] = supported[NT_XGL2] = supported[NT_XGL3] = true;
|
||||
}
|
||||
else
|
||||
{ // Possibly ZDoom extended nodes: SSECTORS is empty, NODES has a signature.
|
||||
|
@ -3478,19 +3545,42 @@ static nodetype_t P_GetNodetype(const virtres_t *virt, UINT8 **nodedata)
|
|||
}
|
||||
|
||||
M_Memcpy(signature, *nodedata, 4);
|
||||
signature[4] = '\0';
|
||||
(*nodedata) += 4;
|
||||
|
||||
if (!strcmp(signature, "XNOD"))
|
||||
nodetype = NT_XNOD;
|
||||
else if (!strcmp(signature, "ZNOD"))
|
||||
nodetype = NT_ZNOD;
|
||||
else if (!strcmp(signature, "XGLN"))
|
||||
nodetype = NT_XGLN;
|
||||
else if (!strcmp(signature, "ZGLN"))
|
||||
nodetype = NT_ZGLN;
|
||||
else if (!strcmp(signature, "XGL3"))
|
||||
nodetype = NT_XGL3;
|
||||
// Identify node format from its starting signature.
|
||||
if (memcmp(&signature[1], "NOD", 3) == 0) // ZDoom extended nodes
|
||||
{
|
||||
if (signature[0] == 'X')
|
||||
{
|
||||
nodetype = NT_XNOD; // Uncompressed
|
||||
}
|
||||
else if (signature[0] == 'Z')
|
||||
{
|
||||
nodetype = NT_ZNOD; // Compressed
|
||||
}
|
||||
}
|
||||
else if (memcmp(&signature[1], "GL", 2) == 0) // GL nodes
|
||||
{
|
||||
switch (signature[0])
|
||||
{
|
||||
case 'X': // Uncompressed
|
||||
switch (signature[3])
|
||||
{
|
||||
case 'N': nodetype = NT_XGLN; break; // GL nodes
|
||||
case '2': nodetype = NT_XGL2; break; // Version 2 GL nodes
|
||||
case '3': nodetype = NT_XGL3; break; // Version 3 GL nodes
|
||||
}
|
||||
break;
|
||||
case 'Z': // Compressed
|
||||
switch (signature[3])
|
||||
{
|
||||
case 'N': nodetype = NT_ZGLN; break; // GL nodes (compressed)
|
||||
case '2': nodetype = NT_ZGL2; break; // Version 2 GL nodes (compressed)
|
||||
case '3': nodetype = NT_ZGL3; break; // Version 3 GL nodes (compressed)
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return supported[nodetype] ? nodetype : NT_UNSUPPORTED;
|
||||
}
|
||||
|
@ -3502,7 +3592,6 @@ static boolean P_LoadExtraVertices(UINT8 **data)
|
|||
UINT32 xtrvrtx = READUINT32((*data));
|
||||
line_t* ld = lines;
|
||||
vertex_t *oldpos = vertexes;
|
||||
ssize_t offset;
|
||||
size_t i;
|
||||
|
||||
if (numvertexes != origvrtx) // If native vertex count doesn't match node original vertex count, bail out (broken data?).
|
||||
|
@ -3517,12 +3606,11 @@ static boolean P_LoadExtraVertices(UINT8 **data)
|
|||
// If extra vertexes were generated, reallocate the vertex array and fix the pointers.
|
||||
numvertexes += xtrvrtx;
|
||||
vertexes = Z_Realloc(vertexes, numvertexes*sizeof(*vertexes), PU_LEVEL, NULL);
|
||||
offset = (size_t)(vertexes - oldpos);
|
||||
|
||||
for (i = 0, ld = lines; i < numlines; i++, ld++)
|
||||
{
|
||||
ld->v1 += offset;
|
||||
ld->v2 += offset;
|
||||
ld->v1 = &vertexes[ld->v1 - oldpos];
|
||||
ld->v2 = &vertexes[ld->v2 - oldpos];
|
||||
}
|
||||
|
||||
// Read extra vertex data.
|
||||
|
@ -3560,6 +3648,7 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype
|
|||
switch (nodetype)
|
||||
{
|
||||
case NT_XGLN:
|
||||
case NT_XGL2:
|
||||
case NT_XGL3:
|
||||
for (m = 0; m < (size_t)subsectors[i].numlines; m++, k++)
|
||||
{
|
||||
|
@ -3571,7 +3660,7 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype
|
|||
|
||||
READUINT32((*data)); // partner, can be ignored by software renderer
|
||||
|
||||
if (nodetype == NT_XGL3)
|
||||
if (nodetype != NT_XGLN)
|
||||
{
|
||||
UINT32 linenum = READUINT32((*data));
|
||||
if (linenum != 0xFFFFFFFF && linenum >= numlines)
|
||||
|
@ -3682,8 +3771,9 @@ static void P_LoadExtendedNodes(UINT8 **data, nodetype_t nodetype)
|
|||
|
||||
static void P_LoadMapBSP(const virtres_t *virt)
|
||||
{
|
||||
char signature[4 + 1];
|
||||
UINT8 *nodedata = NULL;
|
||||
nodetype_t nodetype = P_GetNodetype(virt, &nodedata);
|
||||
nodetype_t nodetype = P_GetNodetype(virt, &nodedata, signature);
|
||||
|
||||
switch (nodetype)
|
||||
{
|
||||
|
@ -3715,6 +3805,7 @@ static void P_LoadMapBSP(const virtres_t *virt)
|
|||
}
|
||||
case NT_XNOD:
|
||||
case NT_XGLN:
|
||||
case NT_XGL2:
|
||||
case NT_XGL3:
|
||||
if (!P_LoadExtraVertices(&nodedata))
|
||||
return;
|
||||
|
@ -3723,10 +3814,13 @@ static void P_LoadMapBSP(const virtres_t *virt)
|
|||
P_LoadExtendedNodes(&nodedata, nodetype);
|
||||
break;
|
||||
default:
|
||||
CONS_Alert(CONS_WARNING, "Unsupported BSP format detected.\n");
|
||||
return;
|
||||
if (isprint(signature[0]) && isprint(signature[1]) && isprint(signature[2]) && isprint(signature[3]))
|
||||
{
|
||||
I_Error("Unsupported BSP format '%s' detected!\n", signature);
|
||||
return;
|
||||
}
|
||||
I_Error("Unknown BSP format detected!\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Split from P_LoadBlockMap for convenience
|
||||
|
|
|
@ -181,8 +181,8 @@ void T_DynamicSlopeLine (dynlineplanethink_t* th)
|
|||
{
|
||||
pslope_t* slope = th->slope;
|
||||
line_t* srcline = th->sourceline;
|
||||
|
||||
fixed_t zdelta;
|
||||
|
||||
fixed_t zdelta, oldoz = slope->o.z;
|
||||
|
||||
switch(th->type) {
|
||||
case DP_FRONTFLOOR:
|
||||
|
@ -209,7 +209,7 @@ void T_DynamicSlopeLine (dynlineplanethink_t* th)
|
|||
return;
|
||||
}
|
||||
|
||||
if (slope->zdelta != FixedDiv(zdelta, th->extent)) {
|
||||
if (slope->zdelta != FixedDiv(zdelta, th->extent) || oldoz != slope->o.z) {
|
||||
slope->zdelta = FixedDiv(zdelta, th->extent);
|
||||
slope->zangle = R_PointToAngle2(0, 0, th->extent, -zdelta);
|
||||
slope->moved = true;
|
||||
|
|
10
src/p_spec.c
10
src/p_spec.c
|
@ -2405,18 +2405,15 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
y = line->args[3] << FRACBITS;
|
||||
z = line->args[4] << FRACBITS;
|
||||
|
||||
P_UnsetThingPosition(mo);
|
||||
mo->x += x;
|
||||
mo->y += y;
|
||||
mo->z += z;
|
||||
P_SetThingPosition(mo);
|
||||
|
||||
P_SetOrigin(mo, mo->x + x, mo->y + y, mo->z + z);
|
||||
|
||||
if (mo->player)
|
||||
{
|
||||
if (bot) // This might put poor Tails in a wall if he's too far behind! D: But okay, whatever! >:3
|
||||
P_SetOrigin(bot, bot->x + x, bot->y + y, bot->z + z);
|
||||
if (splitscreen && mo->player == &players[secondarydisplayplayer] && camera2.chase)
|
||||
{
|
||||
camera2.reset = true;
|
||||
camera2.x += x;
|
||||
camera2.y += y;
|
||||
camera2.z += z;
|
||||
|
@ -2424,6 +2421,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
}
|
||||
else if (camera.chase && mo->player == &players[displayplayer])
|
||||
{
|
||||
camera.reset = true;
|
||||
camera.x += x;
|
||||
camera.y += y;
|
||||
camera.z += z;
|
||||
|
|
14
src/p_user.c
14
src/p_user.c
|
@ -976,6 +976,9 @@ pflags_t P_GetJumpFlags(player_t *player)
|
|||
//
|
||||
boolean P_PlayerInPain(player_t *player)
|
||||
{
|
||||
if (P_MobjWasRemoved(player->mo))
|
||||
return false;
|
||||
|
||||
// no silly, sliding isn't pain
|
||||
if (!(player->pflags & PF_SLIDING) && player->mo->state == &states[player->mo->info->painstate] && player->powers[pw_flashing])
|
||||
return true;
|
||||
|
@ -2078,6 +2081,7 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
|
|||
|
||||
ghost->renderflags = mobj->renderflags;
|
||||
ghost->blendmode = mobj->blendmode;
|
||||
ghost->alpha = mobj->alpha;
|
||||
|
||||
ghost->spritexscale = mobj->spritexscale;
|
||||
ghost->spriteyscale = mobj->spriteyscale;
|
||||
|
@ -8825,6 +8829,8 @@ void P_MovePlayer(player_t *player)
|
|||
player->mo->height = P_GetPlayerSpinHeight(player);
|
||||
atspinheight = true;
|
||||
}
|
||||
else if (player->powers[pw_carry] == CR_PLAYER || player->powers[pw_carry] == CR_PTERABYTE) // You're slightly shorter while being carried
|
||||
player->mo->height = FixedDiv(P_GetPlayerHeight(player), FixedDiv(14*FRACUNIT,10*FRACUNIT));
|
||||
else
|
||||
player->mo->height = P_GetPlayerHeight(player);
|
||||
|
||||
|
@ -12846,9 +12852,9 @@ void P_PlayerAfterThink(player_t *player)
|
|||
else
|
||||
{
|
||||
if (tails->player)
|
||||
P_TryMove(player->mo, tails->x + P_ReturnThrustX(tails, tails->player->drawangle, 4*FRACUNIT), tails->y + P_ReturnThrustY(tails, tails->player->drawangle, 4*FRACUNIT), true);
|
||||
P_TryMove(player->mo, tails->x + P_ReturnThrustX(tails, tails->player->drawangle, 4*tails->scale), tails->y + P_ReturnThrustY(tails, tails->player->drawangle, 4*tails->scale), true);
|
||||
else
|
||||
P_TryMove(player->mo, tails->x + P_ReturnThrustX(tails, tails->angle, 4*FRACUNIT), tails->y + P_ReturnThrustY(tails, tails->angle, 4*FRACUNIT), true);
|
||||
P_TryMove(player->mo, tails->x + P_ReturnThrustX(tails, tails->angle, 4*tails->scale), tails->y + P_ReturnThrustY(tails, tails->angle, 4*tails->scale), true);
|
||||
player->mo->momx = tails->momx;
|
||||
player->mo->momy = tails->momy;
|
||||
player->mo->momz = tails->momz;
|
||||
|
@ -12862,7 +12868,7 @@ void P_PlayerAfterThink(player_t *player)
|
|||
P_SetPlayerAngle(player, player->mo->angle);
|
||||
}
|
||||
|
||||
if (P_AproxDistance(player->mo->x - tails->x, player->mo->y - tails->y) > player->mo->radius)
|
||||
if (P_AproxDistance(player->mo->x - tails->x, player->mo->y - tails->y) > tails->radius)
|
||||
player->powers[pw_carry] = CR_NONE;
|
||||
|
||||
if (player->powers[pw_carry] == CR_PLAYER)
|
||||
|
@ -13083,7 +13089,7 @@ void P_PlayerAfterThink(player_t *player)
|
|||
player->mo->momy = ptera->momy;
|
||||
player->mo->momz = ptera->momz;
|
||||
|
||||
if (P_AproxDistance(player->mo->x - ptera->x - ptera->watertop, player->mo->y - ptera->y - ptera->waterbottom) > player->mo->radius)
|
||||
if (P_AproxDistance(player->mo->x - ptera->x - ptera->watertop, player->mo->y - ptera->y - ptera->waterbottom) > ptera->radius)
|
||||
goto dropoff;
|
||||
|
||||
ptera->watertop >>= 1;
|
||||
|
|
27
src/r_bsp.c
27
src/r_bsp.c
|
@ -230,6 +230,18 @@ static INT32 R_DoorClosed(void)
|
|||
&& (backsector->floorheight <= frontsector->floorheight || curline->sidedef->bottomtexture);
|
||||
}
|
||||
|
||||
static UINT8 R_FloorLightLevel(sector_t *sector, INT16 base_lightlevel)
|
||||
{
|
||||
return max(0, min(255, sector->floorlightlevel +
|
||||
((sector->floorlightabsolute) ? 0 : base_lightlevel)));
|
||||
}
|
||||
|
||||
static UINT8 R_CeilingLightLevel(sector_t *sector, INT16 base_lightlevel)
|
||||
{
|
||||
return max(0, min(255, sector->ceilinglightlevel +
|
||||
((sector->ceilinglightabsolute) ? 0 : base_lightlevel)));
|
||||
}
|
||||
|
||||
//
|
||||
// If player's view height is underneath fake floor, lower the
|
||||
// drawn ceiling to be just under the floor height, and replace
|
||||
|
@ -312,11 +324,11 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
|
|||
tempsec->lightlevel = s->lightlevel;
|
||||
|
||||
if (floorlightlevel)
|
||||
*floorlightlevel = s->floorlightsec == -1 ? (s->floorlightabsolute ? s->floorlightlevel : max(0, min(255, s->lightlevel + s->floorlightlevel)))
|
||||
*floorlightlevel = s->floorlightsec == -1 ? (s->floorlightabsolute ? s->floorlightlevel : max(0, min(255, s->lightlevel + s->floorlightlevel)))
|
||||
: sectors[s->floorlightsec].lightlevel;
|
||||
|
||||
if (ceilinglightlevel)
|
||||
*ceilinglightlevel = s->ceilinglightsec == -1 ? (s->ceilinglightabsolute ? s->ceilinglightlevel : max(0, min(255, s->lightlevel + s->ceilinglightlevel)))
|
||||
*ceilinglightlevel = s->ceilinglightsec == -1 ? (s->ceilinglightabsolute ? s->ceilinglightlevel : max(0, min(255, s->lightlevel + s->ceilinglightlevel)))
|
||||
: sectors[s->ceilinglightsec].lightlevel;
|
||||
}
|
||||
else if (heightsec != -1 && viewz >= sectors[heightsec].ceilingheight
|
||||
|
@ -356,11 +368,11 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
|
|||
tempsec->lightlevel = s->lightlevel;
|
||||
|
||||
if (floorlightlevel)
|
||||
*floorlightlevel = s->floorlightsec == -1 ? (s->floorlightabsolute ? s->floorlightlevel : max(0, min(255, s->lightlevel + s->floorlightlevel)))
|
||||
*floorlightlevel = s->floorlightsec == -1 ? (s->floorlightabsolute ? s->floorlightlevel : max(0, min(255, s->lightlevel + s->floorlightlevel)))
|
||||
: sectors[s->floorlightsec].lightlevel;
|
||||
|
||||
if (ceilinglightlevel)
|
||||
*ceilinglightlevel = s->ceilinglightsec == -1 ? (s->ceilinglightabsolute ? s->ceilinglightlevel : max(0, min(255, s->lightlevel + s->ceilinglightlevel)))
|
||||
*ceilinglightlevel = s->ceilinglightsec == -1 ? (s->ceilinglightabsolute ? s->ceilinglightlevel : max(0, min(255, s->lightlevel + s->ceilinglightlevel)))
|
||||
: sectors[s->ceilinglightsec].lightlevel;
|
||||
}
|
||||
sec = tempsec;
|
||||
|
@ -968,11 +980,10 @@ static void R_Subsector(size_t num)
|
|||
&& ((viewz < heightcheck && (rover->fofflags & FOF_BOTHPLANES || !(rover->fofflags & FOF_INVERTPLANES)))
|
||||
|| (viewz > heightcheck && (rover->fofflags & FOF_BOTHPLANES || rover->fofflags & FOF_INVERTPLANES))))
|
||||
{
|
||||
light = R_GetPlaneLight(frontsector, planecenterz,
|
||||
viewz < heightcheck);
|
||||
light = R_GetPlaneLight(frontsector, planecenterz, viewz < heightcheck);
|
||||
|
||||
ffloor[numffloors].plane = R_FindPlane(rover->master->frontsector, *rover->bottomheight, *rover->bottompic,
|
||||
*frontsector->lightlist[light].lightlevel, *rover->bottomxoffs, *rover->bottomyoffs,
|
||||
R_FloorLightLevel(rover->master->frontsector, *frontsector->lightlist[light].lightlevel), *rover->bottomxoffs, *rover->bottomyoffs,
|
||||
*rover->bottomxscale, *rover->bottomyscale, *rover->bottomangle,
|
||||
*frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->b_slope, NULL);
|
||||
|
||||
|
@ -1002,7 +1013,7 @@ static void R_Subsector(size_t num)
|
|||
light = R_GetPlaneLight(frontsector, planecenterz, viewz < heightcheck);
|
||||
|
||||
ffloor[numffloors].plane = R_FindPlane(rover->master->frontsector, *rover->topheight, *rover->toppic,
|
||||
*frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs,
|
||||
R_CeilingLightLevel(rover->master->frontsector, *frontsector->lightlist[light].lightlevel), *rover->topxoffs, *rover->topyoffs,
|
||||
*rover->topxscale, *rover->topyscale, *rover->topangle,
|
||||
*frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->t_slope, NULL);
|
||||
|
||||
|
|
|
@ -60,6 +60,8 @@ typedef UINT8 lighttable_t;
|
|||
#define CMF_FADEFULLBRIGHTSPRITES 1
|
||||
#define CMF_FOG 4
|
||||
|
||||
#define TEXTURE_255_IS_TRANSPARENT
|
||||
|
||||
// ExtraColormap type. Use for extra_colormaps from now on.
|
||||
typedef struct extracolormap_s
|
||||
{
|
||||
|
@ -358,7 +360,7 @@ typedef struct pslope_s
|
|||
|
||||
double dzdelta;
|
||||
|
||||
boolean moved : 1;
|
||||
boolean moved;
|
||||
|
||||
UINT8 flags; // Slope options
|
||||
} pslope_t;
|
||||
|
@ -631,6 +633,11 @@ typedef struct
|
|||
fixed_t scalex_top, scalex_mid, scalex_bottom;
|
||||
fixed_t scaley_top, scaley_mid, scaley_bottom;
|
||||
|
||||
// per-wall lighting for UDMF
|
||||
// TODO: implement per-texture lighting
|
||||
INT16 light, light_top, light_mid, light_bottom;
|
||||
boolean lightabsolute, lightabsolute_top, lightabsolute_mid, lightabsolute_bottom;
|
||||
|
||||
// Texture indices.
|
||||
// We do not maintain names here.
|
||||
INT32 toptexture, bottomtexture, midtexture;
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include "doomstat.h"
|
||||
#include "r_local.h"
|
||||
#include "r_translation.h"
|
||||
#include "st_stuff.h" // need ST_HEIGHT
|
||||
#include "i_video.h"
|
||||
#include "v_video.h"
|
||||
#include "m_misc.h"
|
||||
|
|
|
@ -154,9 +154,11 @@ void R_VideoErase(size_t ofs, INT32 count);
|
|||
|
||||
void R_DrawColumn_8(void);
|
||||
void R_DrawColumnClamped_8(void);
|
||||
void R_Draw2sMultiPatchColumn_8(void);
|
||||
void R_DrawShadeColumn_8(void);
|
||||
void R_DrawTranslucentColumn_8(void);
|
||||
void R_DrawTranslucentColumnClamped_8(void);
|
||||
void R_Draw2sMultiPatchTranslucentColumn_8(void);
|
||||
void R_DrawDropShadowColumn_8(void);
|
||||
void R_DrawTranslatedColumn_8(void);
|
||||
void R_DrawTranslatedTranslucentColumn_8(void);
|
||||
|
|
183
src/r_draw8.c
183
src/r_draw8.c
|
@ -192,6 +192,189 @@ void R_DrawColumnClamped_8(void)
|
|||
}
|
||||
}
|
||||
|
||||
void R_Draw2sMultiPatchColumn_8(void)
|
||||
{
|
||||
INT32 count;
|
||||
register UINT8 *dest;
|
||||
register fixed_t frac;
|
||||
fixed_t fracstep;
|
||||
|
||||
count = dc_yh - dc_yl;
|
||||
|
||||
if (count < 0) // Zero length, column does not exceed a pixel.
|
||||
return;
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height)
|
||||
return;
|
||||
#endif
|
||||
|
||||
// Framebuffer destination address.
|
||||
dest = &topleft[dc_yl*vid.width + dc_x];
|
||||
|
||||
count++;
|
||||
|
||||
// Determine scaling, which is the only mapping to be done.
|
||||
fracstep = dc_iscale;
|
||||
frac = dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep);
|
||||
|
||||
// Inner loop that does the actual texture mapping, e.g. a DDA-like scaling.
|
||||
// This is as fast as it gets.
|
||||
{
|
||||
register const UINT8 *source = dc_source;
|
||||
register const lighttable_t *colormap = dc_colormap;
|
||||
register INT32 heightmask = dc_texheight-1;
|
||||
register UINT8 val;
|
||||
if (dc_texheight & heightmask) // not a power of 2 -- killough
|
||||
{
|
||||
heightmask++;
|
||||
heightmask <<= FRACBITS;
|
||||
|
||||
if (frac < 0)
|
||||
while ((frac += heightmask) < 0);
|
||||
else
|
||||
while (frac >= heightmask)
|
||||
frac -= heightmask;
|
||||
|
||||
do
|
||||
{
|
||||
// Re-map color indices from wall texture column
|
||||
// using a lighting/special effects LUT.
|
||||
// heightmask is the Tutti-Frutti fix
|
||||
val = source[frac>>FRACBITS];
|
||||
|
||||
if (val != TRANSPARENTPIXEL)
|
||||
*dest = colormap[val];
|
||||
|
||||
dest += vid.width;
|
||||
|
||||
// Avoid overflow.
|
||||
if (fracstep > 0x7FFFFFFF - frac)
|
||||
frac += fracstep - heightmask;
|
||||
else
|
||||
frac += fracstep;
|
||||
|
||||
while (frac >= heightmask)
|
||||
frac -= heightmask;
|
||||
} while (--count);
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((count -= 2) >= 0) // texture height is a power of 2
|
||||
{
|
||||
val = source[(frac>>FRACBITS) & heightmask];
|
||||
if (val != TRANSPARENTPIXEL)
|
||||
*dest = colormap[val];
|
||||
dest += vid.width;
|
||||
frac += fracstep;
|
||||
val = source[(frac>>FRACBITS) & heightmask];
|
||||
if (val != TRANSPARENTPIXEL)
|
||||
*dest = colormap[val];
|
||||
dest += vid.width;
|
||||
frac += fracstep;
|
||||
}
|
||||
if (count & 1)
|
||||
{
|
||||
val = source[(frac>>FRACBITS) & heightmask];
|
||||
if (val != TRANSPARENTPIXEL)
|
||||
*dest = colormap[val];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void R_Draw2sMultiPatchTranslucentColumn_8(void)
|
||||
{
|
||||
INT32 count;
|
||||
register UINT8 *dest;
|
||||
register fixed_t frac;
|
||||
fixed_t fracstep;
|
||||
|
||||
count = dc_yh - dc_yl;
|
||||
|
||||
if (count < 0) // Zero length, column does not exceed a pixel.
|
||||
return;
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height)
|
||||
return;
|
||||
#endif
|
||||
|
||||
// Framebuffer destination address.
|
||||
dest = &topleft[dc_yl*vid.width + dc_x];
|
||||
|
||||
count++;
|
||||
|
||||
// Determine scaling, which is the only mapping to be done.
|
||||
fracstep = dc_iscale;
|
||||
frac = dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep);
|
||||
|
||||
// Inner loop that does the actual texture mapping, e.g. a DDA-like scaling.
|
||||
// This is as fast as it gets.
|
||||
{
|
||||
register const UINT8 *source = dc_source;
|
||||
register const UINT8 *transmap = dc_transmap;
|
||||
register const lighttable_t *colormap = dc_colormap;
|
||||
register INT32 heightmask = dc_texheight-1;
|
||||
register UINT8 val;
|
||||
if (dc_texheight & heightmask) // not a power of 2 -- killough
|
||||
{
|
||||
heightmask++;
|
||||
heightmask <<= FRACBITS;
|
||||
|
||||
if (frac < 0)
|
||||
while ((frac += heightmask) < 0);
|
||||
else
|
||||
while (frac >= heightmask)
|
||||
frac -= heightmask;
|
||||
|
||||
do
|
||||
{
|
||||
// Re-map color indices from wall texture column
|
||||
// using a lighting/special effects LUT.
|
||||
// heightmask is the Tutti-Frutti fix
|
||||
val = source[frac>>FRACBITS];
|
||||
|
||||
if (val != TRANSPARENTPIXEL)
|
||||
*dest = *(transmap + (colormap[val]<<8) + (*dest));
|
||||
|
||||
dest += vid.width;
|
||||
|
||||
// Avoid overflow.
|
||||
if (fracstep > 0x7FFFFFFF - frac)
|
||||
frac += fracstep - heightmask;
|
||||
else
|
||||
frac += fracstep;
|
||||
|
||||
while (frac >= heightmask)
|
||||
frac -= heightmask;
|
||||
} while (--count);
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((count -= 2) >= 0) // texture height is a power of 2
|
||||
{
|
||||
val = source[(frac>>FRACBITS) & heightmask];
|
||||
if (val != TRANSPARENTPIXEL)
|
||||
*dest = *(transmap + (colormap[val]<<8) + (*dest));
|
||||
dest += vid.width;
|
||||
frac += fracstep;
|
||||
val = source[(frac>>FRACBITS) & heightmask];
|
||||
if (val != TRANSPARENTPIXEL)
|
||||
*dest = *(transmap + (colormap[val]<<8) + (*dest));
|
||||
dest += vid.width;
|
||||
frac += fracstep;
|
||||
}
|
||||
if (count & 1)
|
||||
{
|
||||
val = source[(frac>>FRACBITS) & heightmask];
|
||||
if (val != TRANSPARENTPIXEL)
|
||||
*dest = *(transmap + (colormap[val]<<8) + (*dest));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief The R_DrawShadeColumn_8 function
|
||||
Experiment to make software go faster. Taken from the Boom source
|
||||
*/
|
||||
|
|
48
src/r_fps.c
48
src/r_fps.c
|
@ -120,6 +120,19 @@ static vector3_t *R_LerpVector3(const vector3_t *from, const vector3_t *to, fixe
|
|||
return out;
|
||||
}
|
||||
|
||||
static double R_LerpDouble(double from, double to, double frac)
|
||||
{
|
||||
return from + (frac * (to - from));
|
||||
}
|
||||
|
||||
static dvector3_t *R_LerpDVector3(const dvector3_t *from, const dvector3_t *to, double frac, dvector3_t *out)
|
||||
{
|
||||
DVector3_Subtract(to, from, out);
|
||||
DVector3_Multiply(out, frac, out);
|
||||
DVector3_Add(from, out, out);
|
||||
return out;
|
||||
}
|
||||
|
||||
// recalc necessary stuff for mouseaiming
|
||||
// slopes are already calculated for the full possible view (which is 4*viewheight).
|
||||
// 18/08/18: (No it's actually 16*viewheight, thanks Jimita for finding this out)
|
||||
|
@ -497,6 +510,14 @@ void R_CreateInterpolator_DynSlope(thinker_t *thinker, pslope_t *slope)
|
|||
FV2_Copy(&interp->dynslope.bakd, &slope->d);
|
||||
|
||||
interp->dynslope.oldzdelta = interp->dynslope.bakzdelta = slope->zdelta;
|
||||
|
||||
DVector3_Copy(&interp->dynslope.oldorigin, &slope->dorigin);
|
||||
DVector3_Copy(&interp->dynslope.bakorigin, &slope->dorigin);
|
||||
|
||||
DVector3_Copy(&interp->dynslope.oldnormdir, &slope->dnormdir);
|
||||
DVector3_Copy(&interp->dynslope.baknormdir, &slope->dnormdir);
|
||||
|
||||
interp->dynslope.olddzdelta = interp->dynslope.bakdzdelta = slope->dzdelta;
|
||||
}
|
||||
|
||||
void R_InitializeLevelInterpolators(void)
|
||||
|
@ -561,6 +582,21 @@ static void UpdateLevelInterpolatorState(levelinterpolator_t *interp)
|
|||
FV3_Copy(&interp->dynslope.bako, &interp->dynslope.slope->o);
|
||||
FV2_Copy(&interp->dynslope.bakd, &interp->dynslope.slope->d);
|
||||
interp->dynslope.bakzdelta = interp->dynslope.slope->zdelta;
|
||||
|
||||
DVector3_Copy(&interp->dynslope.oldorigin, &interp->dynslope.bakorigin);
|
||||
DVector3_Copy(&interp->dynslope.oldnormdir, &interp->dynslope.baknormdir);
|
||||
interp->dynslope.olddzdelta = interp->dynslope.bakdzdelta;
|
||||
|
||||
if (interp->dynslope.slope->moved)
|
||||
{
|
||||
P_CalculateSlopeVectors(interp->dynslope.slope);
|
||||
|
||||
interp->dynslope.slope->moved = false;
|
||||
}
|
||||
|
||||
DVector3_Copy(&interp->dynslope.bakorigin, &interp->dynslope.slope->dorigin);
|
||||
DVector3_Copy(&interp->dynslope.baknormdir, &interp->dynslope.slope->dnormdir);
|
||||
interp->dynslope.bakdzdelta = interp->dynslope.slope->dzdelta;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -646,7 +682,13 @@ void R_ApplyLevelInterpolators(fixed_t frac)
|
|||
R_LerpVector3(&interp->dynslope.oldo, &interp->dynslope.bako, frac, &interp->dynslope.slope->o);
|
||||
R_LerpVector2(&interp->dynslope.oldd, &interp->dynslope.bakd, frac, &interp->dynslope.slope->d);
|
||||
interp->dynslope.slope->zdelta = R_LerpFixed(interp->dynslope.oldzdelta, interp->dynslope.bakzdelta, frac);
|
||||
interp->dynslope.slope->moved = true;
|
||||
if (rendermode == render_soft)
|
||||
{
|
||||
double dfrac = FixedToDouble(frac);
|
||||
R_LerpDVector3(&interp->dynslope.oldorigin, &interp->dynslope.bakorigin, dfrac, &interp->dynslope.slope->dorigin);
|
||||
R_LerpDVector3(&interp->dynslope.oldnormdir, &interp->dynslope.baknormdir, dfrac, &interp->dynslope.slope->dnormdir);
|
||||
interp->dynslope.slope->dzdelta = R_LerpDouble(interp->dynslope.olddzdelta, interp->dynslope.bakdzdelta, dfrac);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -704,6 +746,10 @@ void R_RestoreLevelInterpolators(void)
|
|||
FV3_Copy(&interp->dynslope.slope->o, &interp->dynslope.bako);
|
||||
FV2_Copy(&interp->dynslope.slope->d, &interp->dynslope.bakd);
|
||||
interp->dynslope.slope->zdelta = interp->dynslope.bakzdelta;
|
||||
|
||||
DVector3_Copy(&interp->dynslope.slope->dorigin, &interp->dynslope.bakorigin);
|
||||
DVector3_Copy(&interp->dynslope.slope->dnormdir, &interp->dynslope.baknormdir);
|
||||
interp->dynslope.slope->dzdelta = interp->dynslope.bakdzdelta;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,6 +115,9 @@ typedef struct levelinterpolator_s {
|
|||
vector3_t oldo, bako;
|
||||
vector2_t oldd, bakd;
|
||||
fixed_t oldzdelta, bakzdelta;
|
||||
dvector3_t oldorigin, bakorigin;
|
||||
dvector3_t oldnormdir, baknormdir;
|
||||
double olddzdelta, bakdzdelta;
|
||||
} dynslope;
|
||||
};
|
||||
} levelinterpolator_t;
|
||||
|
|
|
@ -910,7 +910,7 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
|
||||
if (pl->polyobj->translucency == 0 || (pl->extra_colormap && (pl->extra_colormap->flags & CMF_FOG)))
|
||||
light = (pl->lightlevel >> LIGHTSEGSHIFT);
|
||||
else
|
||||
else // TODO: 2.3: Make transparent polyobject planes always use light level
|
||||
light = LIGHTLEVELS-1;
|
||||
}
|
||||
else
|
||||
|
@ -952,7 +952,7 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
|
||||
if ((spanfunctype == SPANDRAWFUNC_SPLAT) || (pl->extra_colormap && (pl->extra_colormap->flags & CMF_FOG)))
|
||||
light = (pl->lightlevel >> LIGHTSEGSHIFT);
|
||||
else
|
||||
else // TODO: 2.3: Make transparent FOF planes use light level instead of always being fullbright
|
||||
light = LIGHTLEVELS-1;
|
||||
}
|
||||
else if (pl->ffloor->fofflags & FOF_FOG)
|
||||
|
|
165
src/r_segs.c
165
src/r_segs.c
|
@ -94,6 +94,124 @@ transnum_t R_GetLinedefTransTable(fixed_t alpha)
|
|||
return (20*(FRACUNIT - alpha - 1) + FRACUNIT) >> (FRACBITS+1);
|
||||
}
|
||||
|
||||
static UINT8 R_SideLightLevel(side_t *side, INT16 base_lightlevel)
|
||||
{
|
||||
return max(0, min(255, side->light +
|
||||
((side->lightabsolute) ? 0 : base_lightlevel)));
|
||||
}
|
||||
|
||||
/* TODO: implement per-texture lighting
|
||||
static UINT8 R_TopLightLevel(side_t *side, INT16 base_lightlevel)
|
||||
{
|
||||
return max(0, min(255, side->light_top +
|
||||
((side->lightabsolute_top) ? 0 : R_SideLightLevel(side, base_lightlevel))));
|
||||
}
|
||||
|
||||
static UINT8 R_MidLightLevel(side_t *side, INT16 base_lightlevel)
|
||||
{
|
||||
return max(0, min(255, side->light_mid +
|
||||
((side->lightabsolute_mid) ? 0 : R_SideLightLevel(side, base_lightlevel))));
|
||||
}
|
||||
|
||||
static UINT8 R_BottomLightLevel(side_t *side, INT16 base_lightlevel)
|
||||
{
|
||||
return max(0, min(255, side->light_bottom +
|
||||
((side->lightabsolute_bottom) ? 0 : R_SideLightLevel(side, base_lightlevel))));
|
||||
}
|
||||
*/
|
||||
|
||||
// If we have a multi-patch texture on a 2sided wall (rare) then we draw
|
||||
// it using R_DrawColumn, else we draw it using R_DrawMaskedColumn, this
|
||||
// way we don't have to store extra post_t info with each column for
|
||||
// multi-patch textures. They are not normally needed as multi-patch
|
||||
// textures don't have holes in it. At least not for now.
|
||||
static void R_Render2sidedMultiPatchColumn(column_t *column, unsigned lengthcol)
|
||||
{
|
||||
INT32 topscreen, bottomscreen;
|
||||
|
||||
post_t *post = &column->posts[0];
|
||||
if (!post->length)
|
||||
return;
|
||||
|
||||
topscreen = sprtopscreen;
|
||||
bottomscreen = topscreen + spryscale * lengthcol;
|
||||
|
||||
dc_yl = (sprtopscreen+FRACUNIT-1)>>FRACBITS;
|
||||
dc_yh = (bottomscreen-1)>>FRACBITS;
|
||||
|
||||
if (windowtop != INT32_MAX && windowbottom != INT32_MAX)
|
||||
{
|
||||
dc_yl = ((windowtop + FRACUNIT)>>FRACBITS);
|
||||
dc_yh = (windowbottom - 1)>>FRACBITS;
|
||||
}
|
||||
|
||||
if (dc_yh >= mfloorclip[dc_x])
|
||||
dc_yh = mfloorclip[dc_x] - 1;
|
||||
if (dc_yl <= mceilingclip[dc_x])
|
||||
dc_yl = mceilingclip[dc_x] + 1;
|
||||
|
||||
if (dc_yl >= vid.height || dc_yh < 0)
|
||||
return;
|
||||
|
||||
if (dc_yl <= dc_yh && dc_yh < vid.height && dc_yh > 0)
|
||||
{
|
||||
dc_source = column->pixels + post->data_offset;
|
||||
dc_postlength = post->length;
|
||||
|
||||
if (colfunc == colfuncs[BASEDRAWFUNC])
|
||||
(colfuncs[COLDRAWFUNC_TWOSMULTIPATCH])();
|
||||
else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY])
|
||||
(colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS])();
|
||||
else
|
||||
colfunc();
|
||||
}
|
||||
}
|
||||
|
||||
static void R_RenderFlipped2sidedMultiPatchColumn(column_t *column, unsigned lengthcol)
|
||||
{
|
||||
INT32 topscreen, bottomscreen;
|
||||
|
||||
void (*localcolfunc)(void);
|
||||
|
||||
post_t *post = &column->posts[0];
|
||||
if (!post->length)
|
||||
return;
|
||||
|
||||
topscreen = sprtopscreen;
|
||||
bottomscreen = topscreen + spryscale * lengthcol;
|
||||
|
||||
dc_yl = (sprtopscreen+FRACUNIT-1)>>FRACBITS;
|
||||
dc_yh = (bottomscreen-1)>>FRACBITS;
|
||||
|
||||
if (windowtop != INT32_MAX && windowbottom != INT32_MAX)
|
||||
{
|
||||
dc_yl = ((windowtop + FRACUNIT)>>FRACBITS);
|
||||
dc_yh = (windowbottom - 1)>>FRACBITS;
|
||||
}
|
||||
|
||||
if (dc_yh >= mfloorclip[dc_x])
|
||||
dc_yh = mfloorclip[dc_x] - 1;
|
||||
if (dc_yl <= mceilingclip[dc_x])
|
||||
dc_yl = mceilingclip[dc_x] + 1;
|
||||
|
||||
if (dc_yl >= vid.height || dc_yh < 0)
|
||||
return;
|
||||
|
||||
if (dc_yl <= dc_yh && dc_yh < vid.height && dc_yh > 0)
|
||||
{
|
||||
dc_postlength = post->length;
|
||||
|
||||
if (colfunc == colfuncs[BASEDRAWFUNC])
|
||||
localcolfunc = colfuncs[COLDRAWFUNC_TWOSMULTIPATCH];
|
||||
else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY])
|
||||
localcolfunc = colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS];
|
||||
else
|
||||
localcolfunc = colfunc;
|
||||
|
||||
R_DrawFlippedPost(column->pixels + post->data_offset, post->length, localcolfunc);
|
||||
}
|
||||
}
|
||||
|
||||
void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
||||
{
|
||||
size_t pindex;
|
||||
|
@ -181,7 +299,16 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
// Texture must be cached
|
||||
R_CheckTextureCache(texnum);
|
||||
|
||||
if (vertflip) // vertically flipped?
|
||||
// handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures
|
||||
// are not stored per-column with post info in SRB2
|
||||
if (!textures[texnum]->transparency)
|
||||
{
|
||||
if (vertflip) // vertically flipped?
|
||||
colfunc_2s = R_RenderFlipped2sidedMultiPatchColumn;
|
||||
else
|
||||
colfunc_2s = R_Render2sidedMultiPatchColumn;
|
||||
}
|
||||
else if (vertflip) // vertically flipped?
|
||||
colfunc_2s = R_DrawFlippedMaskedColumn;
|
||||
else
|
||||
colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture
|
||||
|
@ -223,7 +350,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
if ((colfunc != colfuncs[COLDRAWFUNC_FUZZY])
|
||||
|| (rlight->flags & FOF_FOG)
|
||||
|| (rlight->extra_colormap && (rlight->extra_colormap->flags & CMF_FOG)))
|
||||
lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT);
|
||||
lightnum = R_SideLightLevel(curline->sidedef, rlight->lightlevel) >> LIGHTSEGSHIFT;
|
||||
else
|
||||
lightnum = LIGHTLEVELS - 1;
|
||||
|
||||
|
@ -241,7 +368,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
{
|
||||
if ((colfunc != colfuncs[COLDRAWFUNC_FUZZY])
|
||||
|| (frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG)))
|
||||
lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT);
|
||||
lightnum = R_SideLightLevel(curline->sidedef, frontsector->lightlevel) >> LIGHTSEGSHIFT;
|
||||
else
|
||||
lightnum = LIGHTLEVELS - 1;
|
||||
|
||||
|
@ -697,9 +824,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
|
||||
// Check if the current light effects the colormap/lightlevel
|
||||
if (pfloor->fofflags & FOF_FOG)
|
||||
rlight->lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT);
|
||||
rlight->lightnum = R_SideLightLevel(curline->sidedef, pfloor->master->frontsector->lightlevel) >> LIGHTSEGSHIFT;
|
||||
else
|
||||
rlight->lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT);
|
||||
rlight->lightnum = R_SideLightLevel(curline->sidedef, rlight->lightlevel) >> LIGHTSEGSHIFT;
|
||||
|
||||
if (pfloor->fofflags & FOF_FOG || rlight->flags & FOF_FOG || (rlight->extra_colormap && (rlight->extra_colormap->flags & CMF_FOG)))
|
||||
;
|
||||
|
@ -717,18 +844,17 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
{
|
||||
// Get correct light level!
|
||||
if ((frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG)))
|
||||
lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT);
|
||||
lightnum = R_SideLightLevel(curline->sidedef, frontsector->lightlevel) >> LIGHTSEGSHIFT;
|
||||
else if (fog)
|
||||
lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT);
|
||||
lightnum = R_SideLightLevel(curline->sidedef, pfloor->master->frontsector->lightlevel) >> LIGHTSEGSHIFT;
|
||||
else if (fuzzy)
|
||||
lightnum = LIGHTLEVELS-1;
|
||||
else
|
||||
lightnum = R_FakeFlat(frontsector, &tempsec, &templight, &templight, false)
|
||||
->lightlevel >> LIGHTSEGSHIFT;
|
||||
lightnum = R_SideLightLevel(curline->sidedef, R_FakeFlat(frontsector, &tempsec, &templight, &templight, false)->lightlevel) >> LIGHTSEGSHIFT;
|
||||
|
||||
if (pfloor->fofflags & FOF_FOG || (frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG)));
|
||||
else if (curline->v1->y == curline->v2->y)
|
||||
lightnum--;
|
||||
lightnum--;
|
||||
else if (curline->v1->x == curline->v2->x)
|
||||
lightnum++;
|
||||
|
||||
|
@ -811,7 +937,16 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
// Texture must be cached
|
||||
R_CheckTextureCache(texnum);
|
||||
|
||||
if (vertflip) // vertically flipped?
|
||||
// handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures
|
||||
// are not stored per-column with post info in SRB2
|
||||
if (!textures[texnum]->transparency)
|
||||
{
|
||||
if (vertflip) // vertically flipped?
|
||||
colfunc_2s = R_RenderFlipped2sidedMultiPatchColumn;
|
||||
else
|
||||
colfunc_2s = R_Render2sidedMultiPatchColumn;
|
||||
}
|
||||
else if (vertflip) // vertically flipped?
|
||||
colfunc_2s = R_DrawRepeatFlippedMaskedColumn;
|
||||
else
|
||||
colfunc_2s = R_DrawRepeatMaskedColumn;
|
||||
|
@ -906,9 +1041,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
{
|
||||
// Otherwise use column drawers with extra checks
|
||||
if (fuzzy)
|
||||
colfunc = R_DrawTranslucentColumnClamped_8;
|
||||
colfunc = colfuncs[COLDRAWFUNC_CLAMPEDTRANS];
|
||||
else
|
||||
colfunc = R_DrawColumnClamped_8;
|
||||
colfunc = colfuncs[COLDRAWFUNC_CLAMPED];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1353,7 +1488,7 @@ static void R_RenderSegLoop (void)
|
|||
for (i = 0; i < dc_numlights; i++)
|
||||
{
|
||||
INT32 lightnum;
|
||||
lightnum = (dc_lightlist[i].lightlevel >> LIGHTSEGSHIFT);
|
||||
lightnum = R_SideLightLevel(curline->sidedef, dc_lightlist[i].lightlevel) >> LIGHTSEGSHIFT;
|
||||
|
||||
if (dc_lightlist[i].extra_colormap)
|
||||
;
|
||||
|
@ -2540,7 +2675,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
// use different light tables
|
||||
// for horizontal / vertical / diagonal
|
||||
// OPTIMIZE: get rid of LIGHTSEGSHIFT globally
|
||||
lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT);
|
||||
lightnum = R_SideLightLevel(curline->sidedef, frontsector->lightlevel) >> LIGHTSEGSHIFT;
|
||||
|
||||
if (curline->v1->y == curline->v2->y)
|
||||
lightnum--;
|
||||
|
|
|
@ -636,6 +636,14 @@ static void R_LoadSkinSprites(UINT16 wadnum, UINT16 *lump, UINT16 *lastlump, ski
|
|||
|
||||
if (skin->sprites[0].numframes == 0)
|
||||
CONS_Alert(CONS_ERROR, M_GetText("No frames found for sprite SPR2_%s\n"), spr2names[0]);
|
||||
|
||||
// TODO: 2.3: Delete
|
||||
memcpy(&skin->sprites_compat[start_spr2],
|
||||
&skin->sprites[start_spr2],
|
||||
sizeof(spritedef_t) * (free_spr2 - start_spr2));
|
||||
memcpy(&skin->sprites_compat[start_spr2 + NUMPLAYERSPRITES],
|
||||
&skin->super.sprites[start_spr2],
|
||||
sizeof(spritedef_t) * (free_spr2 - start_spr2));
|
||||
}
|
||||
|
||||
// returns whether found appropriate property
|
||||
|
|
|
@ -88,6 +88,9 @@ typedef struct
|
|||
spritedef_t sprites[NUMPLAYERSPRITES];
|
||||
spriteinfo_t sprinfo[NUMPLAYERSPRITES];
|
||||
} super;
|
||||
|
||||
// TODO: 2.3: Delete
|
||||
spritedef_t sprites_compat[NUMPLAYERSPRITES * 2];
|
||||
} skin_t;
|
||||
|
||||
/// Externs
|
||||
|
|
|
@ -147,9 +147,9 @@ static void R_DrawFlippedColumnInCache(column_t *column, UINT8 *cache, texpatch_
|
|||
|
||||
if (count > 0)
|
||||
{
|
||||
for (; dest < cache + position + count; --source, is_opaque++)
|
||||
for (; dest < cache + position + count; --source, dest++, is_opaque++)
|
||||
{
|
||||
*dest++ = *source;
|
||||
*dest = *source;
|
||||
*is_opaque = true;
|
||||
}
|
||||
}
|
||||
|
@ -295,7 +295,6 @@ UINT8 *R_GenerateTexture(size_t texnum)
|
|||
UINT16 lumpnum = patch->lump;
|
||||
UINT8 *pdata;
|
||||
softwarepatch_t *realpatch;
|
||||
boolean holey = false;
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
UINT8 header[PNG_HEADER_SIZE];
|
||||
|
@ -310,9 +309,11 @@ UINT8 *R_GenerateTexture(size_t texnum)
|
|||
pdata = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
|
||||
realpatch = (softwarepatch_t *)pdata;
|
||||
|
||||
texture->transparency = false;
|
||||
|
||||
// Check the patch for holes.
|
||||
if (texture->width > SHORT(realpatch->width) || texture->height > SHORT(realpatch->height))
|
||||
holey = true;
|
||||
texture->transparency = true;
|
||||
else
|
||||
{
|
||||
UINT8 *colofs = (UINT8 *)realpatch->columnofs;
|
||||
|
@ -332,12 +333,12 @@ UINT8 *R_GenerateTexture(size_t texnum)
|
|||
col = (doompost_t *)((UINT8 *)col + col->length + 4);
|
||||
}
|
||||
if (y < texture->height)
|
||||
holey = true; // this texture is HOLEy! D:
|
||||
texture->transparency = true; // this texture is HOLEy! D:
|
||||
}
|
||||
}
|
||||
|
||||
// If the patch uses transparency, we have to save it this way.
|
||||
if (holey)
|
||||
if (texture->transparency)
|
||||
{
|
||||
texture->flip = patch->flip;
|
||||
|
||||
|
@ -378,6 +379,15 @@ UINT8 *R_GenerateTexture(size_t texnum)
|
|||
temp_columns = Z_Calloc(sizeof(column_t) * texture->width, PU_STATIC, NULL);
|
||||
temp_block = Z_Calloc(total_pixels, PU_STATIC, NULL);
|
||||
|
||||
#ifdef TEXTURE_255_IS_TRANSPARENT
|
||||
texture->transparency = false;
|
||||
|
||||
// Transparency hack
|
||||
memset(temp_block, TRANSPARENTPIXEL, total_pixels);
|
||||
#else
|
||||
texture->transparency = true;
|
||||
#endif
|
||||
|
||||
for (x = 0; x < texture->width; x++)
|
||||
{
|
||||
column_t *column = &temp_columns[x];
|
||||
|
@ -474,13 +484,27 @@ UINT8 *R_GenerateTexture(size_t texnum)
|
|||
// Now write the columns
|
||||
column_posts = Z_Calloc(sizeof(unsigned) * texture->width, PU_STATIC, NULL);
|
||||
|
||||
#ifdef TEXTURE_255_IS_TRANSPARENT
|
||||
total_posts = texture->width;
|
||||
temp_posts = Z_Realloc(temp_posts, sizeof(post_t) * total_posts, PU_CACHE, NULL);
|
||||
#endif
|
||||
|
||||
for (x = 0; x < texture->width; x++)
|
||||
{
|
||||
post_t *post = NULL;
|
||||
boolean was_opaque = false;
|
||||
|
||||
column_t *column = &temp_columns[x];
|
||||
|
||||
#ifdef TEXTURE_255_IS_TRANSPARENT
|
||||
post = &temp_posts[x];
|
||||
post->topdelta = 0;
|
||||
post->length = texture->height;
|
||||
post->data_offset = 0;
|
||||
column_posts[x] = x;
|
||||
column->num_posts = 1;
|
||||
#else
|
||||
boolean was_opaque = false;
|
||||
|
||||
column_posts[x] = (unsigned)-1;
|
||||
|
||||
for (INT32 y = 0; y < texture->height; y++)
|
||||
|
@ -510,6 +534,7 @@ UINT8 *R_GenerateTexture(size_t texnum)
|
|||
|
||||
post->length++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
blocksize = (sizeof(column_t) * texture->width) + (sizeof(post_t) * total_posts) + (sizeof(UINT8) * total_pixels);
|
||||
|
@ -1154,7 +1179,7 @@ static lumpnum_t W_GetTexPatchLumpNum(const char *name)
|
|||
if (lump == LUMPERROR)
|
||||
{
|
||||
// Use whatever else you can find.
|
||||
return W_GetNumForName(name);
|
||||
return W_CheckNumForPatchName(name);
|
||||
}
|
||||
|
||||
return lump;
|
||||
|
|
|
@ -54,6 +54,7 @@ typedef struct
|
|||
char name[8];
|
||||
UINT32 hash;
|
||||
UINT8 type; // TEXTURETYPE_*
|
||||
boolean transparency;
|
||||
INT16 width, height;
|
||||
UINT8 flip; // 1 = flipx, 2 = flipy, 3 = both
|
||||
void *flat; // The texture, as a flat.
|
||||
|
|
|
@ -996,6 +996,12 @@ UINT8 *R_GetTranslationForThing(mobj_t *mobj, skincolornum_t color, UINT16 trans
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// Based off of R_GetLinedefTransTable
|
||||
transnum_t R_GetThingTransTable(fixed_t alpha, transnum_t transmap)
|
||||
{
|
||||
return (20*(FRACUNIT - ((alpha * (10 - transmap))/10) - 1) + FRACUNIT) >> (FRACBITS+1);
|
||||
}
|
||||
|
||||
//
|
||||
// R_DrawVisSprite
|
||||
// mfloorclip and mceilingclip should also be set.
|
||||
|
@ -1501,6 +1507,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
|
|||
floordiff = abs((isflipped ? interp.height : 0) + interp.z - groundz);
|
||||
|
||||
trans = floordiff / (100*FRACUNIT) + 3;
|
||||
trans = R_GetThingTransTable(thing->alpha, trans);
|
||||
if (trans >= 9) return;
|
||||
|
||||
scalemul = FixedMul(FRACUNIT - floordiff/640, scale);
|
||||
|
@ -2191,6 +2198,11 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
}
|
||||
else
|
||||
trans = 0;
|
||||
|
||||
if ((oldthing->flags2 & MF2_LINKDRAW) && oldthing->tracer)
|
||||
trans = R_GetThingTransTable(oldthing->tracer->alpha, trans);
|
||||
else
|
||||
trans = R_GetThingTransTable(oldthing->alpha, trans);
|
||||
|
||||
// Check if this sprite needs to be rendered like a shadow
|
||||
shadowdraw = (!!(thing->renderflags & RF_SHADOWDRAW) && !(papersprite || splat));
|
||||
|
@ -3652,6 +3664,7 @@ boolean R_ThingVisible (mobj_t *thing)
|
|||
(thing->sprite == SPR_NULL) || // Don't draw null-sprites
|
||||
(thing->flags2 & MF2_DONTDRAW) || // Don't draw MF2_LINKDRAW objects
|
||||
(thing->drawonlyforplayer && thing->drawonlyforplayer != viewplayer) || // Don't draw other players' personal objects
|
||||
(!R_BlendLevelVisible(thing->blendmode, R_GetThingTransTable(thing->alpha, 0))) ||
|
||||
(!P_MobjWasRemoved(r_viewmobj) && (
|
||||
(r_viewmobj == thing) || // Don't draw first-person players or awayviewmobj objects
|
||||
(r_viewmobj->player && r_viewmobj->player->followmobj == thing) || // Don't draw first-person players' followmobj
|
||||
|
|
|
@ -93,6 +93,7 @@ boolean R_ThingIsFullDark (mobj_t *thing);
|
|||
boolean R_ThingIsFlashing (mobj_t *thing);
|
||||
|
||||
UINT8 *R_GetTranslationForThing(mobj_t *mobj, skincolornum_t color, UINT16 translation);
|
||||
transnum_t R_GetThingTransTable(fixed_t alpha, transnum_t transmap);
|
||||
|
||||
void R_ThingOffsetOverlay (mobj_t *thing, fixed_t *outx, fixed_t *outy);
|
||||
|
||||
|
|
|
@ -112,6 +112,10 @@ void SCR_SetDrawFuncs(void)
|
|||
colfuncs[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8;
|
||||
colfuncs[COLDRAWFUNC_SHADOWED] = R_DrawColumnShadowed_8;
|
||||
colfuncs[COLDRAWFUNC_TRANSTRANS] = R_DrawTranslatedTranslucentColumn_8;
|
||||
colfuncs[COLDRAWFUNC_CLAMPED] = R_DrawColumnClamped_8;
|
||||
colfuncs[COLDRAWFUNC_CLAMPEDTRANS] = R_DrawTranslucentColumnClamped_8;
|
||||
colfuncs[COLDRAWFUNC_TWOSMULTIPATCH] = R_Draw2sMultiPatchColumn_8;
|
||||
colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS] = R_Draw2sMultiPatchTranslucentColumn_8;
|
||||
colfuncs[COLDRAWFUNC_FOG] = R_DrawFogColumn_8;
|
||||
|
||||
spanfuncs[SPANDRAWFUNC_TRANS] = R_DrawTranslucentSpan_8;
|
||||
|
|
|
@ -30,10 +30,6 @@
|
|||
#define NUMSCREENS 5
|
||||
#endif
|
||||
|
||||
// Size of statusbar.
|
||||
#define ST_HEIGHT 32
|
||||
#define ST_WIDTH 320
|
||||
|
||||
// used now as a maximum video mode size for extra vesa modes.
|
||||
|
||||
// we try to re-allocate a minimum of buffers for stability of the memory,
|
||||
|
@ -97,6 +93,10 @@ enum
|
|||
COLDRAWFUNC_SHADE,
|
||||
COLDRAWFUNC_SHADOWED,
|
||||
COLDRAWFUNC_TRANSTRANS,
|
||||
COLDRAWFUNC_CLAMPED,
|
||||
COLDRAWFUNC_CLAMPEDTRANS,
|
||||
COLDRAWFUNC_TWOSMULTIPATCH,
|
||||
COLDRAWFUNC_TWOSMULTIPATCHTRANS,
|
||||
COLDRAWFUNC_FOG,
|
||||
|
||||
COLDRAWFUNC_MAX
|
||||
|
|
|
@ -33,8 +33,6 @@ target_compile_options(SRB2SDL2 PRIVATE
|
|||
-Wall
|
||||
-Wno-trigraphs
|
||||
-W # Was controlled by RELAXWARNINGS
|
||||
-pedantic
|
||||
-Wpedantic
|
||||
-Wfloat-equal
|
||||
-Wundef
|
||||
-Wpointer-arith
|
||||
|
|
|
@ -2987,7 +2987,7 @@ static void pathonly(char *s)
|
|||
*/
|
||||
static const char *searchWad(const char *searchDir)
|
||||
{
|
||||
static char tempsw[256] = "";
|
||||
static char tempsw[MAX_WADPATH] = "";
|
||||
filestatus_t fstemp;
|
||||
|
||||
strcpy(tempsw, WADKEYWORD1);
|
||||
|
@ -3003,8 +3003,8 @@ static const char *searchWad(const char *searchDir)
|
|||
|
||||
#define CHECKWADPATH(ret) \
|
||||
do { \
|
||||
I_OutputMsg(",%s", returnWadPath); \
|
||||
if (isWadPathOk(returnWadPath)) \
|
||||
I_OutputMsg(",%s", ret); \
|
||||
if (isWadPathOk(ret)) \
|
||||
return ret; \
|
||||
} while (0)
|
||||
|
||||
|
@ -3033,7 +3033,9 @@ static const char *locateWad(void)
|
|||
#ifndef NOCWD
|
||||
// examine current dir
|
||||
strcpy(returnWadPath, ".");
|
||||
CHECKWADPATH(NULL);
|
||||
I_OutputMsg(",%s", returnWadPath);
|
||||
if (isWadPathOk(returnWadPath))
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
@ -3050,9 +3052,16 @@ static const char *locateWad(void)
|
|||
|
||||
#ifndef NOHOME
|
||||
// find in $HOME
|
||||
I_OutputMsg(",HOME");
|
||||
I_OutputMsg(",HOME/" DEFAULTDIR);
|
||||
if ((envstr = I_GetEnv("HOME")) != NULL)
|
||||
SEARCHWAD(envstr);
|
||||
{
|
||||
char *tmp = malloc(strlen(envstr) + 1 + sizeof(DEFAULTDIR));
|
||||
strcpy(tmp, envstr);
|
||||
strcat(tmp, "/");
|
||||
strcat(tmp, DEFAULTDIR);
|
||||
CHECKWADPATH(tmp);
|
||||
free(tmp);
|
||||
}
|
||||
#endif
|
||||
|
||||
// search paths
|
||||
|
|
|
@ -1706,7 +1706,7 @@ static void Impl_VideoSetupBuffer(void)
|
|||
vid.direct = NULL;
|
||||
if (vid.buffer)
|
||||
free(vid.buffer);
|
||||
vid.buffer = calloc(vid.rowbytes*vid.height, NUMSCREENS);
|
||||
vid.buffer = calloc(NUMSCREENS, vid.rowbytes*vid.height);
|
||||
if (!vid.buffer)
|
||||
{
|
||||
I_Error("%s", M_GetText("Not enough memory for video buffer\n"));
|
||||
|
|
|
@ -582,7 +582,7 @@ boolean Snake_JoyGrabber(void *opaque, event_t *ev)
|
|||
{
|
||||
snake_t *snake = opaque;
|
||||
|
||||
if (ev->type == ev_joystick && ev->key == 0)
|
||||
if (snake != NULL && ev->type == ev_joystick && ev->key == 0)
|
||||
{
|
||||
snake->joyevents[snake->joyeventcount] = ev;
|
||||
snake->joyeventcount++;
|
||||
|
|
Loading…
Reference in a new issue