Page 1 of 1

Bug fix - Framerate-independent Damage and Bonus shifts

Posted: Wed Jun 06, 2012 12:11 am
by mh
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;"

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

Posted: Mon Jun 11, 2012 11:22 pm
by taniwha
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 :)

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

Posted: Mon Jun 11, 2012 11:42 pm
by Spike
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.

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

Posted: Tue Jun 12, 2012 12:41 am
by mh
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.

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

Posted: Tue Jun 12, 2012 8:50 am
by r00k
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.

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

Posted: Fri Feb 22, 2013 9:55 pm
by mh
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.

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

Posted: Mon Apr 10, 2017 12:24 am
by revelator
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.

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

Posted: Mon Apr 10, 2017 4:24 am
by Spike
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.

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

Posted: Tue Apr 11, 2017 3:35 pm
by mh
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.

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

Posted: Wed Apr 12, 2017 12:14 am
by revelator
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:

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

Posted: Wed Apr 12, 2017 12:31 am
by revelator
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:

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

Posted: Wed Apr 12, 2017 12:53 am
by revelator
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.

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

Posted: Sun Apr 16, 2017 9:58 am
by revelator
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: