Merge remote-tracking branch 'public/next' into 2214

This commit is contained in:
Radicalicious 2024-12-13 22:57:48 -06:00
commit 7b7a0727a6
42 changed files with 571 additions and 238 deletions

View file

@ -61,7 +61,7 @@
- - |
# apt_update
echo -e "\e[0Ksection_start:`date +%s`:apt_update[collapsed=true]\r\e[0KUpdating APT listing"
- apt-get update
- timeout 2m apt-get update || timeout 2m apt-get update
- |
# apt_update
echo -e "\e[0Ksection_end:`date +%s`:apt_update\r\e[0K"

View file

@ -1988,7 +1988,7 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth)
if (!var->string)
I_Error("CV_Set: %s no string set!\n", var->name);
#endif
if (!var || !var->string || !value || !stricmp(var->string, value))
if (!var || !var->string || !value || (var->can_change == NULL && !stricmp(var->string, value)))
return; // no changes
if (var->flags & CV_NETVAR)

View file

@ -28,6 +28,12 @@ static inline int lib_freeslot(lua_State *L)
if (!lua_lumploading)
return luaL_error(L, "This function cannot be called from within a hook or coroutine!");
if (!deh_loaded)
{
initfreeslots();
deh_loaded = true;
}
while (n-- > 0)
{
s = Z_StrDup(luaL_checkstring(L,1));

View file

@ -192,7 +192,10 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
INT32 i;
if (!deh_loaded)
{
initfreeslots();
deh_loaded = true;
}
deh_num_warning = 0;
@ -605,14 +608,10 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
if (deh_num_warning)
{
CONS_Printf(M_GetText("%d warning%s in the SOC lump\n"), deh_num_warning, deh_num_warning == 1 ? "" : "s");
if (devparm) {
if (devparm)
I_Error("%s%s",va(M_GetText("%d warning%s in the SOC lump\n"), deh_num_warning, deh_num_warning == 1 ? "" : "s"), M_GetText("See log.txt for details.\n"));
//while (!I_GetKey())
//I_OsPolling();
}
}
deh_loaded = true;
Z_Free(s);
}

View file

@ -114,7 +114,7 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt
polygonArray[polygonArraySize].numVerts = iNumPts;
polygonArray[polygonArraySize].polyFlags = PolyFlags;
polygonArray[polygonArraySize].texture = current_texture;
polygonArray[polygonArraySize].shader = (shader_target != -1) ? HWR_GetShaderFromTarget(shader_target) : shader_target;
polygonArray[polygonArraySize].shader = (shader_target != SHADER_NONE) ? HWR_GetShaderFromTarget(shader_target) : shader_target;
polygonArray[polygonArraySize].horizonSpecial = horizonSpecial;
// default to polygonArraySize so we don't lose order on horizon lines
// (yes, it's supposed to be negative, since we're sorting in that direction)
@ -311,7 +311,6 @@ void HWR_RenderBatches(void)
int nextIndex = polygonIndexArray[polygonReadPos];
if (polygonArray[index].hash != polygonArray[nextIndex].hash)
{
changeState = true;
nextShader = polygonArray[nextIndex].shader;
nextTexture = polygonArray[nextIndex].texture;
nextPolyFlags = polygonArray[nextIndex].polyFlags;
@ -320,14 +319,17 @@ void HWR_RenderBatches(void)
nextTexture = 0;
if (currentShader != nextShader && cv_glshaders.value && gl_shadersavailable)
{
changeState = true;
changeShader = true;
}
if (currentTexture != nextTexture)
{
changeState = true;
changeTexture = true;
}
if (currentPolyFlags != nextPolyFlags)
{
changeState = true;
changePolyFlags = true;
}
if (cv_glshaders.value && gl_shadersavailable)
@ -339,6 +341,7 @@ void HWR_RenderBatches(void)
currentSurfaceInfo.LightInfo.fade_start != nextSurfaceInfo.LightInfo.fade_start ||
currentSurfaceInfo.LightInfo.fade_end != nextSurfaceInfo.LightInfo.fade_end)
{
changeState = true;
changeSurfaceInfo = true;
}
}
@ -346,6 +349,7 @@ void HWR_RenderBatches(void)
{
if (currentSurfaceInfo.PolyColor.rgba != nextSurfaceInfo.PolyColor.rgba)
{
changeState = true;
changeSurfaceInfo = true;
}
}

View file

@ -1258,20 +1258,29 @@ void HWR_SetMapPalette(void)
// Creates a hardware lighttable from the supplied lighttable.
// Returns the id of the hw lighttable, usable in FSurfaceInfo.
UINT32 HWR_CreateLightTable(UINT8 *lighttable)
UINT32 HWR_CreateLightTable(UINT8 *lighttable, RGBA_t *hw_lighttable)
{
UINT32 i, id;
UINT32 i;
RGBA_t *palette = HWR_GetTexturePalette();
RGBA_t *hw_lighttable = Z_Malloc(256 * 32 * sizeof(RGBA_t), PU_STATIC, NULL);
// To make the palette index -> RGBA mapping easier for the shader,
// the hardware lighttable is composed of RGBA colors instead of palette indices.
for (i = 0; i < 256 * 32; i++)
hw_lighttable[i] = palette[lighttable[i]];
id = HWD.pfnCreateLightTable(hw_lighttable);
Z_Free(hw_lighttable);
return id;
return HWD.pfnCreateLightTable(hw_lighttable);
}
// Updates a hardware lighttable of a given id from the supplied lighttable.
void HWR_UpdateLightTable(UINT32 id, UINT8 *lighttable, RGBA_t *hw_lighttable)
{
UINT32 i;
RGBA_t *palette = HWR_GetTexturePalette();
for (i = 0; i < 256 * 32; i++)
hw_lighttable[i] = palette[lighttable[i]];
HWD.pfnUpdateLightTable(id, hw_lighttable);
}
// get hwr lighttable id for colormap, create it if it doesn't already exist
@ -1285,25 +1294,41 @@ UINT32 HWR_GetLightTableID(extracolormap_t *colormap)
default_colormap = true;
}
// create hw lighttable if there isn't one
if (!colormap->gl_lighttable_id)
{
UINT8 *colormap_pointer;
UINT8 *colormap_pointer;
if (default_colormap)
colormap_pointer = colormaps; // don't actually use the data from the "default colormap"
else
colormap_pointer = colormap->colormap;
colormap->gl_lighttable_id = HWR_CreateLightTable(colormap_pointer);
if (default_colormap)
colormap_pointer = colormaps; // don't actually use the data from the "default colormap"
else
colormap_pointer = colormap->colormap;
// create hw lighttable if there isn't one
if (colormap->gl_lighttable.data == NULL)
{
Z_Malloc(256 * 32 * sizeof(RGBA_t), PU_HWRLIGHTTABLEDATA, &colormap->gl_lighttable.data);
}
return colormap->gl_lighttable_id;
// Generate the texture for this light table
if (!colormap->gl_lighttable.id)
{
colormap->gl_lighttable.id = HWR_CreateLightTable(colormap_pointer, colormap->gl_lighttable.data);
}
// Update the texture if it was directly changed by a script
else if (colormap->gl_lighttable.needs_update)
{
HWR_UpdateLightTable(colormap->gl_lighttable.id, colormap_pointer, colormap->gl_lighttable.data);
}
colormap->gl_lighttable.needs_update = false;
return colormap->gl_lighttable.id;
}
// Note: all hardware lighttable ids assigned before this
// call become invalid and must not be used.
void HWR_ClearLightTables(void)
{
Z_FreeTag(PU_HWRLIGHTTABLEDATA);
if (vid.glstate == VID_GL_LIBRARY_LOADED)
HWD.pfnClearLightTables();
}

