Forum

Bug fix - Framerate-independent Damage and Bonus shifts

Post tutorials on how to do certain tasks within game or engine code here.

Moderator: InsideQC Admins

Bug fix - Framerate-independent Damage and Bonus shifts

Postby mh » Wed Jun 06, 2012 12:11 am

When damage and bonus shifts drop their percentages each frame the timing can be all wrong because the percent member is an int - no matter what speed you're running at you'll get something incorrect for the drop rate owing to rounding-off.

Add these two to the cshift_t struct:
Code: Select all
   double   time;
   int      initialpct;

In V_ParseDamage, pop this somewhere near the bottom:
Code: Select all
   cl.cshifts[CSHIFT_DAMAGE].initialpct = cl.cshifts[CSHIFT_DAMAGE].percent;
   cl.cshifts[CSHIFT_DAMAGE].time = cl.time;

And this in V_BonusFlash_f:
Code: Select all
   cl.cshifts[CSHIFT_BONUS].initialpct = 50;
   cl.cshifts[CSHIFT_BONUS].time = cl.time;

Add this somewhere above your V_UpdatePalette:
Code: Select all
void V_DropCShift (cshift_t *cs, float droprate)
{
   if (cs->time < 0)
      cs->percent = 0;
   else if ((cs->percent = cs->initialpct - (cl.time - cs->time) * droprate) <= 0)
   {
      cs->percent = 0;
      cs->time = -1;
   }
}

And replace the old drop-off code for these two shifts with this:
Code: Select all
   // drop the damage and bonus values
   V_DropCShift (&cl.cshifts[CSHIFT_DAMAGE], 150);
   V_DropCShift (&cl.cshifts[CSHIFT_BONUS], 100);

They'll now drop at the correct rate no matter what speed you're running at.

You can also do the same with dynamic lights - store spawntime as cl.time in CL_AllocDlight, set initialradius to the same as radius for each light, then radius in CL_DecayLights becomes "dl->radius = dl->initialradius - (cl.time - dl->spawntime) * dl->decay;"
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
User avatar
mh
 
Posts: 2282
Joined: Sat Jan 12, 2008 1:38 am

Re: Bug fix - Framerate-independent Damage and Bonus shifts

Postby taniwha » Mon Jun 11, 2012 11:22 pm

I've implemented this too in qf. Still can't push :(

I couldn't see any difference, but qf is still locked to 72fps and thus might not cause as much trouble. But then, not seeing any difference might be a good thing: I didn't break anything in the process :)
Leave others their otherness.
http://quakeforge.net/
taniwha
 
Posts: 399
Joined: Thu Jan 14, 2010 7:11 am

Re: Bug fix - Framerate-independent Damage and Bonus shifts

Postby Spike » Mon Jun 11, 2012 11:42 pm

my concern with this is that stuffcmd(player, "bf\nbf\n") no longer results in brigher bfs. most noticable when picking up lots of items near each other.
personally I find just using a float instead of an int in the cshift_t struct works sufficiently well. Sure, there might be minor precision issues, but there are identical minor precision issues all over the quake engine that it doesn't really matter, so long as the value tends towards 0 instead of infinity.
Spike
 
Posts: 2838
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Re: Bug fix - Framerate-independent Damage and Bonus shifts

Postby mh » Tue Jun 12, 2012 12:41 am

Hmmm - I don't see multiple subsequent bfs having that effect in ID Quake either.

In fact V_BonusFlash_f explicitly sets the colours and percent rather than accumulating them, so a new bf will just put them back to the starting values and won't make them brighter (otherwise they would be +=, not =).

Another silly bug with the original code is that the colours will still fade even if the client is paused. Even if nothing else they should use cl.time - cl.oldtime and not host_frametime.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
User avatar
mh
 
Posts: 2282
Joined: Sat Jan 12, 2008 1:38 am

Re: Bug fix - Framerate-independent Damage and Bonus shifts

Postby r00k » Tue Jun 12, 2012 8:50 am

Hmm, I can not replicate this bug. Ive set maxfps 72 -> 200 -> 500, with b bound to "bf" and spam it and it doesnt seem to fade slower/faster. I do notice vid_vsync 0 causes a screen tear but, thats normal.
r00k
 
Posts: 1106
Joined: Sat Nov 13, 2004 10:39 pm

Re: Bug fix - Framerate-independent Damage and Bonus shifts

Postby mh » Fri Feb 22, 2013 9:55 pm

Spike wrote:personally I find just using a float instead of an int in the cshift_t struct works sufficiently well


One advantage of my method is that it allows for multiple calls to SCR_UpdateScreen per frame. Not that big a problem for a fairly vanilla-ish engine, but definitely a big one in cases where this matters.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
User avatar
mh
 
Posts: 2282
Joined: Sat Jan 12, 2008 1:38 am

Re: Bug fix - Framerate-independent Damage and Bonus shifts

Postby revelator » Mon Apr 10, 2017 12:24 am

Small oversight discovered.

Gcc started bitching loudly after i dropped this one on it about excess braces on scalar initialzers so i had a look at the code, and hello and behold.

