diff --git a/.gitlab/ci/templates/srb2ci.yml b/.gitlab/ci/templates/srb2ci.yml index 3716d9df9..bdf8a3ed6 100644 --- a/.gitlab/ci/templates/srb2ci.yml +++ b/.gitlab/ci/templates/srb2ci.yml @@ -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" diff --git a/src/command.c b/src/command.c index 399714bd0..8f9166361 100644 --- a/src/command.c +++ b/src/command.c @@ -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) diff --git a/src/deh_lua.c b/src/deh_lua.c index e81a8c08e..e5b3b03de 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -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)); diff --git a/src/dehacked.c b/src/dehacked.c index 2050a117f..63656753d 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -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); } diff --git a/src/hardware/hw_batching.c b/src/hardware/hw_batching.c index 7a57a7a12..5d1af10e2 100644 --- a/src/hardware/hw_batching.c +++ b/src/hardware/hw_batching.c @@ -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; } } diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index f282ca891..b71bf7007 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -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(); } diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 694cc1b8c..a5fdc00a4 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -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; }; diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index 62fe8d0bd..bf9f7da3b 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -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); diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 19326de57..da290ec47 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -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 = §ors[gl_linedef->frontsector->heightsec]; + else + front = gl_linedef->frontsector; + + if (gl_linedef->backsector->heightsec != -1) + back = §ors[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); diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 75a92c2fb..85a50edb0 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -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) { diff --git a/src/lua_colorlib.c b/src/lua_colorlib.c index 9e679eb40..2743635ed 100644 --- a/src/lua_colorlib.c +++ b/src/lua_colorlib.c @@ -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; } diff --git a/src/lua_hook.h b/src/lua_hook.h index 90a11d05d..ce79cd1cb 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -72,6 +72,7 @@ automatically. X (MusicChange),\ X (PlayerHeight),/* override player height */\ X (PlayerCanEnterSpinGaps),\ + X (AddonLoaded),\ X (KeyDown),\ X (KeyUp),\ diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index ebe995ea8..6bdebf774 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -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!"); diff --git a/src/m_menu.c b/src/m_menu.c index 2e4a42506..63a702474 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -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; } diff --git a/src/netcode/d_net.c b/src/netcode/d_net.c index 031336852..4860d8688 100644 --- a/src/netcode/d_net.c +++ b/src/netcode/d_net.c @@ -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; diff --git a/src/netcode/d_netcmd.c b/src/netcode/d_netcmd.c index d1e2297ec..32731d9f6 100644 --- a/src/netcode/d_netcmd.c +++ b/src/netcode/d_netcmd.c @@ -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 diff --git a/src/netcode/i_net.h b/src/netcode/i_net.h index 4fd317994..a2039bd19 100644 --- a/src/netcode/i_net.h +++ b/src/netcode/i_net.h @@ -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 diff --git a/src/netcode/i_tcp.c b/src/netcode/i_tcp.c index ed1f5b4e7..256d9992e 100644 --- a/src/netcode/i_tcp.c +++ b/src/netcode/i_tcp.c @@ -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; diff --git a/src/p_enemy.c b/src/p_enemy.c index 2ae7276df..59ca95409 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -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. diff --git a/src/p_inter.c b/src/p_inter.c index 19ab5ead4..dc606a47e 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -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) diff --git a/src/p_mobj.c b/src/p_mobj.c index b377ff82f..fb9e7d78e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -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; diff --git a/src/p_saveg.c b/src/p_saveg.c index d6f8d23c5..e939cf8e3 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -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) { diff --git a/src/p_setup.c b/src/p_setup.c index 39be19d54..906195c18 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -530,7 +530,7 @@ UINT32 P_GetScoreForGradeOverall(INT16 map, UINT8 grade) void P_AddNiGHTSTimes(INT16 i, char *gtext) { char *spos = gtext; - + for (UINT8 n = 0; n < 8; n++) { if (spos != NULL) @@ -3075,7 +3075,7 @@ static void P_LoadTextmap(void) // TODO: remove this limitation in a backwards-compatible way (UDMF versioning?) UINT8 lightalpha = (textmap_colormap.lightalpha * 102) / 10; UINT8 fadealpha = (textmap_colormap.fadealpha * 102) / 10; - + INT32 rgba = P_ColorToRGBA(textmap_colormap.lightcolor, lightalpha); INT32 fadergba = P_ColorToRGBA(textmap_colormap.fadecolor, fadealpha); sc->extra_colormap = sc->spawn_extra_colormap = R_CreateColormap(rgba, fadergba, textmap_colormap.fadestart, textmap_colormap.fadeend, textmap_colormap.flags); @@ -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); diff --git a/src/p_spec.c b/src/p_spec.c index 6f3543161..9b124f9af 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -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, §or->portal_floor, result); + return P_SectorGetPortalOrCreate(sector, §or->portal_floor, result, false); } static sectorportal_t *P_SectorGetCeilingPortalOrCreate(sector_t *sector, UINT32 *result) { - return P_SectorGetPortalOrCreate(sector, §or->portal_ceiling, result); + return P_SectorGetPortalOrCreate(sector, §or->portal_ceiling, result, true); } static void P_CopySectorPortalToLines(UINT32 portal_num, int sector_tag) diff --git a/src/r_data.c b/src/r_data.c index e7200ecbd..32faa07a8 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -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 diff --git a/src/r_data.h b/src/r_data.h index 7c6ee19d5..64abf6d83 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -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); diff --git a/src/r_defs.h b/src/r_defs.h index 51fac21fa..eac3e2d1f 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -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 diff --git a/src/r_draw.h b/src/r_draw.h index 00032e44f..d5c5b4e25 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -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); diff --git a/src/r_draw8.c b/src/r_draw8.c index 220878f88..c720f454e 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -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. */ diff --git a/src/r_draw8_npo2.c b/src/r_draw8_npo2.c index 6213ecbc5..7fbb40d84 100644 --- a/src/r_draw8_npo2.c +++ b/src/r_draw8_npo2.c @@ -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. */ diff --git a/src/r_main.c b/src/r_main.c index 32e3138eb..ee05876da 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -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; diff --git a/src/r_plane.c b/src/r_plane.c index 380f39eab..7642a4dd6 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -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; diff --git a/src/r_portal.c b/src/r_portal.c index 4d042cae3..957d574b2 100644 --- a/src/r_portal.c +++ b/src/r_portal.c @@ -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); diff --git a/src/r_portal.h b/src/r_portal.h index 2485e45a7..5190885b7 100644 --- a/src/r_portal.h +++ b/src/r_portal.h @@ -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); diff --git a/src/screen.c b/src/screen.c index 707eb908c..dc77a9a93 100644 --- a/src/screen.c +++ b/src/screen.c @@ -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; diff --git a/src/screen.h b/src/screen.h index 6d45560c4..3ce593a52 100644 --- a/src/screen.h +++ b/src/screen.h @@ -115,6 +115,7 @@ enum SPANDRAWFUNC_SPLAT, SPANDRAWFUNC_TRANSSPLAT, SPANDRAWFUNC_TILTEDSPLAT, + SPANDRAWFUNC_TILTEDTRANSSPLAT, SPANDRAWFUNC_SPRITE, SPANDRAWFUNC_TRANSSPRITE, diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c index ca87fcc79..f56126601 100644 --- a/src/sdl/hwsym_sdl.c +++ b/src/sdl/hwsym_sdl.c @@ -112,6 +112,7 @@ void *hwSym(const char *funcName,void *handle) GETFUNC(SetPaletteLookup); GETFUNC(CreateLightTable); + GETFUNC(UpdateLightTable); GETFUNC(ClearLightTables); GETFUNC(SetScreenPalette); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 10c866a1e..36bfd380f 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -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); diff --git a/src/w_wad.c b/src/w_wad.c index 4a1d44548..50ba622a9 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -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 diff --git a/src/w_wad.h b/src/w_wad.h index 5872ae50a..84aafa3a4 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -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); diff --git a/src/z_zone.c b/src/z_zone.c index 5750f8ae0..0852fabae 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -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); } diff --git a/src/z_zone.h b/src/z_zone.h index ce7af4a15..56c540c3b 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -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