View file

@ -71,6 +71,7 @@ EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value);
EXPORT void HWRAPI(SetPaletteLookup)(UINT8 *lut);
EXPORT UINT32 HWRAPI(CreateLightTable)(RGBA_t *hw_lighttable);
EXPORT void HWRAPI(UpdateLightTable)(UINT32 id, RGBA_t *hw_lighttable);
EXPORT void HWRAPI(ClearLightTables)(void);
EXPORT void HWRAPI(SetScreenPalette)(RGBA_t *palette);
@ -125,6 +126,7 @@ struct hwdriver_s
SetPaletteLookup pfnSetPaletteLookup;
CreateLightTable pfnCreateLightTable;
UpdateLightTable pfnUpdateLightTable;
ClearLightTables pfnClearLightTables;
SetScreenPalette pfnSetScreenPalette;
};

View file

@ -133,7 +133,8 @@ void HWR_UnlockCachedPatch(GLPatch_t *gpatch);
void HWR_SetPalette(RGBA_t *palette);
void HWR_SetMapPalette(void);
UINT32 HWR_CreateLightTable(UINT8 *lighttable);
UINT32 HWR_CreateLightTable(UINT8 *lighttable, RGBA_t *hw_lighttable);
void HWR_UpdateLightTable(UINT32 id, UINT8 *lighttable, RGBA_t *hw_lighttable);
UINT32 HWR_GetLightTableID(extracolormap_t *colormap);
void HWR_ClearLightTables(void);

View file

