diff --git a/src/c_cvars.cpp b/src/c_cvars.cpp index fe859cb49c..11ebf55748 100644 --- a/src/c_cvars.cpp +++ b/src/c_cvars.cpp @@ -1617,8 +1617,16 @@ void C_ArchiveCVars (FConfigFile *f, uint32 filter) } } +EXTERN_CVAR(Bool, sv_cheats); + void FBaseCVar::CmdSet (const char *newval) { + if ((GetFlags() & CVAR_CHEAT) && !sv_cheats) + { + Printf("sv_cheats must be true to set this console variable.\n"); + return; + } + UCVarValue val; // Casting away the const is safe in this case. diff --git a/src/c_cvars.h b/src/c_cvars.h index cf6975b866..98dc71915c 100644 --- a/src/c_cvars.h +++ b/src/c_cvars.h @@ -63,6 +63,7 @@ enum CVAR_NOSAVE = 4096, // when used with CVAR_SERVERINFO, do not save var to savegame CVAR_MOD = 8192, // cvar was defined by a mod CVAR_IGNORE = 16384,// do not send cvar across the network/inaccesible from ACS (dummy mod cvar) + CVAR_CHEAT = 32768,// can be set only when sv_cheats is enabled }; union UCVarValue diff --git a/src/d_main.cpp b/src/d_main.cpp index 2670221c09..fb4acefdaa 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1395,6 +1395,10 @@ void ParseCVarInfo() { cvarflags &= ~CVAR_ARCHIVE; } + else if (stricmp(sc.String, "cheat") == 0) + { + cvarflags |= CVAR_CHEAT; + } else { sc.ScriptError("Unknown cvar attribute '%s'", sc.String); @@ -2704,6 +2708,7 @@ void D_DoomMain (void) S_Shutdown(); // free all channels and delete playlist C_ClearAliases(); // CCMDs won't be reinitialized so these need to be deleted here DestroyCVarsFlagged(CVAR_MOD); // Delete any cvar left by mods + FS_Close(); // destroy the global FraggleScript. GC::FullGC(); // clean up before taking down the object list. diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index 313ee7389c..7468b6dabb 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -69,6 +69,7 @@ FNamespaceManager Namespaces; FTypeTable TypeTable; TArray PClass::AllClasses; +TArray PClass::FunctionPtrList; bool PClass::bShutdown; bool PClass::bVMOperational; @@ -2840,6 +2841,12 @@ void PClass::StaticShutdown () TArray uniqueFPs(64); unsigned int i, j; + // delete all variables containing pointers to script functions. + for (auto p : FunctionPtrList) + { + *p = nullptr; + } + FunctionPtrList.Clear(); // Make a full garbage collection here so that all destroyed but uncollected higher level objects that still exist can be properly taken down. GC::FullGC(); @@ -3547,6 +3554,16 @@ VMFunction *PClass::FindFunction(FName clsname, FName funcname) return func->Variants[0].Implementation; } +void PClass::FindFunction(VMFunction **pptr, FName clsname, FName funcname) +{ + auto cls = PClass::FindActor(clsname); + if (!cls) return; + auto func = dyn_cast(cls->Symbols.FindSymbol(funcname, true)); + if (!func) return; + *pptr = func->Variants[0].Implementation; + FunctionPtrList.Push(pptr); +} + /* FTypeTable **************************************************************/ diff --git a/src/dobjtype.h b/src/dobjtype.h index 632ef96bbd..2726ebff11 100644 --- a/src/dobjtype.h +++ b/src/dobjtype.h @@ -848,9 +848,11 @@ public: static PClassActor *FindActor(ENamedName name) { return FindActor(FName(name)); } static PClassActor *FindActor(FName name); static VMFunction *FindFunction(FName cls, FName func); + static void FindFunction(VMFunction **pptr, FName cls, FName func); PClass *FindClassTentative(FName name); static TArray AllClasses; + static TArray FunctionPtrList; static bool bShutdown; static bool bVMOperational; diff --git a/src/g_inventory/a_pickups.cpp b/src/g_inventory/a_pickups.cpp index cd4d02f04a..fc35d2da4a 100644 --- a/src/g_inventory/a_pickups.cpp +++ b/src/g_inventory/a_pickups.cpp @@ -522,7 +522,7 @@ DEFINE_ACTION_FUNCTION(AInventory, DoRespawn) bool AInventory::CallTryPickup(AActor *toucher, AActor **toucher_return) { static VMFunction *func = nullptr; - if (func == nullptr) func = PClass::FindFunction(NAME_Inventory, NAME_CallTryPickup); + if (func == nullptr) PClass::FindFunction(&func, NAME_Inventory, NAME_CallTryPickup); VMValue params[2] = { (DObject*)this, toucher }; VMReturn ret[2]; int res; diff --git a/src/g_statusbar/sbarinfo_commands.cpp b/src/g_statusbar/sbarinfo_commands.cpp index 5e12bf9d05..c3950571f1 100644 --- a/src/g_statusbar/sbarinfo_commands.cpp +++ b/src/g_statusbar/sbarinfo_commands.cpp @@ -1437,7 +1437,7 @@ class CommandDrawNumber : public CommandDrawString { // num = statusBar.CPlayer.mo.GetEffectTicsForItem(inventoryItem) / TICRATE + 1; static VMFunction *func = nullptr; - if (func == nullptr) func = PClass::FindFunction(NAME_PlayerPawn, "GetEffectTicsForItem"); + if (func == nullptr) PClass::FindFunction(&func, NAME_PlayerPawn, "GetEffectTicsForItem"); VMValue params[] = { statusBar->CPlayer->mo, inventoryItem }; int retv; VMReturn ret(&retv); @@ -2830,7 +2830,7 @@ class CommandDrawBar : public SBarInfoCommand // [value, max] = statusBar.CPlayer.mo.GetEffectTicsForItem(inventoryItem); // value++; max++; static VMFunction *func = nullptr; - if (func == nullptr) func = PClass::FindFunction(NAME_PlayerPawn, "GetEffectTicsForItem"); + if (func == nullptr) PClass::FindFunction(&func, NAME_PlayerPawn, "GetEffectTicsForItem"); VMValue params[] = { statusBar->CPlayer->mo, data.inventoryItem }; VMReturn ret[2]; int ival; diff --git a/src/gl/utility/gl_clock.cpp b/src/gl/utility/gl_clock.cpp index 68a2b06e58..2377029c2d 100644 --- a/src/gl/utility/gl_clock.cpp +++ b/src/gl/utility/gl_clock.cpp @@ -40,6 +40,8 @@ #include #define USE_WINDOWS_DWORD +#elif defined __APPLE__ +#include #endif #include "i_system.h" @@ -114,6 +116,15 @@ void gl_CalculateCPUSpeed () gl_SecondsPerCycle = 1.0 / CyclesPerSecond; gl_MillisecPerCycle = 1000.0 / CyclesPerSecond; } + #elif defined __APPLE__ + long long frequency; + size_t size = sizeof frequency; + + if (0 == sysctlbyname("machdep.tsc.frequency", &frequency, &size, nullptr, 0) && 0 != frequency) + { + gl_SecondsPerCycle = 1.0 / frequency; + gl_MillisecPerCycle = 1000.0 / frequency; + } #endif } diff --git a/src/gl/utility/gl_clock.h b/src/gl/utility/gl_clock.h index 4d5163d86f..2ccda639a8 100644 --- a/src/gl/utility/gl_clock.h +++ b/src/gl/utility/gl_clock.h @@ -7,11 +7,11 @@ extern bool gl_benching; -#ifdef _MSC_VER - extern double gl_SecondsPerCycle; extern double gl_MillisecPerCycle; +#ifdef _MSC_VER + __forceinline long long GetClockCycle () { #if _M_X64 @@ -21,10 +21,14 @@ __forceinline long long GetClockCycle () #endif } -#elif defined(__GNUG__) && defined(__i386__) +#elif defined __APPLE__ && (defined __i386__ || defined __x86_64__) -extern double gl_SecondsPerCycle; -extern double gl_MillisecPerCycle; +inline long long GetClockCycle() +{ + return __builtin_ia32_rdtsc(); +} + +#elif defined(__GNUG__) && defined(__i386__) inline long long GetClockCycle() { @@ -42,21 +46,12 @@ inline long long GetClockCycle() #else -extern double gl_SecondsPerCycle; -extern double gl_MillisecPerCycle; - inline long long GetClockCycle () { return 0; } #endif -#if defined (__APPLE__) - -typedef cycle_t glcycle_t; - -#else // !__APPLE__ - class glcycle_t { public: @@ -100,8 +95,6 @@ private: long long Counter; }; -#endif // __APPLE__ - extern glcycle_t RenderWall,SetupWall,ClipWall; extern glcycle_t RenderFlat,SetupFlat; extern glcycle_t RenderSprite,SetupSprite; @@ -122,4 +115,4 @@ void CheckBench(); void checkBenchActive(); -#endif \ No newline at end of file +#endif diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index 2f99ea61c1..23c2f1ded7 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -478,7 +478,7 @@ void cht_DoCheat (player_t *player, int cheat) if (player->mo != NULL && player->health >= 0) { static VMFunction *gsp = nullptr; - if (gsp == nullptr) gsp = PClass::FindFunction(NAME_Sigil, NAME_GiveSigilPiece); + if (gsp == nullptr) PClass::FindFunction(&gsp, NAME_Sigil, NAME_GiveSigilPiece); if (gsp) { VMValue params[1] = { player->mo }; diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 24142e0ec5..e346579c4c 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -6203,7 +6203,7 @@ static bool CharArrayParms(int &capacity, int &offset, int &a, int *Stack, int & static void SetMarineWeapon(AActor *marine, int weapon) { static VMFunction *smw = nullptr; - if (smw == nullptr) smw = PClass::FindFunction(NAME_ScriptedMarine, NAME_SetWeapon); + if (smw == nullptr) PClass::FindFunction(&smw, NAME_ScriptedMarine, NAME_SetWeapon); if (smw) { VMValue params[2] = { marine, weapon }; @@ -6214,7 +6214,7 @@ static void SetMarineWeapon(AActor *marine, int weapon) static void SetMarineSprite(AActor *marine, PClassActor *source) { static VMFunction *sms = nullptr; - if (sms == nullptr) sms = PClass::FindFunction(NAME_ScriptedMarine, NAME_SetSprite); + if (sms == nullptr) PClass::FindFunction(&sms, NAME_ScriptedMarine, NAME_SetSprite); if (sms) { VMValue params[2] = { marine, source }; diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index e93f41ce53..2926e4e8cf 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -2049,7 +2049,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Look) } } - if (self->target) + if (self->target && self->SeeState) { self->SetState (self->SeeState); } diff --git a/src/p_setup.cpp b/src/p_setup.cpp index df41345f42..a4e4ef1b9a 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -3423,6 +3423,17 @@ extern polyblock_t **PolyBlockMap; void P_FreeLevelData () { + MapThingsConverted.Clear(); + MapThingsUserDataIndex.Clear(); + MapThingsUserData.Clear(); + linemap.Clear(); + FCanvasTextureInfo::EmptyList(); + R_FreePastViewers(); + P_ClearUDMFKeys(); + + // [RH] Clear all ThingID hash chains. + AActor::ClearTIDHashes(); + P_FreeMapDataBackup(); interpolator.ClearInterpolations(); // [RH] Nothing to interpolate on a fresh level. Renderer->CleanLevelData(); @@ -3575,14 +3586,6 @@ void P_SetupLevel (const char *lumpname, int position) level.maptype = MAPTYPE_UNKNOWN; wminfo.partime = 180; - MapThingsConverted.Clear(); - MapThingsUserDataIndex.Clear(); - MapThingsUserData.Clear(); - linemap.Clear(); - FCanvasTextureInfo::EmptyList (); - R_FreePastViewers (); - P_ClearUDMFKeys(); - if (!savegamerestore) { for (i = 0; i < MAXPLAYERS; ++i) @@ -3612,8 +3615,6 @@ void P_SetupLevel (const char *lumpname, int position) // Make sure all sounds are stopped before Z_FreeTags. S_Start (); - // [RH] Clear all ThingID hash chains. - AActor::ClearTIDHashes (); // [RH] clear out the mid-screen message C_MidPrint (NULL, NULL); diff --git a/src/posix/cocoa/i_system.mm b/src/posix/cocoa/i_system.mm index 2e27a80028..35b71c64b8 100644 --- a/src/posix/cocoa/i_system.mm +++ b/src/posix/cocoa/i_system.mm @@ -36,6 +36,7 @@ #include #include #include +#include #include "d_ticcmd.h" #include "doomdef.h" @@ -98,9 +99,29 @@ void SetLanguageIDs() void I_InitTimer(); void I_ShutdownTimer(); +double PerfToSec, PerfToMillisec; + +static void CalculateCPUSpeed() +{ + long long frequency; + size_t size = sizeof frequency; + + if (0 == sysctlbyname("machdep.tsc.frequency", &frequency, &size, nullptr, 0) && 0 != frequency) + { + PerfToSec = 1.0 / frequency; + PerfToMillisec = 1000.0 / frequency; + + if (!batchrun) + { + Printf("CPU speed: %.0f MHz\n", 0.001 / PerfToMillisec); + } + } +} + void I_Init(void) { CheckCPUID(&CPU); + CalculateCPUSpeed(); DumpCPUInfo(&CPU); atterm(I_ShutdownSound); diff --git a/src/posix/cocoa/i_video.mm b/src/posix/cocoa/i_video.mm index 7b5bdec8e8..d7791c43ce 100644 --- a/src/posix/cocoa/i_video.mm +++ b/src/posix/cocoa/i_video.mm @@ -546,6 +546,9 @@ CocoaVideo::CocoaVideo() { memset(&m_modeIterator, 0, sizeof m_modeIterator); + extern void gl_CalculateCPUSpeed(); + gl_CalculateCPUSpeed(); + // Create OpenGL pixel format NSOpenGLPixelFormat* pixelFormat = CreatePixelFormat(OpenGLProfile::Core); diff --git a/src/stats.cpp b/src/stats.cpp index c57b326401..237436c413 100644 --- a/src/stats.cpp +++ b/src/stats.cpp @@ -42,15 +42,6 @@ #include "m_swap.h" #include "sbar.h" - -#if defined (__APPLE__) - -mach_timebase_info_data_t cycle_t::s_info; -bool cycle_t::s_initialized; - -#endif // __APPLE__ - - FStat *FStat::FirstStat; FStat::FStat (const char *name) diff --git a/src/stats.h b/src/stats.h index d90efa7e40..f18159616d 100644 --- a/src/stats.h +++ b/src/stats.h @@ -36,78 +36,7 @@ #include "zstring.h" -#ifndef _WIN32 - -#if defined (__APPLE__) - - -#include - - -class cycle_t -{ -public: - cycle_t() - { - if ( !s_initialized ) - { - mach_timebase_info( &s_info ); - s_initialized = true; - } - - Reset(); - } - - cycle_t &operator=( const cycle_t &other ) - { - if ( &other != this ) - { - m_seconds = other.m_seconds; - - } - - return *this; - } - - void Reset() - { - m_seconds = 0; - } - - void Clock() - { - m_seconds -= Nanoseconds() * 1e-9; - } - - void Unclock() - { - m_seconds += Nanoseconds() * 1e-9; - } - - double Time() - { - return m_seconds; - } - - double TimeMS() - { - return m_seconds * 1e3; - } - -private: - double m_seconds; - - static mach_timebase_info_data_t s_info; - static bool s_initialized; - - uint64_t Nanoseconds() const - { - return mach_absolute_time() * s_info.numer / s_info.denom; - } - -}; - -#else // !__APPLE__ +#if !defined _WIN32 && !defined __APPLE__ #ifdef NO_CLOCK_GETTIME class cycle_t @@ -171,11 +100,9 @@ private: #endif -#endif // __APPLE__ - #else -// Windows +// Windows and macOS #include "x86.h" extern double PerfToSec, PerfToMillisec; @@ -199,15 +126,19 @@ inline unsigned __int64 rdtsc() #else inline unsigned long long rdtsc() { -#ifndef __amd64__ +#ifdef __amd64__ + unsigned long long tsc; + asm volatile ("rdtsc; shlq $32, %%rdx; orq %%rdx, %%rax" : "=a" (tsc) :: "%rdx"); + return tsc; +#else // i386 if (CPU.bRDTSC) -#endif { - register unsigned long long tsc; + unsigned long long tsc; asm volatile ("\trdtsc\n" : "=A" (tsc)); return tsc; } return 0; +#endif // __amd64__ } #endif diff --git a/wadsrc/static/zscript/shared/movingcamera.txt b/wadsrc/static/zscript/shared/movingcamera.txt index 0fc50f3e2f..15fdd08368 100644 --- a/wadsrc/static/zscript/shared/movingcamera.txt +++ b/wadsrc/static/zscript/shared/movingcamera.txt @@ -287,7 +287,7 @@ class PathFollower : Actor if (Interpolate ()) { - Time += (8. / (CurrNode.args[1] * TICRATE)); + Time += (8. / (max(1, CurrNode.args[1]) * TICRATE)); if (Time > 1.) { Time -= 1.; diff --git a/wadsrc_lights/static/filter/hexen/gldefs.txt b/wadsrc_lights/static/filter/hexen/gldefs.txt index d72b9c76f6..cc9513d978 100644 --- a/wadsrc_lights/static/filter/hexen/gldefs.txt +++ b/wadsrc_lights/static/filter/hexen/gldefs.txt @@ -1345,7 +1345,7 @@ flickerlight2 FIREBULL attenuate 1 color 1.0 0.7 0.0 size 96 - secondarysize - 105 + secondarysize 130 interval 0.1 offset 0 40 0 }