Code: Select all
// changed to color / percent / initialpercent / time
cshift_t   cshift_empty = {{130, 80, 50}, 0, 0, 0};
cshift_t   cshift_water = {{130, 80, 50}, 128, 0, 0};
cshift_t   cshift_slime = {{0, 25, 5}, 150, 0, 0};
cshift_t   cshift_lava = {{255, 80, 0}, 150, 0, 0};


originally the last two digits where not there but consider this

Code: Select all
typedef struct
{
    int      destcolor[3];
    int      percent;      // 0-256
} cshift_t;


Thats the original code, and below

Code: Select all
typedef struct
{
    int      destcolor[3];
    int      percent;      // 0-256
    int     initialpct;
    double  time;
} cshift_t;


the modified block.

we have two new members so our scalars no longer fit.

cshift_t cshift_empty = {{130, 80, 50}, 0};
cshift_t cshift_water = {{130, 80, 50}, 128};
cshift_t cshift_slime = {{0, 25, 5}, 150};
cshift_t cshift_lava = {{255, 80, 0}, 150};

originally the scalars set hardcoded values for destcolor, thats this part of it -> {130, 80, 50} and, with percent it becomes this {{130, 80, 50}, 0}
but now we have initialpct and time also so it becomes {{130, 80, 50}, 0, 0, 0}. Question since these are hardcoded would initialpct still start of at 50 ?, i took a bit of a guess with time also so just imitialized it to zero.
Productivity is a state of mind.
User avatar
revelator
 
Posts: 2482
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: Bug fix - Framerate-independent Damage and Bonus shifts

Postby Spike » Mon Apr 10, 2017 4:24 am

most compilers don't care if you leave trailing fields uninitialised inside structs.
some warn, because they're overly paranoid (gcc with -Wextra or -Wmissing-field-initializers), but C does not require it.

content-based colour shifts do not fade, so the added initial/time fields are not used in this case iiuc. the bugfix is really just for bonus+damage shifts as these are the only two that actually drop the flash percentages over time.
Spike
 
Posts: 2838
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Re: Bug fix - Framerate-independent Damage and Bonus shifts

Postby mh » Tue Apr 11, 2017 3:35 pm

You should be getting the same problems on all of your cvar initializations too:
Code: Select all
typedef struct cvar_s
{
   char   *name;
   char   *string;
   qboolean archive;      // set to true to cause it to be saved to vars.rc
   qboolean server;      // notifies players when changed
   float   value;
   struct cvar_s *next;
} cvar_t;

There is no code whatsoever in the engine that fully initializes every member of this struct:
Code: Select all
cvar_t   gl_finish = {"gl_finish","0"};
cvar_t   gl_clear = {"gl_clear","0"};
cvar_t   gl_cull = {"gl_cull","1"};
cvar_t   gl_texsort = {"gl_texsort","1"};

If your gcc is bitching about one but not the other, I suggest that's a bug in your gcc.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
User avatar
mh
 
Posts: 2282
Joined: Sat Jan 12, 2008 1:38 am

Re: Bug fix - Framerate-independent Damage and Bonus shifts

Postby revelator » Wed Apr 12, 2017 12:14 am

All versions of gcc after 4.5 will throw this warning, can't say if correct or not but i doub't that if it was not that they would leave it in ?
since others before me have mentioned this behaviour.

Does make sense though gcc may becomming a bit to strict, atleast its not a compiler error yet :lol:
Productivity is a state of mind.
User avatar
revelator
 
Posts: 2482
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: Bug fix - Framerate-independent Damage and Bonus shifts

Postby revelator » Wed Apr 12, 2017 12:31 am

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119

ancient bug it seems, still not fixed because the patch that was proposed needs further work.

also seems to be a problem because newer versions of gcc actually use the c++ compiler to do most C code, in fact after the first bootstrap of a gcc build g++ takes over building the remaining passes.

Gah :evil:
Productivity is a state of mind.
User avatar
revelator
 
Posts: 2482
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: Bug fix - Framerate-independent Damage and Bonus shifts

Postby revelator » Wed Apr 12, 2017 12:53 am

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=21033

second one i ran into was excess elements in scalar initializer, seems this one stems back from the gcc-3 days yikes.

So a good guess is that it will newer be fixed cause the gcc devs see the warnings as a feature to tell developers to check there code for possible errors.

Sadly this warning cannot be turned off.
Productivity is a state of mind.
User avatar
revelator
 
Posts: 2482
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: Bug fix - Framerate-independent Damage and Bonus shifts

Postby revelator » Sun Apr 16, 2017 9:58 am

Omg and it's totally random when this turns up, i just tried this tutorial on another engine and hello ? no warnings :shock:
but in another one -> joequake it also throws this. No adverse effects anyway so id flags this as a gcc fuckup of major dimensions but good luck getting them to fix it :lol:
Productivity is a state of mind.
User avatar
revelator
 
Posts: 2482
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger


Return to Programming Tutorials

Who is online

Users browsing this forum: No registered users and 1 guest