@ -881,6 +881,7 @@ static boolean HWR_BlendMidtextureSurface(FSurfaceInfo *pSurf)
static void HWR_RenderMidtexture(INT32 gl_midtexture, float cliplow, float cliphigh, fixed_t worldtop, fixed_t worldbottom, fixed_t worldhigh, fixed_t worldlow, fixed_t worldtopslope, fixed_t worldbottomslope, fixed_t worldhighslope, fixed_t worldlowslope, UINT32 lightnum, FOutVector *inWallVerts)
{
sector_t *front, *back;
FOutVector wallVerts[4];
FSurfaceInfo Surf;
@ -890,6 +891,16 @@ static void HWR_RenderMidtexture(INT32 gl_midtexture, float cliplow, float cliph
if (!HWR_BlendMidtextureSurface(&Surf))
return;
if (gl_linedef->frontsector->heightsec != -1)
front = &sectors[gl_linedef->frontsector->heightsec];
else
front = gl_linedef->frontsector;
if (gl_linedef->backsector->heightsec != -1)
back = &sectors[gl_linedef->backsector->heightsec];
else
back = gl_linedef->backsector;
fixed_t texheight = FixedDiv(textureheight[gl_midtexture], abs(gl_sidedef->scaley_mid));
INT32 repeats;
@ -899,15 +910,15 @@ static void HWR_RenderMidtexture(INT32 gl_midtexture, float cliplow, float cliph
{
fixed_t high, low;
if (gl_frontsector->ceilingheight > gl_backsector->ceilingheight)
high = gl_backsector->ceilingheight;
if (front->ceilingheight > back->ceilingheight)
high = back->ceilingheight;
else
high = gl_frontsector->ceilingheight;
high = front->ceilingheight;
if (gl_frontsector->floorheight > gl_backsector->floorheight)
low = gl_frontsector->floorheight;
if (front->floorheight > back->floorheight)
low = front->floorheight;
else
low = gl_backsector->floorheight;
low = back->floorheight;
repeats = (high - low) / texheight;
if ((high - low) % texheight)
@ -934,8 +945,8 @@ static void HWR_RenderMidtexture(INT32 gl_midtexture, float cliplow, float cliph
if (gl_curline->polyseg)
{
// Change this when polyobjects support slopes
popentop = popentopslope = gl_curline->backsector->ceilingheight;
popenbottom = popenbottomslope = gl_curline->backsector->floorheight;
popentop = popentopslope = back->ceilingheight;
popenbottom = popenbottomslope = back->floorheight;
}
else
{
@ -1608,7 +1619,7 @@ static void HWR_ProcessSeg(void)
{
blendmode = PF_Masked;
if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend)
if ((rover->fofflags & FOF_TRANSLUCENT && !((rover->fofflags & FOF_SPLAT) && rover->alpha >= 255)) || rover->blend)
{
blendmode = rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent;
Surf.PolyColor.s.alpha = max(0, min(rover->alpha, 255));
@ -1765,7 +1776,7 @@ static void HWR_ProcessSeg(void)
{
blendmode = PF_Masked;
if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend)
if ((rover->fofflags & FOF_TRANSLUCENT && !((rover->fofflags & FOF_SPLAT) && rover->alpha >= 255)) || rover->blend)
{
blendmode = rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent;
Surf.PolyColor.s.alpha = max(0, min(rover->alpha, 255));
@ -2419,7 +2430,7 @@ static void HWR_Subsector(size_t num)
if (gl_frontsector->cullheight)
{
if (HWR_DoCulling(gl_frontsector->cullheight, viewsector->cullheight, gl_viewz, FIXED_TO_FLOAT(bottomCullHeight), FIXED_TO_FLOAT(topCullHeight)))
if (HWR_DoCulling(gl_frontsector->cullheight, viewsector->cullheight, gl_viewz, FIXED_TO_FLOAT(*rover->bottomheight), FIXED_TO_FLOAT(*rover->topheight)))
continue;
}
@ -2446,7 +2457,7 @@ static void HWR_Subsector(size_t num)
alpha, rover->master->frontsector, PF_Fog|PF_NoTexture,
true, false, rover->master->frontsector->extra_colormap);
}
else if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend) // SoM: Flags are more efficient
else if ((rover->fofflags & FOF_TRANSLUCENT && !((rover->fofflags & FOF_SPLAT) && rover->alpha >= 255)) || rover->blend) // SoM: Flags are more efficient
{
light = R_GetPlaneLight(gl_frontsector, centerHeight, viewz < bottomCullHeight ? true : false);
@ -2492,7 +2503,7 @@ static void HWR_Subsector(size_t num)
alpha, rover->master->frontsector, PF_Fog|PF_NoTexture,
true, false, rover->master->frontsector->extra_colormap);
}
else if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend)
else if ((rover->fofflags & FOF_TRANSLUCENT && !((rover->fofflags & FOF_SPLAT) && rover->alpha >= 255)) || rover->blend)
{
light = R_GetPlaneLight(gl_frontsector, centerHeight, viewz < topCullHeight ? true : false);

View file

@ -3257,6 +3257,24 @@ EXPORT UINT32 HWRAPI(CreateLightTable)(RGBA_t *hw_lighttable)
return item->id;
}
EXPORT void HWRAPI(UpdateLightTable)(UINT32 id, RGBA_t *hw_lighttable)
{
LTListItem *item = LightTablesHead;
while (item && item->id != id)
item = item->next;
if (item)
{
pglBindTexture(GL_TEXTURE_2D, item->id);
// Just update it
pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 32, GL_RGBA, GL_UNSIGNED_BYTE, hw_lighttable);
// restore previously bound texture
pglBindTexture(GL_TEXTURE_2D, tex_downloaded);
}
}
// Delete light table textures, ids given before become invalid and must not be used.
EXPORT void HWRAPI(ClearLightTables)(void)
{

View file

@ -593,7 +593,7 @@ static int extracolormap_set(lua_State *L)
|| exc->fadergba != old_fade_rgba
|| exc->fadestart != old_fade_start
|| exc->fadeend != old_fade_end)
R_GenerateLightTable(exc, true);
R_UpdateLightTable(exc, true);
return 0;
}

View file

@ -72,6 +72,7 @@ automatically.
X (MusicChange),\
X (PlayerHeight),/* override player height */\
X (PlayerCanEnterSpinGaps),\
X (AddonLoaded),\
X (KeyDown),\
X (KeyUp),\

View file

@ -198,12 +198,12 @@ static int mobj_get(lua_State *L)
enum mobj_e field = Lua_optoption(L, 2, -1, mobj_fields_ref);
lua_settop(L, 2);
if (!mo || !ISINLEVEL) {
if (P_MobjWasRemoved(mo) || !ISINLEVEL) {
if (field == mobj_valid) {
lua_pushboolean(L, 0);
return 1;
}
if (!mo) {
if (P_MobjWasRemoved(mo)) {
return LUA_ErrInvalid(L, "mobj_t");
} else
return luaL_error(L, "Do not access an mobj_t field outside a level!");

View file

@ -3401,7 +3401,7 @@ boolean M_Responder(event_t *ev)
{
// ignore ev_keydown events if the key maps to a character, since
// the ev_text event will follow immediately after in that case.
if (ev->type == ev_keydown && ch >= 32 && ch <= 127)
if (ev->type == ev_keydown && ((ch >= 32 && ch <= 127) || (ch >= KEY_KEYPAD7 && ch <= KEY_KPADDEL)))
return true;
routine(ch);
@ -12195,15 +12195,6 @@ static void M_HandleConnectIP(INT32 choice)
setupm_ip[l] = (char)choice;
setupm_ip[l+1] = 0;
}
else if (choice >= 199 && choice <= 211 && choice != 202 && choice != 206) //numpad too!
{
char keypad_translation[] = {'7','8','9','-','4','5','6','+','1','2','3','0','.'};
choice = keypad_translation[choice - 199];
S_StartSound(NULL,sfx_menu1); // Tails
setupm_ip[l] = (char)choice;
setupm_ip[l+1] = 0;
}
break;
}

View file

@ -67,8 +67,6 @@ INT16 hardware_MAXPACKETLENGTH;
boolean (*I_NetGet)(void) = NULL;
void (*I_NetSend)(void) = NULL;
boolean (*I_NetCanSend)(void) = NULL;
boolean (*I_NetCanGet)(void) = NULL;
void (*I_NetCloseSocket)(void) = NULL;
void (*I_NetFreeNodenum)(INT32 nodenum) = NULL;
SINT8 (*I_NetMakeNodewPort)(const char *address, const char* port) = NULL;
@ -993,15 +991,7 @@ boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlen
netbuffer->ackreturn = 0;
if (reliable)
{
if (I_NetCanSend && !I_NetCanSend())
{
if (netbuffer->packettype < PT_CANFAIL)
GetFreeAcknum(&netbuffer->ack, true);
DEBFILE("HSendPacket: Out of bandwidth\n");
return false;
}
else if (!GetFreeAcknum(&netbuffer->ack, false))
if (!GetFreeAcknum(&netbuffer->ack, false))
return false;
}
else
@ -1153,7 +1143,7 @@ static void Internal_FreeNodenum(INT32 nodenum)
char *I_NetSplitAddress(char *host, char **port)
{
boolean v4 = (strchr(host, '.') != NULL);
boolean v4 = (host[0] != '[');
host = strtok(host, v4 ? ":" : "[]");
@ -1205,7 +1195,6 @@ boolean D_CheckNetGame(void)
I_NetGet = Internal_Get;
I_NetSend = Internal_Send;
I_NetCanSend = NULL;
I_NetCloseSocket = NULL;
I_NetFreeNodenum = Internal_FreeNodenum;
I_NetMakeNodewPort = NULL;
@ -1375,7 +1364,6 @@ void D_CloseConnection(void)
I_NetGet = Internal_Get;
I_NetSend = Internal_Send;
I_NetCanSend = NULL;
I_NetCloseSocket = NULL;
I_NetFreeNodenum = Internal_FreeNodenum;
I_NetMakeNodewPort = NULL;

View file

@ -4910,11 +4910,13 @@ static void Name2_OnChange(void)
static boolean Skin_CanChange(const char *valstr)
{
(void)valstr;
if (!Playing())
return true; // do whatever you want
// You already are that skin.
if (stricmp(skins[players[consoleplayer].skin]->name, valstr) == 0)
return false;
if (!(multiplayer || netgame)) // In single player.
return true;
@ -4929,11 +4931,13 @@ static boolean Skin_CanChange(const char *valstr)
static boolean Skin2_CanChange(const char *valstr)
{
(void)valstr;
if (!Playing() || !splitscreen)
return true; // do whatever you want
// You already are that skin.
if (stricmp(skins[players[secondarydisplayplayer].skin]->name, valstr) == 0)
return false;
if (CanChangeSkin(secondarydisplayplayer) && !P_PlayerMoving(secondarydisplayplayer))
return true;
else

View file

@ -67,18 +67,10 @@ extern doomcom_t *doomcom;
*/
extern boolean (*I_NetGet)(void);
/** \brief ask to driver if there is data waiting
*/
extern boolean (*I_NetCanGet)(void);
/** \brief send packet within doomcom struct
*/
extern void (*I_NetSend)(void);
/** \brief ask to driver if all is ok to send data now
*/
extern boolean (*I_NetCanSend)(void);
/** \brief close a connection
\param nodenum node to be closed

View file

@ -143,7 +143,6 @@ typedef union
#endif
#include "i_addrinfo.h"
#define SELECTTEST
#define DEFAULTPORT "5029"
#ifdef USE_WINSOCK
@ -631,56 +630,6 @@ static boolean SOCK_Get(void)
return false;
}
// check if we can send (do not go over the buffer)
static fd_set masterset;
#ifdef SELECTTEST
static boolean FD_CPY(fd_set *src, fd_set *dst, SOCKET_TYPE *fd, size_t len)
{
boolean testset = false;
FD_ZERO(dst);
for (size_t i = 0; i < len;i++)
{
if(fd[i] != (SOCKET_TYPE)ERRSOCKET &&
FD_ISSET(fd[i], src) && !FD_ISSET(fd[i], dst)) // no checking for dups
{
FD_SET(fd[i], dst);
testset = true;
}
}
return testset;
}
static boolean SOCK_CanSend(void)
{
struct timeval timeval_for_select = {0, 0};
fd_set tset;
int wselect;
if(!FD_CPY(&masterset, &tset, mysockets, mysocketses))
return false;
wselect = select(255, NULL, &tset, NULL, &timeval_for_select);
if (wselect >= 1)
return true;
return false;
}
static boolean SOCK_CanGet(void)
{
struct timeval timeval_for_select = {0, 0};
fd_set tset;
int rselect;
if(!FD_CPY(&masterset, &tset, mysockets, mysocketses))
return false;
rselect = select(255, &tset, NULL, NULL, &timeval_for_select);
if (rselect >= 1)
return true;
return false;
}
#endif
static inline ssize_t SOCK_SendToAddr(SOCKET_TYPE socket, mysockaddr_t *sockaddr)
{
socklen_t d4 = (socklen_t)sizeof(struct sockaddr_in);
@ -922,7 +871,6 @@ static boolean UDP_Socket(void)
mysockets[s] = ERRSOCKET;
for (s = 0; s < MAXNETNODES+1; s++)
nodesocket[s] = ERRSOCKET;
FD_ZERO(&masterset);
s = 0;
memset(&hints, 0x00, sizeof (hints));
@ -949,7 +897,6 @@ static boolean UDP_Socket(void)
mysockets[s] = UDP_Bind(runp->ai_family, runp->ai_addr, (socklen_t)runp->ai_addrlen);
if (mysockets[s] != (SOCKET_TYPE)ERRSOCKET)
{
FD_SET(mysockets[s], &masterset);
myfamily[s] = hints.ai_family;
s++;
}
@ -970,7 +917,6 @@ static boolean UDP_Socket(void)
mysockets[s] = UDP_Bind(runp->ai_family, runp->ai_addr, (socklen_t)runp->ai_addrlen);
if (mysockets[s] != (SOCKET_TYPE)ERRSOCKET)
{
FD_SET(mysockets[s], &masterset);
myfamily[s] = hints.ai_family;
s++;
#ifdef HAVE_MINIUPNPC
@ -1003,7 +949,6 @@ static boolean UDP_Socket(void)
mysockets[s] = UDP_Bind(runp->ai_family, runp->ai_addr, (socklen_t)runp->ai_addrlen);
if (mysockets[s] != (SOCKET_TYPE)ERRSOCKET)
{
FD_SET(mysockets[s], &masterset);
myfamily[s] = hints.ai_family;
s++;
}
@ -1024,7 +969,6 @@ static boolean UDP_Socket(void)
mysockets[s] = UDP_Bind(runp->ai_family, runp->ai_addr, (socklen_t)runp->ai_addrlen);
if (mysockets[s] != (SOCKET_TYPE)ERRSOCKET)
{
FD_SET(mysockets[s], &masterset);
myfamily[s] = hints.ai_family;
s++;
}
@ -1150,16 +1094,13 @@ boolean I_InitTcpDriver(void)
static void SOCK_CloseSocket(void)
{
for (size_t i=0; i < MAXNETNODES+1; i++)
for (size_t i=0; i < mysocketses; i++)
{
if (mysockets[i] != (SOCKET_TYPE)ERRSOCKET
&& FD_ISSET(mysockets[i], &masterset))
{
FD_CLR(mysockets[i], &masterset);
if (mysockets[i] != (SOCKET_TYPE)ERRSOCKET)
close(mysockets[i]);
}
mysockets[i] = ERRSOCKET;
}
mysocketses = 0;
}
void I_ShutdownTcpDriver(void)
@ -1211,11 +1152,7 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
// test ip address of server
for (i = 0; i < mysocketses; ++i)
{
/* sendto tests that there is a network to this
address */
if (runp->ai_addr->sa_family == myfamily[i] &&
sendto(mysockets[i], NULL, 0, 0,
runp->ai_addr, runp->ai_addrlen) == 0)
if (runp->ai_addr->sa_family == myfamily[i])
{
memcpy(&clientaddress[newnode], runp->ai_addr, runp->ai_addrlen);
break;
@ -1245,12 +1182,6 @@ static boolean SOCK_OpenSocket(void)
I_NetFreeNodenum = SOCK_FreeNodenum;
I_NetMakeNodewPort = SOCK_NetMakeNodewPort;
#ifdef SELECTTEST
// seem like not work with libsocket : (
I_NetCanSend = SOCK_CanSend;
I_NetCanGet = SOCK_CanGet;
#endif
// build the socket but close it first
SOCK_CloseSocket();
return UDP_Socket();
@ -1273,7 +1204,7 @@ static boolean SOCK_Ban(INT32 node)
else if (banned[numbans].any.sa_family == AF_INET6)
{
banned[numbans].ip6.sin6_port = 0;
bannedmask[numbans] = 128;
bannedmask[numbans] = 64;
}
#endif
numbans++;
@ -1310,7 +1241,7 @@ static boolean SOCK_SetBanAddress(const char *address, const char *mask)
bannedmask[numbans] = (UINT8)atoi(mask);
#ifdef HAVE_IPV6
else if (runp->ai_family == AF_INET6)
bannedmask[numbans] = 128;
bannedmask[numbans] = 64;
#endif
else
bannedmask[numbans] = 32;
@ -1319,7 +1250,7 @@ static boolean SOCK_SetBanAddress(const char *address, const char *mask)
bannedmask[numbans] = 32;
#ifdef HAVE_IPV6
else if (bannedmask[numbans] > 128 && runp->ai_family == AF_INET6)
bannedmask[numbans] = 128;
bannedmask[numbans] = 64;
#endif
numbans++;
runp = runp->ai_next;

View file

@ -14395,7 +14395,7 @@ void A_LavafallLava(mobj_t *actor)
if (LUA_CallAction(A_LAVAFALLLAVA, actor))
return;
if ((40 - actor->fuse) % (2*(actor->scale >> FRACBITS)))
if ((40 - actor->fuse) % max(2*(actor->scale >> FRACBITS), 1)) // avoid crashes if actor->scale < FRACUNIT
return;
// Don't spawn lava unless a player is nearby.

View file

@ -836,7 +836,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
{
clientGamedata->collected[special->health-1] = true;
M_UpdateUnlockablesAndExtraEmblems(clientGamedata);
G_SaveGameData(clientGamedata);
if (!prevCollected) // don't thrash the disk and wreak performance.
G_SaveGameData(clientGamedata);
}
if (netgame)

View file

@ -90,7 +90,7 @@ static void P_SetupStateAnimation(mobj_t *mobj, state_t *st)
if (mobj->sprite == SPR_PLAY && mobj->skin)
{
spritedef_t *spritedef = P_GetSkinSpritedef(mobj->skin, mobj->sprite2);
animlength = (INT32)(spritedef->numframes);
animlength = (INT32)(spritedef->numframes) - 1;
}
else
animlength = st->var1;

View file

@ -5239,8 +5239,8 @@ static void P_NetArchiveSectorPortals(save_t *save_p)
UINT8 type = secportals[i].type;
P_WriteUINT8(save_p, type);
P_WriteFixed(save_p, secportals[i].origin.x);
P_WriteFixed(save_p, secportals[i].origin.y);
P_WriteUINT8(save_p, secportals[i].ceiling ? 1 : 0);
P_WriteUINT32(save_p, SaveSector(secportals[i].target));
switch (type)
{
@ -5255,8 +5255,8 @@ static void P_NetArchiveSectorPortals(save_t *save_p)
P_WriteUINT32(save_p, SaveSector(secportals[i].sector));
break;
case SECPORTAL_OBJECT:
if (secportals[i].mobj && !P_MobjWasRemoved(secportals[i].mobj))
SaveMobjnum(secportals[i].mobj);
if (!P_MobjWasRemoved(secportals[i].mobj))
P_WriteUINT32(save_p, SaveMobjnum(secportals[i].mobj));
else
P_WriteUINT32(save_p, 0);
break;
@ -5283,8 +5283,8 @@ static void P_NetUnArchiveSectorPortals(save_t *save_p)
sectorportal_t *secportal = &secportals[id];
secportal->type = P_ReadUINT8(save_p);
secportal->origin.x = P_ReadFixed(save_p);
secportal->origin.y = P_ReadFixed(save_p);
secportal->ceiling = (P_ReadUINT8(save_p) != 0) ? true : false;
secportal->target = LoadSector(P_ReadUINT32(save_p));
switch (secportal->type)
{

View file

@ -7645,20 +7645,20 @@ static void P_InitCamera(void)
CV_SetValue(&cv_analog[1], 0);
displayplayer = consoleplayer; // Start with your OWN view, please!
}
if (twodlevel)
{
CV_SetValue(&cv_analog[0], false);
CV_SetValue(&cv_analog[1], false);
}
else
{
if (cv_useranalog[0].value)
CV_SetValue(&cv_analog[0], true);
if (twodlevel)
{
CV_SetValue(&cv_analog[0], false);
CV_SetValue(&cv_analog[1], false);
}
else
{
if (cv_useranalog[0].value)
CV_SetValue(&cv_analog[0], true);
if ((splitscreen && cv_useranalog[1].value) || botingame)
CV_SetValue(&cv_analog[1], true);
if ((splitscreen && cv_useranalog[1].value) || botingame)
CV_SetValue(&cv_analog[1], true);
}
}
}
@ -8002,6 +8002,9 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
// Free GPU textures before freeing patches.
if (rendermode == render_opengl && (vid.glstate == VID_GL_LIBRARY_LOADED))
HWR_ClearAllTextures();
// Delete light table textures
HWR_ClearLightTables();
#endif
Patch_FreeTag(PU_PATCH_LOWPRIORITY);

View file

@ -6236,7 +6236,7 @@ static void P_DoPortalCopyFromLine(sector_t *dest_sector, int plane_type, int ta
}
}
static sectorportal_t *P_SectorGetPortalOrCreate(sector_t *sector, UINT32 *num, UINT32 *result)
static sectorportal_t *P_SectorGetPortalOrCreate(sector_t *sector, UINT32 *num, UINT32 *result, boolean ceiling)
{
sectorportal_t *secportal = NULL;
@ -6244,8 +6244,8 @@ static sectorportal_t *P_SectorGetPortalOrCreate(sector_t *sector, UINT32 *num,
{
*num = P_NewSectorPortal();
secportal = &secportals[*num];
secportal->origin.x = sector->soundorg.x;
secportal->origin.y = sector->soundorg.y;
secportal->target = sector;
secportal->ceiling = ceiling;
*result = *num;
}
else
@ -6259,12 +6259,12 @@ static sectorportal_t *P_SectorGetPortalOrCreate(sector_t *sector, UINT32 *num,
static sectorportal_t *P_SectorGetFloorPortalOrCreate(sector_t *sector, UINT32 *result)
{
return P_SectorGetPortalOrCreate(sector, &sector->portal_floor, result);
return P_SectorGetPortalOrCreate(sector, &sector->portal_floor, result, false);
}
static sectorportal_t *P_SectorGetCeilingPortalOrCreate(sector_t *sector, UINT32 *result)
{
return P_SectorGetPortalOrCreate(sector, &sector->portal_ceiling, result);
return P_SectorGetPortalOrCreate(sector, &sector->portal_ceiling, result, true);
}
static void P_CopySectorPortalToLines(UINT32 portal_num, int sector_tag)

View file

@ -426,9 +426,6 @@ void R_ClearColormaps(void)
{
// Purged by PU_LEVEL, just overwrite the pointer
extra_colormaps = R_CreateDefaultColormap(true);
#ifdef HWRENDER
HWR_ClearLightTables();
#endif
}
//
@ -849,6 +846,15 @@ void R_GenerateLightTable(extracolormap_t *extra_colormap, boolean uselookup)
}
}
void R_UpdateLightTable(extracolormap_t *extra_colormap, boolean uselookup)
{
R_GenerateLightTable(extra_colormap, uselookup);
#ifdef HWRENDER
extra_colormap->gl_lighttable.needs_update = true;
#endif
}
extracolormap_t *R_CreateColormapFromLinedef(char *p1, char *p2, char *p3)
{
// default values

View file

@ -90,6 +90,7 @@ typedef enum
} textmapcolormapflags_t;
void R_GenerateLightTable(extracolormap_t *extra_colormap, boolean uselookup);
void R_UpdateLightTable(extracolormap_t *extra_colormap, boolean uselookup);
lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap);
extracolormap_t * R_CreateColormapFromLinedef(char *p1, char *p2, char *p3);
extracolormap_t* R_CreateColormap(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 flags);

View file

@ -76,8 +76,11 @@ typedef struct extracolormap_s
lighttable_t *colormap;
#ifdef HWRENDER
// The id of the hardware lighttable. Zero means it does not exist yet.
UINT32 gl_lighttable_id;
struct {
UINT32 id; // The id of the hardware lighttable. Zero means it does not exist yet.
RGBA_t *data; // The texture data of the hardware lighttable.
boolean needs_update; // If the colormap changed recently or not.
} gl_lighttable;
#endif
#ifdef EXTRACOLORMAPLUMPS
@ -242,9 +245,8 @@ typedef struct sectorportal_s
struct sector_s *sector;
struct mobj_s *mobj;
};
struct {
fixed_t x, y;
} origin;
struct sector_s *target;
boolean ceiling;
} sectorportal_t;
typedef struct ffloor_s

View file

@ -173,6 +173,7 @@ void R_DrawTiltedTranslucentSpan_8(void);
void R_DrawSplat_8(void);
void R_DrawTranslucentSplat_8(void);
void R_DrawTiltedSplat_8(void);
void R_DrawTiltedTranslucentSplat_8(void);
void R_DrawFloorSprite_8(void);
void R_DrawTranslucentFloorSprite_8(void);
@ -194,6 +195,7 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void);
void R_DrawSplat_NPO2_8(void);
void R_DrawTranslucentSplat_NPO2_8(void);
void R_DrawTiltedSplat_NPO2_8(void);
void R_DrawTiltedTranslucentSplat_NPO2_8(void);
void R_DrawFloorSprite_NPO2_8(void);
void R_DrawTranslucentFloorSprite_NPO2_8(void);

View file

@ -1301,6 +1301,136 @@ void R_DrawTiltedSplat_8(void)
#endif
}
void R_DrawTiltedTranslucentSplat_8(void)
{
// x1, x2 = ds_x1, ds_x2
int width = ds_x2 - ds_x1;
double iz, uz, vz;
UINT32 u, v;
int i;
UINT8 *source;
UINT8 *colormap;
UINT8 *dest;
UINT8 val;
double startz, startu, startv;
double izstep, uzstep, vzstep;
double endz, endu, endv;
UINT32 stepu, stepv;
iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx);
uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
R_CalcSlopeLight();
dest = &topleft[ds_y*vid.width + ds_x1];
source = ds_source;
//colormap = ds_colormap;
#if 0 // The "perfect" reference version of this routine. Pretty slow.
// Use it only to see how things are supposed to look.
i = 0;
do
{
double z = 1.f/iz;
u = (INT64)(uz*z);
v = (INT64)(vz*z);
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
*dest = *(ds_transmap + (colormap[val] << 8) + *dest);
dest++;
iz += ds_sz.x;
uz += ds_su.x;
vz += ds_sv.x;
} while (--width >= 0);
#else
startz = 1.f/iz;
startu = uz*startz;
startv = vz*startz;
izstep = ds_sz.x * SPANSIZE;
uzstep = ds_su.x * SPANSIZE;
vzstep = ds_sv.x * SPANSIZE;
//x1 = 0;
width++;
while (width >= SPANSIZE)
{
iz += izstep;
uz += uzstep;
vz += vzstep;
endz = 1.f/iz;
endu = uz*endz;
endv = vz*endz;
stepu = (INT64)((endu - startu) * INVSPAN);
stepv = (INT64)((endv - startv) * INVSPAN);
u = (INT64)(startu);
v = (INT64)(startv);
for (i = SPANSIZE-1; i >= 0; i--)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
*dest = *(ds_transmap + (colormap[val] << 8) + *dest);
dest++;
u += stepu;
v += stepv;
}
startu = endu;
startv = endv;
width -= SPANSIZE;
}
if (width > 0)
{
if (width == 1)
{
u = (INT64)(startu);
v = (INT64)(startv);
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
*dest = *(ds_transmap + (colormap[val] << 8) + *dest);
}
else
{
double left = width;
iz += ds_sz.x * left;
uz += ds_su.x * left;
vz += ds_sv.x * left;
endz = 1.f/iz;
endu = uz*endz;
endv = vz*endz;
left = 1.f/left;
stepu = (INT64)((endu - startu) * left);
stepv = (INT64)((endv - startv) * left);
u = (INT64)(startu);
v = (INT64)(startv);
for (; width != 0; width--)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
if (val != TRANSPARENTPIXEL)
*dest = *(ds_transmap + (colormap[val] << 8) + *dest);
dest++;
u += stepu;
v += stepv;
}
}
}
#endif
}
/** \brief The R_DrawSplat_8 function
Just like R_DrawSpan_8, but skips transparent pixels.
*/

