View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0002065 | FSSCP | cutscenes | public | 2009-12-13 17:43 | 2012-01-24 12:57 |
Reporter | Spoon | Assigned To | Eli2 | ||
Priority | normal | Severity | minor | Reproducibility | always |
Status | resolved | Resolution | fixed | ||
Product Version | 3.6.11 | ||||
Summary | 0002065: Fade in&Fade out sexp's do not work properly when the time is set beyond 5000 milliseconds | ||||
Description | Easily 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 | ||||
Tags | No tags attached. | ||||
|
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. :) |
|
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) |
|
Applied patch as provided by Eli2 seems to resolve the issue, would appreciate confirmation. |
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 |