Skip to content

Commit

Permalink
Improve Classic DOOM's memory safety and Framerate Interpolation
Browse files Browse the repository at this point in the history
  • Loading branch information
MadDeCoDeR committed Nov 13, 2024
1 parent 758958f commit 75ca1fc
Show file tree
Hide file tree
Showing 13 changed files with 84 additions and 81 deletions.
4 changes: 3 additions & 1 deletion doomclassic/doom/constructs.h
Original file line number Diff line number Diff line change
Expand Up @@ -911,4 +911,6 @@ ::g->totalmus = 68;

::g->mapmax = 0;

::g->lastMasocTick = 0;
::g->lastMasocTick = 0;

::g->accumulatedTimeDeltas.resize(100); //GK: For that to be exceeded the game must run more than @3500 or @4000 FPS
29 changes: 18 additions & 11 deletions doomclassic/doom/d_net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -671,7 +671,23 @@ void D_QuitNetGame (void)
}

//GK: Begin
//
/**
* CalculateInterpolationCheckSkips
*
* Calculate and check if the engine's frameTime is slower than the expected frameTime and if it is accumulate interpolaction check skips in order to not lose any frames
*/
void CalculateInterpolationCheckSkips(int timeDelta, float expectedFrameMs, int index) {
if (index == 100) { //We only use 100 entries to keep the accumulated FrameTimes, if it run out just skip and start playing the frames
return;
}
::g->accumulatedTimeDeltas[index] += timeDelta - expectedFrameMs;
if (::g->accumulatedTimeDeltas[index] >= expectedFrameMs) {
::g->skipTicInterpolationCheck++;
CalculateInterpolationCheckSkips(::g->accumulatedTimeDeltas[index], expectedFrameMs, index + 1);
::g->accumulatedTimeDeltas[index] = 0;
}
}

// InterpolateTics
//
// Check if the current tic must run or not.
Expand All @@ -682,16 +698,7 @@ bool InterpolateTics() {
float expectedFrameMs = 1000.0f / cl_engineHz.GetFloat();
::g->timeDelta = currentTime - ::g->lastTicTime;
if (::g->timeDelta >= expectedFrameMs) {
::g->accumulatedTimeDelta += ::g->timeDelta - expectedFrameMs;
if (::g->accumulatedTimeDelta >= expectedFrameMs) {
::g->accumulatedTimeDelta2 += ::g->accumulatedTimeDelta - expectedFrameMs;
if (::g->accumulatedTimeDelta2 >= expectedFrameMs) {
::g->skipTicInterpolationCheck++;
::g->accumulatedTimeDelta2 = 0;
}
::g->skipTicInterpolationCheck++;
::g->accumulatedTimeDelta = 0;
}
CalculateInterpolationCheckSkips(::g->timeDelta, expectedFrameMs, 0);
::g->lastTicTime = currentTime;
return true;
}
Expand Down
10 changes: 5 additions & 5 deletions doomclassic/doom/doomlib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -466,14 +466,14 @@ void DoomLib::Shutdown() {
globaldata[currentplayer] = NULL;
//CleanVector(glob->activeceilings); //GK: Contains memory managed by the Zone Memory. Skip
//CleanVector(glob->activeplats); //GK: Contains memory managed by the Zone Memory. Skip
CleanVector(glob->intercepts);
CleanVector(glob->drawsegs);
glob->intercepts.clear();
glob->drawsegs.clear();
CleanVector(glob->sprites);
CleanVector(glob->vissprites);
glob->vissprites.clear();
CleanVector(glob->cpatch);
CleanVector(glob->visplanes);
glob->visplanes.clear();
CleanVector(glob->reverbs);
CleanVector(glob->sector_list);
glob->sector_list.clear();
for (size_t j = 0; j < glob->acts.size(); j++) {
CleanVector(glob->acts[j]);
}
Expand Down
2 changes: 1 addition & 1 deletion doomclassic/doom/p_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ typedef struct

#define MAXINTERCEPTS 128 //GK:Not needed
//GK:From now on it uses indexed vectors (for now until and if I found something better)
extern std::vector<intercept_t*> intercepts;
extern std::vector<std::unique_ptr<intercept_t>> intercepts;
//extern intercept_t* intercept_p;

typedef qboolean (*traverser_t) (intercept_t *in);
Expand Down
22 changes: 12 additions & 10 deletions doomclassic/doom/p_map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -571,25 +571,26 @@ void P_AddSecnode(sector_t* s, mobj_t* thing)
}

}
msecnode_t* tnode = new msecnode_t();
tnode->visited = 0;

