diff --git a/specs/udmf_zdoom.txt b/specs/udmf_zdoom.txt index d501cb884..e79ae196b 100644 --- a/specs/udmf_zdoom.txt +++ b/specs/udmf_zdoom.txt @@ -27,7 +27,8 @@ II. Implementation Semantics II.A : Storage and Retrieval of Data ------------------------------------ -No changes. +Any TEXTMAP lump in the described namespaces must be encoded in ISO 8859-1 which +as of this writing is the only character encoding supported by ZDoom. ----------------------------------- II.B : Storage Within Archive Files diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 799bf6dd4..9332e4919 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -509,6 +509,11 @@ if( NOT MSVC ) add_definitions( -D__forceinline=inline ) endif( NOT MSVC ) +# Fix stat in v140_xp (broken in RTM and Update 1 so far) +if( MSVC AND MSVC_VERSION EQUAL 1900 AND CMAKE_GENERATOR_TOOLSET STREQUAL "v140_xp" ) + add_definitions( -D_stat64i32=VS14Stat ) +endif( MSVC AND MSVC_VERSION EQUAL 1900 AND CMAKE_GENERATOR_TOOLSET STREQUAL "v140_xp" ) + if( UNIX ) CHECK_LIBRARY_EXISTS( rt clock_gettime "" CLOCK_GETTIME_IN_RT ) if( NOT CLOCK_GETTIME_IN_RT ) diff --git a/src/d_net.cpp b/src/d_net.cpp index e6b5713f2..780b89382 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -973,7 +973,7 @@ void NetUpdate (void) { I_StartTic (); D_ProcessEvents (); - if ((maketic - gametic) / ticdup >= BACKUPTICS/2-1) + if (pauseext || (maketic - gametic) / ticdup >= BACKUPTICS/2-1) break; // can't hold any more //Printf ("mk:%i ",maketic); @@ -1204,7 +1204,7 @@ void NetUpdate (void) // Send current network delay // The number of tics we just made should be removed from the count. - netbuffer[k++] = ((maketic - newtics - gametic) / ticdup); + netbuffer[k++] = ((maketic - numtics - gametic) / ticdup); if (numtics > 0) { @@ -1810,7 +1810,8 @@ void TryRunTics (void) // If paused, do not eat more CPU time than we need, because it // will all be wasted anyway. - if (pauseext) r_NoInterpolate = true; + if (pauseext) + r_NoInterpolate = true; bool doWait = cl_capfps || r_NoInterpolate /*|| netgame*/; // get real tics @@ -1828,6 +1829,9 @@ void TryRunTics (void) // get available tics NetUpdate (); + if (pauseext) + return; + lowtic = INT_MAX; numplaying = 0; for (i = 0; i < doomcom.numnodes; i++) @@ -1935,7 +1939,7 @@ void TryRunTics (void) C_Ticker (); M_Ticker (); I_GetTime (true); - if (!pauseext) G_Ticker(); + G_Ticker(); gametic++; NetUpdate (); // check for new console commands diff --git a/src/g_shared/hudmessages.cpp b/src/g_shared/hudmessages.cpp index f60c8a84e..997021c5f 100644 --- a/src/g_shared/hudmessages.cpp +++ b/src/g_shared/hudmessages.cpp @@ -134,6 +134,7 @@ DHUDMessage::DHUDMessage (FFont *font, const char *text, float x, float y, int h NoWrap = false; ClipX = ClipY = ClipWidth = ClipHeight = 0; WrapWidth = 0; + HandleAspect = true; Top = y; Next = NULL; Lines = NULL; @@ -196,6 +197,14 @@ void DHUDMessage::Serialize (FArchive &arc) NoWrap = false; ClipX = ClipY = ClipWidth = ClipHeight = WrapWidth = 0; } + if (SaveVersion >= 4525) + { + arc << HandleAspect; + } + else + { + HandleAspect = true; + } if (arc.IsLoading ()) { Lines = NULL; @@ -257,7 +266,7 @@ void DHUDMessage::CalcClipCoords(int hudheight) else { screen->VirtualToRealCoordsInt(x, y, w, h, - HUDWidth, hudheight, false, true); + HUDWidth, hudheight, false, HandleAspect); ClipLeft = x; ClipTop = y; ClipRight = x + w; diff --git a/src/g_shared/sbar.h b/src/g_shared/sbar.h index b8dde5850..b8416dd5d 100644 --- a/src/g_shared/sbar.h +++ b/src/g_shared/sbar.h @@ -94,12 +94,13 @@ public: NoWrap = nowrap; ResetText(SourceText); } - void SetClipRect(int x, int y, int width, int height) + void SetClipRect(int x, int y, int width, int height, bool aspect) { ClipX = x; ClipY = y; ClipWidth = width; ClipHeight = height; + HandleAspect = aspect; } void SetWrapWidth(int wrap) { @@ -119,6 +120,7 @@ protected: int HUDWidth, HUDHeight; int ClipX, ClipY, ClipWidth, ClipHeight, WrapWidth; // in HUD coords int ClipLeft, ClipTop, ClipRight, ClipBot; // in screen coords + bool HandleAspect; EColorRange TextColor; FFont *Font; FRenderStyle Style; diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 4f8a0c6c3..30733eac8 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -5315,6 +5315,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args, const ClipRectWidth = argCount > 2 ? args[2] : 0; ClipRectHeight = argCount > 3 ? args[3] : 0; WrapWidth = argCount > 4 ? args[4] : 0; + HandleAspect = argCount > 5 ? !!args[5] : true; break; case ACSF_SetHUDWrapWidth: @@ -5919,6 +5920,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) break; } + return 0; } @@ -7854,7 +7856,7 @@ scriptwait: } break; } - msg->SetClipRect(ClipRectLeft, ClipRectTop, ClipRectWidth, ClipRectHeight); + msg->SetClipRect(ClipRectLeft, ClipRectTop, ClipRectWidth, ClipRectHeight, HandleAspect); if (WrapWidth != 0) { msg->SetWrapWidth(WrapWidth); @@ -9466,6 +9468,7 @@ DLevelScript::DLevelScript (AActor *who, line_t *where, int num, const ScriptPtr activefont = SmallFont; hudwidth = hudheight = 0; ClipRectLeft = ClipRectTop = ClipRectWidth = ClipRectHeight = WrapWidth = 0; + HandleAspect = true; state = SCRIPT_Running; // Hexen waited one second before executing any open scripts. I didn't realize diff --git a/src/p_acs.h b/src/p_acs.h index d5971e349..3188e46aa 100644 --- a/src/p_acs.h +++ b/src/p_acs.h @@ -891,6 +891,7 @@ protected: int hudwidth, hudheight; int ClipRectLeft, ClipRectTop, ClipRectWidth, ClipRectHeight; int WrapWidth; + bool HandleAspect; FBehavior *activeBehavior; int InModuleScriptNumber; diff --git a/src/p_switch.cpp b/src/p_switch.cpp index 1ca4654b5..984794c8a 100644 --- a/src/p_switch.cpp +++ b/src/p_switch.cpp @@ -177,10 +177,47 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno) if ((TexMan.FindSwitch(side->GetTexture(side_t::top))) != NULL) { + + // Check 3D floors on back side + { + sector_t * back = line->sidedef[1 - sideno]->sector; + for (unsigned i = 0; i < back->e->XFloor.ffloors.Size(); i++) + { + F3DFloor *rover = back->e->XFloor.ffloors[i]; + if (!(rover->flags & FF_EXISTS)) continue; + if (!(rover->flags & FF_UPPERTEXTURE)) continue; + + if (user->z > rover->top.plane->ZatPoint(checkx, checky) || + user->z + user->height < rover->bottom.plane->ZatPoint(checkx, checky)) + continue; + + // This 3D floor depicts a switch texture in front of the player's eyes + return true; + } + } + return (user->z + user->height > open.top); } else if ((TexMan.FindSwitch(side->GetTexture(side_t::bottom))) != NULL) { + // Check 3D floors on back side + { + sector_t * back = line->sidedef[1 - sideno]->sector; + for (unsigned i = 0; i < back->e->XFloor.ffloors.Size(); i++) + { + F3DFloor *rover = back->e->XFloor.ffloors[i]; + if (!(rover->flags & FF_EXISTS)) continue; + if (!(rover->flags & FF_LOWERTEXTURE)) continue; + + if (user->z > rover->top.plane->ZatPoint(checkx, checky) || + user->z + user->height < rover->bottom.plane->ZatPoint(checkx, checky)) + continue; + + // This 3D floor depicts a switch texture in front of the player's eyes + return true; + } + } + return (user->z < open.bottom); } else if ((flags & ML_3DMIDTEX) || (TexMan.FindSwitch(side->GetTexture(side_t::mid))) != NULL) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 9fd631d16..89299e0fa 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -5893,6 +5893,103 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetRipMax) self->RipLevelMax = max; } +//========================================================================== +// +// A_CheckProximity(jump, classname, distance, count, flags, ptr) +// +// Checks to see if a certain actor class is close to the +// actor/pointer within distance, in numbers. +//========================================================================== +enum CPXFflags +{ + CPXF_ANCESTOR = 1, + CPXF_LESSOREQUAL = 1 << 1, + CPXF_NOZ = 1 << 2, + CPXF_COUNTDEAD = 1 << 3, + CPXF_DEADONLY = 1 << 4, + CPXF_EXACT = 1 << 5, +}; +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckProximity) +{ + ACTION_PARAM_START(6); + ACTION_PARAM_STATE(jump, 0); + ACTION_PARAM_CLASS(classname, 1); + ACTION_PARAM_FIXED(distance, 2); + ACTION_PARAM_INT(count, 3); + ACTION_PARAM_INT(flags, 4); + ACTION_PARAM_INT(ptr, 5); + + ACTION_SET_RESULT(false); //No inventory chain results please. + AActor *ref = COPY_AAPTR(self, ptr); + + //We need these to check out. + if (!ref || !jump || !classname || distance <= 0) + return; + + int counter = 0; + bool result = false; + + TThinkerIterator it; + AActor * mo; + + //[MC] Process of elimination, I think, will get through this as quickly and + //efficiently as possible. + while ((mo = it.Next())) + { + if (mo == ref) //Don't count self. + continue; + + //Check inheritance for the classname. Taken partly from CheckClass DECORATE function. + if (flags & CPXF_ANCESTOR) + { + if (!(mo->GetClass()->IsAncestorOf(classname))) + continue; + } + //Otherwise, just check for the regular class name. + else if (classname != mo->GetClass()) + continue; + + //Make sure it's in range and respect the desire for Z or not. + if (P_AproxDistance(ref->x - mo->x, ref->y - mo->y) < distance && + ((flags & CPXF_NOZ) || + ((ref->z > mo->z && ref->z - (mo->z + mo->height) < distance) || + (ref->z <= mo->z && mo->z - (ref->z + ref->height) < distance)))) + { + if (mo->flags6 & MF6_KILLED) + { + if (!(flags & (CPXF_COUNTDEAD | CPXF_DEADONLY))) + continue; + counter++; + } + else + { + if (flags & CPXF_DEADONLY) + continue; + counter++; + } + + //Abort if the number of matching classes nearby is greater, we have obviously succeeded in our goal. + if (counter > count) + { + result = (flags & (CPXF_LESSOREQUAL | CPXF_EXACT)) ? false : true; + break; + } + } + } + + if (counter == count) + result = true; + else if (counter < count) + result = !!((flags & CPXF_LESSOREQUAL) && !(flags & CPXF_EXACT)); + + + + if (result) + { + ACTION_JUMP(jump); + } +} + /*=========================================================================== A_CheckBlock (state block, int flags, int ptr) @@ -5951,4 +6048,4 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckBlock) { ACTION_JUMP(block); } -} \ No newline at end of file +} diff --git a/src/version.h b/src/version.h index f33f0999a..0cb89765d 100644 --- a/src/version.h +++ b/src/version.h @@ -76,7 +76,7 @@ const char *GetVersionString(); // Use 4500 as the base git save version, since it's higher than the // SVN revision ever got. -#define SAVEVER 4524 +#define SAVEVER 4525 #define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x) diff --git a/src/win32/i_system.cpp b/src/win32/i_system.cpp index ef56c7050..133337af5 100644 --- a/src/win32/i_system.cpp +++ b/src/win32/i_system.cpp @@ -1726,3 +1726,36 @@ FString I_GetLongPathName(FString shortpath) delete[] buff; return longpath; } + +#if _MSC_VER == 1900 && defined(_USING_V110_SDK71_) +//========================================================================== +// +// VS14Stat +// +// Work around an issue where stat doesn't work with v140_xp. This was +// supposedly fixed, but as of Update 1 continues to not function on XP. +// +//========================================================================== + +#include + +int VS14Stat(const char *path, struct _stat64i32 *buffer) +{ + WIN32_FILE_ATTRIBUTE_DATA data; + if(!GetFileAttributesEx(path, GetFileExInfoStandard, &data)) + return -1; + + buffer->st_ino = 0; + buffer->st_mode = ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? S_IFDIR : S_IFREG)| + ((data.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? S_IREAD : S_IREAD|S_IWRITE); + buffer->st_dev = buffer->st_rdev = 0; + buffer->st_nlink = 1; + buffer->st_uid = 0; + buffer->st_gid = 0; + buffer->st_size = data.nFileSizeLow; + buffer->st_atime = (*(QWORD*)&data.ftLastAccessTime) / 10000000 - 11644473600LL; + buffer->st_mtime = (*(QWORD*)&data.ftLastWriteTime) / 10000000 - 11644473600LL; + buffer->st_ctime = (*(QWORD*)&data.ftCreationTime) / 10000000 - 11644473600LL; + return 0; +} +#endif diff --git a/tools/lemon/lemon.c b/tools/lemon/lemon.c index 5e8f03a8b..651e43f20 100644 --- a/tools/lemon/lemon.c +++ b/tools/lemon/lemon.c @@ -3061,6 +3061,7 @@ struct lemon *lemp; FILE *in; char *tpltname; char *cp; + Boolean tpltnameinbuf; cp = strrchr(lemp->filename,'.'); if( cp ){ @@ -3070,10 +3071,13 @@ struct lemon *lemp; } if( access(buf,004)==0 ){ tpltname = buf; + tpltnameinbuf = LEMON_TRUE; }else if( access(templatename,004)==0 ){ tpltname = templatename; + tpltnameinbuf = LEMON_TRUE; }else{ tpltname = pathsearch(lemp->argv0,templatename,0); + tpltnameinbuf = LEMON_FALSE; } if( tpltname==0 ){ fprintf(stderr,"Can't find the parser driver template file \"%s\".\n", @@ -3084,11 +3088,11 @@ struct lemon *lemp; in = fopen(tpltname,"rb"); if( in==0 ){ fprintf(stderr,"Can't open the template file \"%s\".\n",templatename); - free(tpltname); + if (tpltnameinbuf == LEMON_FALSE) free(tpltname); lemp->errorcnt++; return 0; } - free(tpltname); + if (tpltnameinbuf == LEMON_FALSE) free(tpltname); return in; } diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index be4b8b416..5158aa7b5 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -337,6 +337,7 @@ ACTOR Actor native //: Thinker action native A_SetRipperLevel(int level); action native A_SetRipMin(int min); action native A_SetRipMax(int max); + action native A_CheckProximity(state jump, class classname, float distance, int count = 1, int flags = 0, int ptr = AAPTR_DEFAULT); action native A_CheckBlock(state block, int flags = 0, int ptr = AAPTR_DEFAULT); action native A_CheckSightOrRange(float distance, state label, bool two_dimension = false); action native A_CheckRange(float distance, state label, bool two_dimension = false); diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index 7f8fbc09e..956ed119f 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -484,6 +484,17 @@ enum QF_WAVE = 1 << 5, }; +// A_CheckProximity flags +enum +{ + CPXF_ANCESTOR = 1, + CPXF_LESSOREQUAL = 1 << 1, + CPXF_NOZ = 1 << 2, + CPXF_COUNTDEAD = 1 << 3, + CPXF_DEADONLY = 1 << 4, + CPXF_EXACT = 1 << 5, +}; + // Flags for A_CheckBlock // These flags only affect the calling actor('s pointer), not the ones being searched. enum