Compare commits

...
5 Commits
Author SHA1 Message Date
Alug 669b42c4bb remove the loop condition for framelimiter
this was for an older iteration where it ran the loop until it hit the target per condition, keeping like this may cause issue if the loop exits per condition instead of the return block
now we return from within the loop
2026-02-04 18:05:13 +01:00
Alug 2a658a8476 rewrite the framerate limiter
this completely rewrites the old simple sleep based limiter with
whatever tf i came up with at 2am
this almost completely gets rid of any jitter, stutter, uneven framepacing and missing the cap
it might be slightly less efficient due to busy waiting more, but so far it seems to be about the same
2026-02-04 18:05:00 +01:00
Alug 8cab07a4b2 add missing "ifdef LOGMESSAGES" 2026-02-03 15:59:53 +01:00
Alug 55c8546d68 do not use Zone Memory for masterserver rules
this gets called from within non main threads!
zone memory is not thread safe!
2026-02-02 17:27:23 +01:00
Alug 1762f18116 delet all the Z_Free checks
Z_Free already checks its input internally!
2026-02-02 16:12:38 +01:00
23 changed files with 132 additions and 129 deletions

No files matched your search

+70 -24
View File
@@ -653,6 +653,68 @@ static boolean D_Display(void)
return ranwipe;
}
static UINT64 precision = 0;
static precise_t sleeptime = 0;
static void D_LimitFps(void)
{
static precise_t curtime = 0, lasttime = 0;
static precise_t start;
precise_t elapsed = 0;
sleeptime = 0;
// timedemo runs uncapped!
if (singletics)
return;
// in the case of "match refresh rate" + vsync, don't sleep at all
if (cv_vidwait.value && cv_fpscap.value == 0)
return;
const UINT32 framecap = R_GetFramerateCap();
// uncapped obviously does not need to be... capped...
if (framecap == 0)
return;
start = I_GetPreciseTime();
// frametarget in precise_t ticks (ex. 60fps = ~16,666,666)
const precise_t frametarget = precision / framecap;
while (1)
{
// check the current time against the "time of the old frame""
curtime = I_GetPreciseTime();
elapsed = curtime - lasttime;
// done waiting!
// continue as normal
if (elapsed >= frametarget)
{
lasttime = curtime;
// time we spent :chaosleep:ing or doing absolutely nothing
// for frameskip calculations
sleeptime = curtime - start;
return;
}
// if we have more than 1ms to wait
// sleep for a bit to not trash the cpu lul
precise_t remaining = frametarget - elapsed;
if (remaining > (precise_t)(precision / 1000))
{
// sleep for 90% of the time we gotta wait for the next frame
// since we dont wanna oversleep :chaosleep:
I_SleepDuration(9 * remaining / 10);
}
}
// the rest we just be waitin until we meet our frametime target
}
// =========================================================================
// D_SRB2Loop
// =========================================================================
@@ -664,7 +726,6 @@ void D_SRB2Loop(void)
tic_t entertic = 0, oldentertics = 0, realtics = 0, rendertimeout = INFTICS;
double deltatics = 0.0;
double deltasecs = 0.0;
UINT64 precision = 0;
boolean interp = false;
boolean doDisplay = false;
@@ -704,22 +765,16 @@ void D_SRB2Loop(void)
for (;;)
{
// capbudget is the minimum precise_t duration of a single loop iteration
precise_t capbudget;
precise_t elapsed;
precise_t enterprecise, finishprecise;
enterprecise = I_GetPreciseTime();
boolean ranwipe = false;
memset(&g_dc, 0, sizeof(g_dc));
Z_Frame_Reset();
// Casting the return value of a function is bad practice (apparently)
const UINT32 framecap = R_GetFramerateCap();
capbudget = (framecap == 0) ? 0 : (precise_t)((double)precision / (double)framecap + 0.5); // + 0.5 instead of round
boolean ranwipe = false;
I_UpdateTime(cv_timescale.value);
if (lastwipetic)
@@ -809,6 +864,10 @@ void D_SRB2Loop(void)
R_SetTimeFrac(FRACUNIT);
}
// be sure to limit our fps *before* drawing
// so we can properly "pace" our frames
D_LimitFps();
if (interp || doDisplay)
{
if (!frameskip)
@@ -843,9 +902,9 @@ void D_SRB2Loop(void)
// Fully completed frame made.
finishprecise = I_GetPreciseTime();
// Use the time before sleep for frameskip calculations:
// Use the time without sleep for frameskip calculations:
// post-sleep time is literally being intentionally wasted
elapsed = finishprecise - enterprecise;
elapsed = (finishprecise - enterprecise) - sleeptime;
deltasecs = (double)elapsed / (double)precision;
deltatics = deltasecs * (double)NEWTICRATE;
@@ -873,19 +932,6 @@ void D_SRB2Loop(void)
frameskip = 0;
}
if (!singletics)
{
// in the case of "match refresh rate" + vsync, don't sleep at all
const boolean vsync_with_match_refresh = cv_vidwait.value && cv_fpscap.value == 0;
if ((elapsed > 0) && (capbudget > elapsed) && !vsync_with_match_refresh)
{
I_SleepDuration(capbudget - elapsed);
}
}
// Capture the time once more to get the real delta time.
finishprecise = I_GetPreciseTime();
elapsed = finishprecise - enterprecise;
deltasecs = (double)elapsed / (double)precision;
deltatics = deltasecs * (double)NEWTICRATE;
+1 -3
View File
@@ -1172,9 +1172,7 @@ void F_StartWaitingPlayers(void)
randskin = M_RandomKey(numskins);
boolean waithires = skins[randskin].flags && SF_HIRES;
if (waitcolormap)
Z_Free(waitcolormap);
Z_Free(waitcolormap);
waitcolormap = R_GetTranslationColormap(randskin, skins[randskin].prefcolor, 0);
if (waithires)
+6 -8
View File
@@ -317,8 +317,7 @@ void closefilemenu(boolean validsize)
coredirmenu = NULL;
}
if (refreshdirname)
Z_Free(refreshdirname);
Z_Free(refreshdirname);
refreshdirname = NULL;
}
@@ -346,8 +345,7 @@ void searchfilemenu(char *tempname)
if (!menusearch.length)
{
if (dirmenu)
Z_Free(dirmenu);
Z_Free(dirmenu);
dirmenu = coredirmenu;
sizedirmenu = sizecoredirmenu;
@@ -389,8 +387,8 @@ void searchfilemenu(char *tempname)
I_Error("searchfilemenu(): could not create \"No results...\".");
sizedirmenu = 1;
dir_on[menudepthleft] = 0;
if (tempname)
Z_Free(tempname);
Z_Free(tempname);
return;
}
@@ -505,8 +503,8 @@ boolean preparefilemenu(boolean samedepth, boolean replayhut)
{
closedir(dirhandle);
closefilemenu(false);
if (tempname)
Z_Free(tempname);
Z_Free(tempname);
return false;
}
+2 -5
View File
@@ -523,11 +523,8 @@ void G_ClearRecords(void)
INT16 i;
for (i = 0; i < NUMMAPS; ++i)
{
if (mainrecords[i])
{
Z_Free(mainrecords[i]);
mainrecords[i] = NULL;
}
Z_Free(mainrecords[i]);
mainrecords[i] = NULL;
}
}
+2 -1
View File
@@ -225,9 +225,10 @@ HMS_connect (const char *format, ...)
{
cc = curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf);
#ifdef LOGMESSAGES
cc = curl_easy_setopt(curl, CURLOPT_STDERR, logstream);
if (cc != CURLE_OK) I_OutputMsg("libcurl: %s\n", buffer->errbuf);
#endif
}
if (M_CheckParm("-bindaddr") && M_IsNextParm())
+4 -8
View File
@@ -1072,8 +1072,7 @@ static void Got_Saycmd(const UINT8 **p, INT32 playernum)
HU_AddChatText(va(fmt2, prefix, cstart, dispname, textcolor, msg), cv_chatnotifications.value); // add to chat
if (tempchar)
Z_Free(tempchar);
Z_Free(tempchar);
}
#ifdef _DEBUG
// I just want to point out while I'm here that because the data is still
@@ -1569,8 +1568,7 @@ static void HU_drawMiniChat(void)
dy = 0;
dx = 0;
msglines += linescount+1;
if (msg)
Z_Free(msg);
Z_Free(msg);
}
y = chaty - charheight*(msglines+1);
@@ -1657,8 +1655,7 @@ static void HU_drawMiniChat(void)
dy += charheight;
dx = 0;
if (msg)
Z_Free(msg);
Z_Free(msg);
}
// decrement addy and make that shit smooth:
@@ -1767,8 +1764,7 @@ static void HU_drawChatLog(INT32 offset)
dy += charheight;
dx = 0;
if (msg)
Z_Free(msg);
Z_Free(msg);
}
if (((chat_scroll >= chat_maxscroll) || (chat_scrollmedown)) && !(justscrolleddown || justscrolledup || chat_scrolltime)) // was already at the bottom of the page before new maxscroll calculation and was NOT scrolling.
+4 -10
View File
@@ -1510,11 +1510,8 @@ static boolean SOCK_SetBanUsername(const char *username)
username = "Direct IP ban";
}
if (banned[numbans - 1].username)
{
Z_Free(banned[numbans - 1].username);
banned[numbans - 1].username = NULL;
}
Z_Free(banned[numbans - 1].username);
banned[numbans - 1].username = NULL;
banned[numbans - 1].username = Z_StrDup(username);
@@ -1528,11 +1525,8 @@ static boolean SOCK_SetBanReason(const char *reason)
reason = "No reason given";
}
if (banned[numbans - 1].reason)
{
Z_Free(banned[numbans - 1].reason);
banned[numbans - 1].reason = NULL;
}
Z_Free(banned[numbans - 1].reason);
banned[numbans - 1].reason = NULL;
banned[numbans - 1].reason = Z_StrDup(reason);
+1 -2
View File
@@ -99,8 +99,7 @@ void K_EraseStats(void)
// The only field we want to remember
boolean vanilla = kartstats.vanilla;
if (kartstats.copy)
Z_Free(kartstats.copy);
Z_Free(kartstats.copy);
memset(&kartstats, 0, sizeof(kartstats_t));
+3 -12
View File
@@ -136,18 +136,9 @@ void LUA_HUD_DestroyDrawList(huddrawlist_h list)
{
if (list == NULL) return;
if (list->items)
{
Z_Free(list->items);
}
if (list->olditems)
{
Z_Free(list->olditems);
}
if (list->strbuf)
{
Z_Free(list->strbuf);
}
Z_Free(list->items);
Z_Free(list->olditems);
Z_Free(list->strbuf);
Z_Free(list);
}
+3 -6
View File
@@ -695,16 +695,13 @@ INT32 GIF_close(void)
fclose(gif_out);
gif_out = NULL;
if (gifbwr_buf)
Z_Free(gifbwr_buf);
Z_Free(gifbwr_buf);
gifbwr_buf = gifbwr_cur = NULL;
if (gifframe_data)
Z_Free(gifframe_data);
Z_Free(gifframe_data);
gifframe_data = NULL;
if (giflzw_hashTable)
Z_Free(giflzw_hashTable);
Z_Free(giflzw_hashTable);
giflzw_hashTable = NULL;
Z_Free(scrbuf_screens);
+3 -6
View File
@@ -248,12 +248,9 @@ void M_AddRawCondition(UINT8 set, UINT8 id, conditiontype_t c, INT32 r, INT16 x1
void M_ClearConditionSet(UINT8 set)
{
if (conditionSets[set - 1].numconditions)
{
Z_Free(conditionSets[set - 1].condition);
conditionSets[set - 1].condition = NULL;
conditionSets[set - 1].numconditions = 0;
}
Z_Free(conditionSets[set - 1].condition);
conditionSets[set - 1].condition = NULL;
conditionSets[set - 1].numconditions = 0;
conditionSets[set - 1].achieved = false;
}
+10 -6
View File
@@ -5356,7 +5356,7 @@ void M_PopupMasterServerRules(void)
{
firstDismissedRulesThisBoot = false;
M_StartMessage(va("%s\n(press any key)", rules), NULL, MM_NOTHING);
Z_Free(rules);
free(rules);
}
}
#endif
@@ -6560,17 +6560,22 @@ static void M_EraseGuest(INT32 choice)
static void M_OverwriteGuest(const char *which)
{
char *rguest = Z_StrDup(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)));
char *rguest;
UINT8 *buf;
size_t len;
len = FIL_ReadFile(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), cv_chooseskin.string, which), &buf);
if (!len) {
if (!len)
return;
}
if (FIL_FileExists(rguest)) {
rguest = Z_StrDup(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)));
if (FIL_FileExists(rguest))
{
M_StopMessage(0);
remove(rguest);
}
FIL_WriteFile(rguest, buf, len);
Z_Free(rguest);
@@ -7587,7 +7592,6 @@ static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade)
static void M_DrawServerMenu(void)
{
M_DrawLevelSelectOnly(false, false);
#ifdef MASTERSERVER
if (currentMenu == &MP_ServerDef && cv_advertise.value) // Remind players where they're hosting.
+4 -3
View File
@@ -219,8 +219,9 @@ static void Get_masterserver_rules(boolean checkfirst)
if (HMS_fetch_rules(rules, sizeof rules))
{
Lock_state();
Z_Free(MSRules);
MSRules = Z_StrDup(rules);
if (MSRules)
free(MSRules);
MSRules = strdup(rules);
if (MSRegistered == true)
{
@@ -507,7 +508,7 @@ char *GetMasterServerRules(void)
char *rules;
Lock_state();
rules = MSRules ? Z_StrDup(MSRules) : NULL;
rules = MSRules ? strdup(MSRules) : NULL;
Unlock_state();
return rules;
+1 -3
View File
@@ -320,9 +320,7 @@ void P_AddGradesForMare(INT16 i, UINT8 mare, char *gtext)
*/
void P_DeleteGrades(INT16 i)
{
if (mapheaderinfo[i]->grades)
Z_Free(mapheaderinfo[i]->grades);
Z_Free(mapheaderinfo[i]->grades);
mapheaderinfo[i]->grades = NULL;
mapheaderinfo[i]->numGradedMares = 0;
}
+1 -2
View File
@@ -6221,8 +6221,7 @@ void P_SpawnSpecials(INT32 fromnetsave, boolean reloadinggamestate)
// Allocate each list
for (i = 0; i < numsectors; i++)
if(secthinkers[i].thinkers)
Z_Free(secthinkers[i].thinkers);
Z_Free(secthinkers[i].thinkers);
Z_Free(secthinkers);
+1 -2
View File
@@ -1720,8 +1720,7 @@ void R_InitData(void)
void R_ClearTextureNumCache(boolean btell)
{
if (tidcache)
Z_Free(tidcache);
Z_Free(tidcache);
tidcache = NULL;
if (btell)
CONS_Debug(DBG_SETUP, "Fun Fact: There are %d textures used in this map.\n", tidcachelen);
+6 -10
View File
@@ -925,11 +925,11 @@ void R_ExecuteSetViewSize(void)
viewheight = vid.height;
if (splitscreen)
{
viewheight >>= 1;
if (splitscreen > 1)
{
viewwidth >>= 1;
if (splitscreen > 1)
viewwidth >>= 1;
}
centerx = viewwidth/2;
@@ -956,13 +956,9 @@ void R_ExecuteSetViewSize(void)
screenheightarray[i] = (INT16)viewheight;
}
if (ds_su)
Z_Free(ds_su);
if (ds_sv)
Z_Free(ds_sv);
if (ds_sz)
Z_Free(ds_sz);
Z_Free(ds_su);
Z_Free(ds_sv);
Z_Free(ds_sz);
ds_su = ds_sv = ds_sz = NULL;
memset(scalelight, 0xFF, sizeof(scalelight));
+2 -4
View File
@@ -405,10 +405,8 @@ static void Patch_FreeData(patch_t *patch)
}*/
#endif
if (patch->columnofs)
Z_Free(patch->columnofs);
if (patch->columns)
Z_Free(patch->columns);
Z_Free(patch->columnofs);
Z_Free(patch->columns);
}
void Patch_Free(patch_t *patch)
+1 -1
View File
@@ -391,7 +391,7 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16
// allocate space for the frames present and copy sprtemp to it
if (spritedef->numframes && // has been allocated
spritedef->numframes < maxframe) // more frames are defined ?
spritedef->numframes < maxframe) // more frames are defined ?
{
Z_Free(spritedef->spriteframes);
+2 -5
View File
@@ -1841,18 +1841,15 @@ static void I_Fork(void)
I_RegisterChildSignals();
break;
default:
#ifdef LOGMESSAGES
if (logstream)
fclose(logstream);/* the child has this */
#endif
c = wait(&status);
#ifdef LOGMESSAGES
/* By the way, exit closes files. */
logstream = fopen(logfilename, "at");
#else
logstream = 0;
#endif
if (c == -1)
{
kill(child, SIGKILL);
+1 -3
View File
@@ -3716,9 +3716,7 @@ void V_DoPostProcessor(INT32 view, INT32 param)
// Make sure table is built
if (heatshifter == NULL || lastheight != viewheight)
{
if (heatshifter)
Z_Free(heatshifter);
Z_Free(heatshifter);
heatshifter = Z_Calloc(viewheight * sizeof(boolean), PU_STATIC, NULL);
for (y = 0; y < viewheight; y++)
+3 -4
View File
@@ -122,7 +122,9 @@ void W_Shutdown(void)
if (wad->handle)
fclose(wad->handle);
Z_Free(wad->filename);
while (wad->numlumps--)
{
Z_Free(wad->lumpinfo[wad->numlumps].longname);
@@ -2730,10 +2732,7 @@ void vres_Free(virtres_t* vres)
while (vres->numlumps--)
{
if (vres->vlumps[vres->numlumps].data)
{
Z_Free(vres->vlumps[vres->numlumps].data);
}
Z_Free(vres->vlumps[vres->numlumps].data);
}
Z_Free(vres->vlumps);
+1 -1
View File
@@ -91,7 +91,7 @@ void Z_Init(void);
// Z_Free and alloc with alignment
#ifdef ZDEBUG
#define Z_Free(p) Z_Free2(p, __FILE__, __LINE__)
#define Z_Free(p) Z_Free2(p, __FILE__, __LINE__)
#define Z_Malloc(s,t,u) Z_Malloc2(s, t, u, __FILE__, __LINE__)
#define Z_Calloc(s,t,u) Z_Calloc2(s, t, u, __FILE__, __LINE__)
#define Z_Realloc(p,s,t,u) Z_Realloc2(p,s, t, u, __FILE__, __LINE__)