tnode->m_sector = s; // sector
tnode->m_thing = thing; // mobj
//s->touching_thinglist = tnode;

#if _ITERATOR_DEBUG_LEVEL < 2
if (::g->sector_list.size() == ::g->sector_list.capacity()) {
::g->sector_list.reserve(::g->sector_list.size() + 100);
}
//::g->specind = 0;
::g->sector_list.emplace_back(tnode);
msecnode_t* tnode = ::g->sector_list.emplace_back(std::make_unique<msecnode_t>()).get();
#else
if (::g->sector_list.size() == ::g->sector_list.capacity()) {
::g->sector_list.resize(::g->sector_list.size() + 100);
}
::g->sector_list[::g->headsecind] = tnode;
::g->sector_list[::g->headsecind] = std::make_unique<msecnode_t>();
msecnode_t* tnode = ::g->sector_list[::g->headsecind].get();
#endif
::g->headsecind++;
tnode->visited = 0;

tnode->m_sector = s; // sector
tnode->m_thing = thing; // mobj
//s->touching_thinglist = tnode;

//msecnode_t* node;

Expand Down Expand Up @@ -649,7 +650,7 @@ void P_DelSeclist()

{
while(!::g->sector_list.empty()) {
msecnode_t* node = ::g->sector_list[::g->headsecind - 1];
msecnode_t* node = ::g->sector_list[::g->headsecind - 1].get();
::g->sector_list[::g->headsecind - 1] = NULL;
::g->headsecind--;
if (::g->headsecind < 0) {
Expand Down Expand Up @@ -719,8 +720,9 @@ void P_CreateSecNodeList(mobj_t* thing, fixed_t x, fixed_t y)
// finished, delete all nodes where m_thing is still NULL. These
// represent the sectors the Thing has vacated.

for (msecnode_t* node : ::g->sector_list)
for (int i = 0; i < ::g->sector_list.size(); i++)
{
msecnode_t* node = ::g->sector_list[i].get();
if (node != NULL) {
node->m_thing = NULL;
}
Expand Down
10 changes: 5 additions & 5 deletions doomclassic/doom/p_maputl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,7 @@ P_TraverseIntercepts
dist = MAXINT;
for (size_t i = 0 ; i < ::g->interind-1; i++)
{
scan = ::g->intercepts[i];
scan = ::g->intercepts[i].get();
if (scan->frac < dist)
{
dist = scan->frac;
Expand Down Expand Up @@ -810,11 +810,11 @@ P_PathTraverse
if (::g->intercepts.empty()) {
#if _ITERATOR_DEBUG_LEVEL < 2
::g->intercepts.reserve(MAXINTERCEPTS);
::g->intercepts.emplace_back(new intercept_t());
::g->intercepts.emplace_back(std::make_unique<intercept_t>());
#else
::g->intercepts.resize(MAXINTERCEPTS);
for (int ii = 0; ii < MAXINTERCEPTS; ii++) {
::g->intercepts[ii] = new intercept_t();
::g->intercepts[ii] = std::make_unique<intercept_t>();
}
#endif
}
Expand Down Expand Up @@ -932,13 +932,13 @@ void AddNewIntercept() {
if (::g->intercepts.size() == ::g->intercepts.capacity()) {
::g->intercepts.reserve(::g->intercepts.size() + MAXINTERCEPTS);
}
::g->intercepts.emplace_back(new intercept_t());
::g->intercepts.emplace_back(std::make_unique<intercept_t>());
#else
if (::g->intercepts.size() == ::g->intercepts.capacity()) {
::g->intercepts.resize(::g->intercepts.size() + MAXINTERCEPTS);
}
for (int j = ::g->interind; j < ::g->intercepts.size(); j++) {
::g->intercepts[j] = new intercept_t();
::g->intercepts[j] = std::make_unique<intercept_t>();
}
#endif
}
Expand Down
19 changes: 6 additions & 13 deletions doomclassic/doom/p_spec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1709,11 +1709,11 @@ void P_UpdateSpecials (void)
for (ai = 0; ai < ::g->numlinespecials; ai++)
{
// line = ::g->linespeciallist[i];
switch(::g->linespeciallist[ai]->special)
switch(::g->linespeciallist[ai].special)
{
case 48:
// EFFECT FIRSTCOL SCROLL +
::g->sides[::g->linespeciallist[ai]->sidenum[0]].textureoffset += FRACUNIT;
::g->sides[::g->linespeciallist[ai].sidenum[0]].textureoffset += FRACUNIT;
break;
}
}
Expand Down Expand Up @@ -1963,21 +1963,13 @@ void P_SpawnSpecials (void)
case 48:
// EFFECT FIRSTCOL SCROLL+
if (::g->numlinespecials >= ::g->linespeciallist.size()) {
#if _ITERATOR_DEBUG_LEVEL < 2
//::g->linespeciallist.clear();
if (::g->linespeciallist.size() == ::g->linespeciallist.capacity()) {
::g->linespeciallist.reserve(::g->linespeciallist.size() + MAXLINEANIMS);
}
::g->linespeciallist.emplace_back(&::g->lines[i]);
#else
if (::g->linespeciallist.size() == ::g->linespeciallist.capacity()) {
::g->linespeciallist.resize(::g->linespeciallist.size() + MAXLINEANIMS);
}
::g->linespeciallist[::g->numlinespecials] = &::g->lines[i];
#endif
::g->linespeciallist[::g->numlinespecials] = ::g->lines[i];
}
else {
::g->linespeciallist[::g->numlinespecials] = &::g->lines[i];
::g->linespeciallist[::g->numlinespecials] = ::g->lines[i];
}
::g->numlinespecials++;
break;
Expand Down Expand Up @@ -2138,7 +2130,8 @@ void T_Scroll(scroll_t *s)
::g->sectors[sec->heightsec].floorheight > height ?
::g->sectors[sec->heightsec].floorheight : MININT;

for (msecnode_t* node : ::g->sector_list) {
for (int i = 0; i < ::g->sector_list.size(); i++) {
msecnode_t* node = ::g->sector_list[i].get();
if (node != NULL) {
if (node->m_sector == sec) {
if (!((thing = node->m_thing)->flags & MF_NOCLIP) &&
Expand Down
4 changes: 2 additions & 2 deletions doomclassic/doom/r_bsp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,11 @@ void R_ClearDrawSegs (void)
if (::g->drawsegs.empty()) {
#if _ITERATOR_DEBUG_LEVEL < 2
::g->drawsegs.reserve(MAXDRAWSEGS);
::g->drawsegs.emplace_back(new drawseg_t());
::g->drawsegs.emplace_back(std::make_unique<drawseg_t>());
#else
::g->drawsegs.resize(MAXDRAWSEGS);
for (int di = 0; di < MAXDRAWSEGS; di++) {
::g->drawsegs[di] = new drawseg_t();
::g->drawsegs[di] = std::make_unique<drawseg_t>();
}
#endif
}
Expand Down
14 changes: 7 additions & 7 deletions doomclassic/doom/r_plane.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,11 +197,11 @@ void R_ClearPlanes (void)
if (::g->visplanes.empty()) {
#if _ITERATOR_DEBUG_LEVEL < 2
::g->visplanes.reserve(MAXVISPLANES);
::g->visplanes.emplace_back(new visplane_t());
::g->visplanes.emplace_back(std::make_unique<visplane_t>());
#else
::g->visplanes.resize(MAXVISPLANES);
for (int vpi = 0; vpi < MAXVISPLANES; vpi++) {
::g->visplanes[vpi] = new visplane_t();
::g->visplanes[vpi] = std::make_unique<visplane_t>();
}
#endif
}
Expand Down Expand Up @@ -235,13 +235,13 @@ visplane_t* R_FindPlane( fixed_t height, int picnum, int lightlevel,fixed_t xoff
lightlevel = 0;
}
for (uint i = 0; i < ::g->planeind; i++) {
check = ::g->visplanes[i];
check = ::g->visplanes[i].get();
if (height == check->height && picnum == check->picnum && lightlevel == check->lightlevel && xoffs == check->xoffs && check->yoffs) {
break;
}
}

if (check != ::g->visplanes[::g->planeind-1])
if (check != ::g->visplanes[::g->planeind-1].get())
return check;

//if (::g->lastvisplane - ::g->visplanes == MAXVISPLANES)
Expand Down Expand Up @@ -326,7 +326,7 @@ R_CheckPlane
::g->visplanes[::g->planeind-1]->height = pl->height;
::g->visplanes[::g->planeind - 1]->picnum = pl->picnum;
::g->visplanes[::g->planeind - 1]->lightlevel = pl->lightlevel;
pl = ::g->visplanes[::g->planeind - 1];
pl = ::g->visplanes[::g->planeind - 1].get();
AddNewVisplane();
pl->minx = start;
pl->maxx = stop;
Expand Down Expand Up @@ -558,11 +558,11 @@ void AddNewVisplane() {
if (::g->visplanes.size() == ::g->visplanes.capacity()) {
::g->visplanes.reserve(::g->visplanes.size() + MAXVISPLANES);
}
::g->visplanes.emplace_back(new visplane_t());
::g->visplanes.emplace_back(std::make_unique<visplane_t>());
#else
::g->visplanes.resize(::g->visplanes.size() + MAXVISPLANES);
for (int vpi = ::g->planeind; vpi < ::g->visplanes.size(); vpi++) {
::g->visplanes[vpi] = new visplane_t();
::g->visplanes[vpi] = std::make_unique<visplane_t>();
}
#endif
}
Expand Down
6 changes: 3 additions & 3 deletions doomclassic/doom/r_segs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ R_StoreWallRange
sineval = finesine[distangle>>ANGLETOFINESHIFT];
::g->rw_distance = FixedMul (hyp, sineval);

::g->ds_p = ::g->drawsegs[::g->drawsegind - 1];
::g->ds_p = ::g->drawsegs[::g->drawsegind - 1].get();
::g->ds_p->x1 = ::g->rw_x = start;
::g->ds_p->x2 = stop;
::g->ds_p->curline = ::g->curline;
Expand Down Expand Up @@ -737,13 +737,13 @@ void AddDrawSeg() {
if (::g->drawsegs.size() == ::g->drawsegs.capacity()) {
::g->drawsegs.reserve(::g->drawsegs.size() + MAXDRAWSEGS);
}
::g->drawsegs.emplace_back(new drawseg_t());
::g->drawsegs.emplace_back(std::make_unique<drawseg_t>());
#else
if (::g->drawsegs.size() == ::g->drawsegs.capacity()) {
::g->drawsegs.resize(::g->drawsegs.size() + MAXDRAWSEGS);
}
for (int i = ::g->drawsegind; i < ::g->drawsegs.size(); i++) {
::g->drawsegs[i] = new drawseg_t();
::g->drawsegs[i] = std::make_unique<drawseg_t>();
}
#endif
}
Expand Down
Loading

0 comments on commit 75ca1fc

Please sign in to comment.