View file

@ -666,6 +666,204 @@ void R_DrawTiltedSplat_NPO2_8(void)
#endif
}
void R_DrawTiltedTranslucentSplat_NPO2_8(void)
{
// x1, x2 = ds_x1, ds_x2
int width = ds_x2 - ds_x1;
double iz, uz, vz;
UINT32 u, v;
int i;
UINT8 *source;
UINT8 *colormap;
UINT8 *dest;
UINT8 val;
double startz, startu, startv;
double izstep, uzstep, vzstep;
double endz, endu, endv;
UINT32 stepu, stepv;
struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth);
struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight);
iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx);
uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
R_CalcSlopeLight();
dest = &topleft[ds_y*vid.width + ds_x1];
source = ds_source;
//colormap = ds_colormap;
#if 0 // The "perfect" reference version of this routine. Pretty slow.
// Use it only to see how things are supposed to look.
i = 0;
do
{
double z = 1.f/iz;
u = (INT64)(uz*z);
v = (INT64)(vz*z);
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
// Lactozilla: Non-powers-of-two
{
fixed_t x = (((fixed_t)u) >> FRACBITS);
fixed_t y = (((fixed_t)v) >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth;
else
x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth;
if (y < 0)
y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight;
else
y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight;
val = source[((y * ds_flatwidth) + x)];
}
if (val != TRANSPARENTPIXEL)
*dest = *(ds_transmap + (colormap[val] << 8) + *dest);
dest++;
iz += ds_sz.x;
uz += ds_su.x;
vz += ds_sv.x;
} while (--width >= 0);
#else
startz = 1.f/iz;
startu = uz*startz;
startv = vz*startz;
izstep = ds_sz.x * SPANSIZE;
uzstep = ds_su.x * SPANSIZE;
vzstep = ds_sv.x * SPANSIZE;
//x1 = 0;
width++;
while (width >= SPANSIZE)
{
iz += izstep;
uz += uzstep;
vz += vzstep;
endz = 1.f/iz;
endu = uz*endz;
endv = vz*endz;
stepu = (INT64)((endu - startu) * INVSPAN);
stepv = (INT64)((endv - startv) * INVSPAN);
u = (INT64)(startu);
v = (INT64)(startv);
for (i = SPANSIZE-1; i >= 0; i--)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
// Lactozilla: Non-powers-of-two
{
fixed_t x = (((fixed_t)u) >> FRACBITS);
fixed_t y = (((fixed_t)v) >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth;
else
x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth;
if (y < 0)
y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight;
else
y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight;
val = source[((y * ds_flatwidth) + x)];
}
if (val != TRANSPARENTPIXEL)
*dest = *(ds_transmap + (colormap[val] << 8) + *dest);
dest++;
u += stepu;
v += stepv;
}
startu = endu;
startv = endv;
width -= SPANSIZE;
}
if (width > 0)
{
if (width == 1)
{
u = (INT64)(startu);
v = (INT64)(startv);
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
// Lactozilla: Non-powers-of-two
{
fixed_t x = (((fixed_t)u) >> FRACBITS);
fixed_t y = (((fixed_t)v) >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth;
else
x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth;
if (y < 0)
y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight;
else
y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight;
val = source[((y * ds_flatwidth) + x)];
}
if (val != TRANSPARENTPIXEL)
*dest = *(ds_transmap + (colormap[val] << 8) + *dest);
}
else
{
double left = width;
iz += ds_sz.x * left;
uz += ds_su.x * left;
vz += ds_sv.x * left;
endz = 1.f/iz;
endu = uz*endz;
endv = vz*endz;
left = 1.f/left;
stepu = (INT64)((endu - startu) * left);
stepv = (INT64)((endv - startv) * left);
u = (INT64)(startu);
v = (INT64)(startv);
for (; width != 0; width--)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
// Lactozilla: Non-powers-of-two
{
fixed_t x = (((fixed_t)u) >> FRACBITS);
fixed_t y = (((fixed_t)v) >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth;
else
x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth;
if (y < 0)
y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight;
else
y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight;
val = source[((y * ds_flatwidth) + x)];
}
if (val != TRANSPARENTPIXEL)
*dest = *(ds_transmap + (colormap[val] << 8) + *dest);
dest++;
u += stepu;
v += stepv;
}
}
}
#endif
}
/** \brief The R_DrawSplat_NPO2_8 function
Just like R_DrawSpan_NPO2_8, but skips transparent pixels.
*/

View file

@ -1434,6 +1434,9 @@ static void R_PortalFrame(portal_t *portal)
viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
if (!P_MobjWasRemoved(portal->viewmobj))
r_viewmobj = portal->viewmobj;
portalclipstart = portal->start;
portalclipend = portal->end;

View file

@ -1079,6 +1079,9 @@ void R_DrawSinglePlane(visplane_t *pl)
case SPANDRAWFUNC_SPLAT:
spanfunctype = SPANDRAWFUNC_TILTEDSPLAT;
break;
case SPANDRAWFUNC_TRANSSPLAT:
spanfunctype = SPANDRAWFUNC_TILTEDTRANSSPLAT;
break;
case SPANDRAWFUNC_SOLID:
spanfunctype = SPANDRAWFUNC_TILTEDSOLID;
break;

View file

@ -101,7 +101,7 @@ void Portal_ClipApply (const portal_t* portal)
static portal_t* Portal_Add (const INT16 x1, const INT16 x2)
{
portal_t *portal = Z_Malloc(sizeof(portal_t), PU_LEVEL, NULL);
portal_t *portal = Z_Calloc(sizeof(portal_t), PU_LEVEL, NULL);
INT16 *ceilingclipsave = Z_Malloc(sizeof(INT16)*(x2-x1 + 1), PU_LEVEL, NULL);
INT16 *floorclipsave = Z_Malloc(sizeof(INT16)*(x2-x1 + 1), PU_LEVEL, NULL);
fixed_t *frontscalesave = Z_Malloc(sizeof(fixed_t)*(x2-x1 + 1), PU_LEVEL, NULL);
@ -117,7 +117,7 @@ static portal_t* Portal_Add (const INT16 x1, const INT16 x2)
portal_cap->next = portal;
portal_cap = portal;
}
portal->next = NULL;
portal->clipline = -1;
// Store clipping values so they can be restored once the portal is rendered.
portal->ceilingclip = ceilingclipsave;
@ -142,11 +142,9 @@ void Portal_Remove (portal_t* portal)
Z_Free(portal);
}
static void Portal_GetViewpointForLine(portal_t *portal, line_t *start, line_t *dest)
static void Portal_GetViewpointForLine(portal_t *portal, line_t *start, line_t *dest, angle_t dangle)
{
// Offset the portal view by the linedef centers
angle_t dangle = R_PointToAngle2(0,0,dest->dx,dest->dy) - R_PointToAngle2(start->dx,start->dy,0,0);
fixed_t disttopoint;
angle_t angtopoint;
@ -168,7 +166,6 @@ static void Portal_GetViewpointForLine(portal_t *portal, line_t *start, line_t *
portal->viewx = dest_c.x + FixedMul(FINECOSINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
portal->viewy = dest_c.y + FixedMul(FINESINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
portal->viewz = viewz + dest->frontsector->floorheight - start->frontsector->floorheight;
portal->viewangle = viewangle + dangle;
}
@ -189,12 +186,13 @@ void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, con
line_t* start = &lines[line1];
line_t* dest = &lines[line2];
Portal_GetViewpointForLine(portal, start, dest);
angle_t dangle = R_PointToAngle2(0,0,dest->dx,dest->dy) - R_PointToAngle2(start->dx,start->dy,0,0);
Portal_GetViewpointForLine(portal, start, dest, dangle);
portal->viewz = viewz + dest->frontsector->floorheight - start->frontsector->floorheight;
portal->clipline = line2;
portal->is_skybox = false;
portal->is_horizon = false;
portal->horizon_sector = NULL;
Portal_ClipRange(portal);
@ -317,10 +315,7 @@ static boolean Portal_AddSkybox (const visplane_t* plane)
Portal_ClipVisplane(plane, portal);
portal->clipline = -1;
portal->is_skybox = true;
portal->is_horizon = false;
portal->horizon_sector = NULL;
Portal_GetViewpointForSkybox(portal);
@ -332,14 +327,28 @@ static void Portal_GetViewpointForSecPortal(portal_t *portal, sectorportal_t *se
fixed_t x, y, z;
angle_t angle;
sector_t *target = secportal->target;
fixed_t target_x = target->soundorg.x;
fixed_t target_y = target->soundorg.y;
fixed_t target_z;
if (secportal->ceiling)
target_z = P_GetSectorCeilingZAt(target, target_x, target_y);
else
target_z = P_GetSectorFloorZAt(target, target_x, target_y);
switch (secportal->type)
{
case SECPORTAL_LINE:
Portal_GetViewpointForLine(portal, secportal->line.start, secportal->line.dest);
angle = secportal->line.dest->angle - secportal->line.start->angle;
Portal_GetViewpointForLine(portal, secportal->line.start, secportal->line.dest, angle);
portal->viewz = viewz; // Apparently it just works like that. Not going to question it.
return;
case SECPORTAL_OBJECT:
if (!secportal->mobj || P_MobjWasRemoved(secportal->mobj))
if (P_MobjWasRemoved(secportal->mobj))
return;
portal->viewmobj = secportal->mobj;
x = secportal->mobj->x;
y = secportal->mobj->y;
z = secportal->mobj->z;
@ -373,8 +382,9 @@ static void Portal_GetViewpointForSecPortal(portal_t *portal, sectorportal_t *se
return;
}
fixed_t refx = secportal->origin.x - viewx;
fixed_t refy = secportal->origin.y - viewy;
fixed_t refx = target_x - viewx;
fixed_t refy = target_y - viewy;
fixed_t refz = target_z - viewz;
// Rotate the X/Y to match the target angle
if (angle != 0)
@ -387,7 +397,7 @@ static void Portal_GetViewpointForSecPortal(portal_t *portal, sectorportal_t *se
portal->viewx = x - refx;
portal->viewy = y - refy;
portal->viewz = z + viewz;
portal->viewz = z - refz;
portal->viewangle = angle + viewangle;
}
@ -413,11 +423,6 @@ static boolean Portal_AddSectorPortal (const visplane_t* plane)
Portal_ClipVisplane(plane, portal);
portal->clipline = -1;
portal->is_horizon = false;
portal->is_skybox = false;
portal->horizon_sector = NULL;
Portal_GetViewpointForSecPortal(portal, secportal);
return true;
@ -425,7 +430,7 @@ static boolean Portal_AddSectorPortal (const visplane_t* plane)
/** Creates a transferred sector portal.
*/
void Portal_AddTransferred (UINT32 secportalnum, const INT32 x1, const INT32 x2)
void Portal_AddTransferred (const UINT32 secportalnum, const INT32 x1, const INT32 x2)
{
if (secportalnum >= secportalcount)
return;
@ -435,9 +440,6 @@ void Portal_AddTransferred (UINT32 secportalnum, const INT32 x1, const INT32 x2)
return;
portal_t* portal = Portal_Add(x1, x2);
portal->is_skybox = false;
portal->is_horizon = false;
portal->horizon_sector = NULL;
if (secportal->type == SECPORTAL_SKYBOX)
Portal_GetViewpointForSkybox(portal);

View file

@ -36,6 +36,8 @@ typedef struct portal_s
boolean is_skybox;
mobj_t *viewmobj;
UINT8 pass; /**< Keeps track of the portal's recursion depth. */
INT32 clipline; /**< Optional clipline for line-based portals. */
@ -58,7 +60,7 @@ extern INT32 portalclipstart, portalclipend;
void Portal_InitList (void);
void Portal_Remove (portal_t* portal);
void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2);
void Portal_AddTransferred (UINT32 secportalnum, const INT32 x1, const INT32 x2);
void Portal_AddTransferred (const UINT32 secportalnum, const INT32 x1, const INT32 x2);
void Portal_ClipRange (portal_t* portal);
void Portal_ClipApply (const portal_t* portal);

View file

@ -124,6 +124,7 @@ void SCR_SetDrawFuncs(void)
spanfuncs[SPANDRAWFUNC_SPLAT] = R_DrawSplat_8;
spanfuncs[SPANDRAWFUNC_TRANSSPLAT] = R_DrawTranslucentSplat_8;
spanfuncs[SPANDRAWFUNC_TILTEDSPLAT] = R_DrawTiltedSplat_8;
spanfuncs[SPANDRAWFUNC_TILTEDTRANSSPLAT] = R_DrawTiltedTranslucentSplat_8;
spanfuncs[SPANDRAWFUNC_SPRITE] = R_DrawFloorSprite_8;
spanfuncs[SPANDRAWFUNC_TRANSSPRITE] = R_DrawTranslucentFloorSprite_8;
spanfuncs[SPANDRAWFUNC_TILTEDSPRITE] = R_DrawTiltedFloorSprite_8;
@ -146,6 +147,7 @@ void SCR_SetDrawFuncs(void)
spanfuncs_npo2[SPANDRAWFUNC_SPLAT] = R_DrawSplat_NPO2_8;
spanfuncs_npo2[SPANDRAWFUNC_TRANSSPLAT] = R_DrawTranslucentSplat_NPO2_8;
spanfuncs_npo2[SPANDRAWFUNC_TILTEDSPLAT] = R_DrawTiltedSplat_NPO2_8;
spanfuncs_npo2[SPANDRAWFUNC_TILTEDTRANSSPLAT] = R_DrawTiltedTranslucentSplat_NPO2_8;
spanfuncs_npo2[SPANDRAWFUNC_SPRITE] = R_DrawFloorSprite_NPO2_8;
spanfuncs_npo2[SPANDRAWFUNC_TRANSSPRITE] = R_DrawTranslucentFloorSprite_NPO2_8;
spanfuncs_npo2[SPANDRAWFUNC_TILTEDSPRITE] = R_DrawTiltedFloorSprite_NPO2_8;

View file

@ -115,6 +115,7 @@ enum
SPANDRAWFUNC_SPLAT,
SPANDRAWFUNC_TRANSSPLAT,
SPANDRAWFUNC_TILTEDSPLAT,
SPANDRAWFUNC_TILTEDTRANSSPLAT,
SPANDRAWFUNC_SPRITE,
SPANDRAWFUNC_TRANSSPRITE,

View file

@ -112,6 +112,7 @@ void *hwSym(const char *funcName,void *handle)
GETFUNC(SetPaletteLookup);
GETFUNC(CreateLightTable);
GETFUNC(UpdateLightTable);
GETFUNC(ClearLightTables);
GETFUNC(SetScreenPalette);

View file

@ -1901,6 +1901,7 @@ void VID_StartupOpenGL(void)
HWD.pfnSetPaletteLookup = hwSym("SetPaletteLookup",NULL);
HWD.pfnCreateLightTable = hwSym("CreateLightTable",NULL);
HWD.pfnUpdateLightTable = hwSym("UpdateLightTable",NULL);
HWD.pfnClearLightTables = hwSym("ClearLightTables",NULL);
HWD.pfnSetScreenPalette = hwSym("SetScreenPalette",NULL);

View file

@ -65,6 +65,7 @@
#include "i_video.h" // rendermode
#include "md5.h"
#include "lua_script.h"
#include "lua_hook.h"
#ifdef SCANTHINGS
#include "p_setup.h" // P_ScanThings
#endif
@ -307,12 +308,10 @@ static void W_LoadDehackedLumps(UINT16 wadnum, boolean mainfile)
* \param resblock resulting MD5 checksum
* \return 0 if MD5 checksum was made, and is at resblock, 1 if error was found
*/
#ifndef NOMD5
static INT32 W_MakeFileMD5(const char *filename, void *resblock)
{
#ifdef NOMD5
(void)filename;
memset(resblock, 0x00, 16);
#else
FILE *fhandle;
if ((fhandle = fopen(filename, "rb")) != NULL)
@ -329,9 +328,9 @@ static INT32 W_MakeFileMD5(const char *filename, void *resblock)
fclose(fhandle);
return 0;
}
#endif
return 1;
}
#endif
// Invalidates the cache of lump numbers. Call this whenever a wad is added.
static void W_InvalidateLumpnumCache(void)
@ -1011,6 +1010,10 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup)
break;
}
lua_lumploading++;
LUA_HookVoid(HOOK(AddonLoaded));
lua_lumploading--;
W_InvalidateLumpnumCache();
return wadfile->numlumps;
}
@ -1171,6 +1174,11 @@ UINT16 W_InitFolder(const char *path, boolean mainfile, boolean startup)
W_ReadFileShaders(wadfile);
W_LoadTrnslateLumps(numwadfiles - 1);
W_LoadDehackedLumpsPK3(numwadfiles - 1, mainfile);
lua_lumploading++;
LUA_HookVoid(HOOK(AddonLoaded));
lua_lumploading--;
W_InvalidateLumpnumCache();
return wadfile->numlumps;
@ -1350,17 +1358,6 @@ UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump)
return i;
}
// Returns 0 if the folder is not empty, 1 if it is empty, -1 if it doesn't exist
INT32 W_IsFolderEmpty(const char *name, UINT16 wad)
{
UINT16 start = W_CheckNumForFolderStartPK3(name, wad, 0);
if (start == INT16_MAX)
return -1;
// Unlike W_CheckNumForFolderStartPK3, W_CheckNumForFolderEndPK3 doesn't return INT16_MAX.
return W_CheckNumForFolderEndPK3(name, wad, start) <= start;
}
char *W_GetLumpFolderPathPK3(UINT16 wad, UINT16 lump)
{
const char *fullname = wadfiles[wad]->lumpinfo[lump].fullname;
@ -1725,10 +1722,14 @@ static UINT16 W_CheckNumForPatchNamePwad(const char *name, UINT16 wad, boolean l
// TODO: cache namespace lump IDs
if (W_FileHasFolders(wadfiles[wad]))
{
if (!W_IsFolderEmpty("Flats/", wad))
start = W_CheckNumForFolderStartPK3("Flats/", wad, 0);
end = W_CheckNumForFolderEndPK3("Flats/", wad, start);
// if the start and end is the same, the folder is empty
if (end <= start)
{
start = W_CheckNumForFolderStartPK3("Flats/", wad, 0);
end = W_CheckNumForFolderEndPK3("Flats/", wad, start);
start = INT16_MAX;
end = INT16_MAX;
}
}
else

View file

@ -180,7 +180,6 @@ UINT16 W_CheckNumForMarkerStartPwad(const char *name, UINT16 wad, UINT16 startlu
UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump);
UINT16 W_CheckNumForFolderStartPK3(const char *name, UINT16 wad, UINT16 startlump);
UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump);
INT32 W_IsFolderEmpty(const char *name, UINT16 wad);
char *W_GetLumpFolderPathPK3(UINT16 wad, UINT16 lump);
char *W_GetLumpFolderNamePK3(UINT16 wad, UINT16 lump);

View file

@ -671,6 +671,7 @@ static void Command_Memfree_f(void)
CONS_Printf(M_GetText("Cached textures : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRCACHE)>>10));
CONS_Printf(M_GetText("Texture colormaps : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHCOLMIPMAP)>>10));
CONS_Printf(M_GetText("Model textures : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRMODELTEXTURE)>>10));
CONS_Printf(M_GetText("Light table textures : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRLIGHTTABLEDATA)>>10));
CONS_Printf(M_GetText("Plane polygons : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPLANE)>>10));
CONS_Printf(M_GetText("All GPU textures : %7d KB\n"), HWR_GetTextureUsed()>>10);
}

View file

@ -55,6 +55,7 @@ enum
PU_HWRPATCHINFO = 21, // Hardware GLPatch_t struct for OpenGL texture cache
PU_HWRPATCHCOLMIPMAP = 22, // Hardware GLMipmap_t struct colormap variation of patch
PU_HWRMODELTEXTURE = 23, // Hardware model texture
PU_HWRLIGHTTABLEDATA = 24, // Hardware light table data
PU_HWRCACHE = 48, // static until unlocked
PU_CACHE = 49, // static until unlocked