View Issue Details

IDProjectCategoryView StatusLast Update
0002065FSSCPcutscenespublic2012-01-24 12:57
ReporterSpoon Assigned ToEli2  
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
Product Version3.6.11 
Summary0002065: Fade in&Fade out sexp's do not work properly when the time is set beyond 5000 milliseconds
DescriptionEasily reproducible by setting up a mission with a when has-time-elapsed, fade-out 0 and a when has-time-elapsed 1, fade-in 7000.
The screen will only fade in half way.
The sexp will work properly up till 5000
TagsNo tags attached.

Relationships

has duplicate 0002538 resolvedEli2 Fade-in time limitation 

Activities

taylor

2010-02-17 06:32

administrator   ~0011689

This is due to high FPS. Well, not that high. Assuming 60 FPS, the highest value you can use without the math rounding to 0 is about 5100 ms. There is no check to compensate for this so the alpha value never gets changed passed that point. Fixing that isn't difficult, I just don't know if it would unknowingly break something in the process.

The easy and obvious fix is just max(1, 0), but then a fade in/out would always be limited to ~5100ms. A better fix is probably to keep track of the frame rate and frame count and use the max(1, 0) solution just enough to keep fade time accurate.

Hopefully someone with more time to work on it can give this a test and figure out the best fix. The problem lies in game_shade_frame(), so somebody give it a look. :)

Zacam

2012-01-15 21:27

administrator  

Eli2-fade-in_fade-out.patch (6,170 bytes)   
Index: code/freespace2/freespace.cpp
===================================================================
--- code/freespace2/freespace.cpp	(revision 8233)
+++ code/freespace2/freespace.cpp	(working copy)
@@ -4197,49 +4197,38 @@
 void game_reset_shade_frame()
 {
 	Fade_type = FI_NONE;
-	Fade_delta_time = 1.0f;
 	gr_create_shader(&Viewer_shader, 0, 0, 0, 0);
 }
 
 void game_shade_frame(float frametime)
 {
-	int alpha = 0;
-
 	// only do frame shade if we are actually in a game play state
 	if ( !game_actually_playing() ) {
 		return;
 	}
 
-	if (Fade_type != FI_NONE)
-	{
-		if ( (Viewer_shader.c == 0) && (Fade_type != FI_FADEOUT) ) {
-			return;
-		}
+	if (Fade_type != FI_NONE) {
+		Assert(Fade_start_timestamp > 0);
+		Assert(Fade_end_timestamp > 0);
+		Assert(Fade_end_timestamp > Fade_start_timestamp);
 
-		alpha = Viewer_shader.c;
+		int startAlpha = 0;
+		int endAlpha = 0;
 
 		// Fade in or out if necessary
 		if (Fade_type == FI_FADEOUT) {
-			alpha += fl2i(frametime * (255.0f / Fade_delta_time) + 0.5f);
+			endAlpha = 255;
 		} else if (Fade_type == FI_FADEIN) {
-			alpha -= fl2i(frametime * (255.0f / Fade_delta_time) + 0.5f);
+			startAlpha = 255;
 		}
 
-		// Limit and set fade type if done
-		if (alpha < 0) {
-			alpha = 0;
+		int duration = (Fade_end_timestamp - Fade_start_timestamp);
+		int elapsed = (timestamp() - Fade_start_timestamp);
 
-			if (Fade_type == FI_FADEIN) {
-				Fade_type = FI_NONE;
-			}
-		}
+		int alpha = fl2i( (float)startAlpha + (((float)endAlpha - (float)startAlpha) / (float)duration) * (float)elapsed );
 
-		if (alpha > 255) {
-			alpha = 255;
-
-			if (Fade_type == FI_FADEOUT) {
-				Fade_type = FI_NONE;
-			}
+		if (alpha == endAlpha) {
+			Fade_type = FI_NONE;
 		}
 
 		Viewer_shader.c = (ubyte)alpha;
Index: code/globalincs/systemvars.cpp
===================================================================
--- code/globalincs/systemvars.cpp	(revision 8233)
+++ code/globalincs/systemvars.cpp	(working copy)
@@ -36,8 +36,9 @@
 
 //FADEIN STUFF
 shader Viewer_shader;
-int Fade_type = FI_NONE;
-float Fade_delta_time = 1.0f;
+FadeType Fade_type = FI_NONE;
+int Fade_start_timestamp = 0;
+int Fade_end_timestamp = 0;
 
 // The detail level.  Anything below zero draws simple models earlier than it
 // should.   Anything above zero draws higher detail models longer than it should.
Index: code/globalincs/systemvars.h
===================================================================
--- code/globalincs/systemvars.h	(revision 8233)
+++ code/globalincs/systemvars.h	(working copy)
@@ -58,13 +58,17 @@
 //-----Fadein stuff
 struct shader;
 extern shader Viewer_shader;
-#define FI_NONE					0
-#define FI_FADEIN				1
-#define FI_FADEOUT				2
-extern float Fade_delta_time;
-extern int Fade_type;
 
+enum FadeType {
+	FI_NONE,
+	FI_FADEIN,
+	FI_FADEOUT
+};
+extern FadeType Fade_type;
+extern int Fade_start_timestamp;
+extern int Fade_end_timestamp;
 
+
 typedef struct vei {
 	angles_t	angles;			//	Angles defining viewer location.
 	float		distance;		//	Distance from which to view, plus 2x radius.
Index: code/parse/sexp.cpp
===================================================================
--- code/parse/sexp.cpp	(revision 8233)
+++ code/parse/sexp.cpp	(working copy)
@@ -18324,52 +18324,49 @@
 
 void sexp_fade_in(int n)
 {
-	float delta_time = 0.0f;
+	int duration = 0;
 
 	if(n != -1)
-		delta_time = eval_num(n)/1000.0f;
+		duration = eval_num(n);
 
-	if(delta_time > 0.0f)
-	{
-		Fade_delta_time = delta_time;
+	if (duration > 0) {
+		Fade_start_timestamp = timestamp();
+		Fade_end_timestamp = timestamp(duration);
 		Fade_type = FI_FADEIN;
-	}
-	else
-	{
+	} else {
 		Fade_type = FI_NONE;
 		gr_create_shader(&Viewer_shader, 0, 0, 0, 0);
 	}
 
 	// multiplayer callback
 	multi_start_callback();
-	multi_send_float(delta_time);
+	multi_send_int(duration);
 	multi_end_callback();
 }
 
 void multi_sexp_fade_in()
 {
-	float delta_time = 0.0f;
+	int duration = 0;
 
-	multi_get_float(delta_time);
+	multi_get_int(duration);
 
-	if(delta_time > 0.0f) {
-		Fade_delta_time = delta_time;
+	if (duration > 0) {
+		Fade_start_timestamp = timestamp();
+		Fade_end_timestamp = timestamp(duration);
 		Fade_type = FI_FADEIN;
-	}
-	else {
+	} else {
 		Fade_type = FI_NONE;
 		gr_create_shader(&Viewer_shader, 0, 0, 0, 0);
 	}
 }
 
-void sexp_fade_out(float delta_time, int fade_type) 
+void sexp_fade_out(int duration, int fadeColor)
 {
 	ubyte R = 0;
 	ubyte G = 0;
 	ubyte B = 0;
 
-	switch(fade_type)
-	{
+	switch(fadeColor) {
 		//White out
 		case 1:
 			gr_create_shader(&Viewer_shader, 255, 255, 255, Viewer_shader.c);
@@ -18381,18 +18378,18 @@
 		//Black out
 		default:
 			gr_create_shader(&Viewer_shader, 0, 0, 0, Viewer_shader.c);
+			break;
 	}
 
 	R = Viewer_shader.r;
 	G = Viewer_shader.g;
 	B = Viewer_shader.b;
 
-	if(delta_time > 0.0f) {
+	if (duration > 0) {
+		Fade_start_timestamp = timestamp();
+		Fade_end_timestamp = timestamp(duration);
 		Fade_type = FI_FADEOUT;
-		Fade_delta_time = delta_time;
-	}
-	else
-	{
+	} else {
 		Fade_type = FI_NONE;
 		gr_create_shader(&Viewer_shader, R, G, B, 255);
 	}
@@ -18400,40 +18397,38 @@
 
 void sexp_fade_out(int n)
 {
-	float delta_time = 0.0f;
-	int fade_type = 0;
+	int duration = 0;
+	int fadeColor = 0;
 
-	if(n != -1)
-	{
-		delta_time = eval_num(n)/1000.0f;
+	if (n != -1) {
+		duration = eval_num(n);
 
 		n = CDR(n);
-		if(n != -1)
-		{
-			fade_type = eval_num(n);			
+		if (n != -1) {
+			fadeColor = eval_num(n);
 		}
 	}
 
-	sexp_fade_out(delta_time, fade_type);
+	sexp_fade_out(duration, fadeColor);
 
 	multi_start_callback();
-	multi_send_float(delta_time);
-	multi_send_int(fade_type);
+	multi_send_int(duration);
+	multi_send_int(fadeColor);
 	multi_end_callback();
 }
 
 void multi_sexp_fade_out()
 {
-	float delta_time = 0.0f;
-	int fade_type;
+	int duration = 0;
+	int fadeColor = 0;
 
-	multi_get_float(delta_time);
-	if (!multi_get_int(fade_type)){
+	multi_get_int(duration);
+	if (!multi_get_int(fadeColor)){
 		Int3();	// misformed packet
 		return;
 	}
 
-	sexp_fade_out(delta_time, fade_type);
+	sexp_fade_out(duration, fadeColor);
 }
 
 camera* sexp_get_set_camera(bool reset = false)
Eli2-fade-in_fade-out.patch (6,170 bytes)   

Zacam

2012-01-15 21:29

administrator   ~0013061

Applied patch as provided by Eli2 seems to resolve the issue, would appreciate confirmation.

Issue History

Date Modified Username Field Change
2009-12-13 17:43 Spoon New Issue
2010-02-17 06:32 taylor Note Added: 0011689
2012-01-15 18:25 Eli2 Relationship added has duplicate 0002538
2012-01-15 21:27 Zacam File Added: Eli2-fade-in_fade-out.patch
2012-01-15 21:27 Eli2 File Added: 0001-Fix-for-mantis-2065-fade-in-out.svn.patch
2012-01-15 21:28 Eli2 File Deleted: 0001-Fix-for-mantis-2065-fade-in-out.svn.patch
2012-01-15 21:29 Zacam Assigned To => Zacam
2012-01-15 21:29 Zacam Status new => assigned
2012-01-15 21:29 Zacam Note Added: 0013061
2012-01-15 21:29 Zacam Status assigned => feedback
2012-01-24 12:57 Eli2 Assigned To Zacam => Eli2
2012-01-24 12:57 Eli2 Status feedback => assigned
2012-01-24 12:57 Eli2 Status assigned => resolved
2012-01-24 12:57 Eli2 Resolution open => fixed