diff --git a/source/cl_hud.c b/source/cl_hud.c index 80d382c..29eac32 100644 --- a/source/cl_hud.c +++ b/source/cl_hud.c @@ -75,6 +75,11 @@ char player_name[16]; extern cvar_t waypoint_mode; +int screenflash_color; +double screenflash_duration; +int screenflash_type; +double screenflash_worktime; +double screenflash_starttime; int old_points; int current_points; @@ -1420,6 +1425,75 @@ void HUD_PlayerName (void) Draw_ColoredString(70, 170, player_name, 255, 255, 255, alpha, 1); } +/* +=============== +HUD_Screenflash +=============== +*/ + +// +// Types of screen-flashes. +// + +// Colors +#define SCREENFLASH_COLOR_WHITE 0 +#define SCREENFLASH_COLOR_BLACK 1 + +// Types +#define SCREENFLASH_FADE_INANDOUT 0 +#define SCREENFLASH_FADE_IN 1 +#define SCREENFLASH_FADE_OUT 2 + +// +// invert float takes in float value between 0 and 1, inverts position +// eg: 0.1 returns 0.9, 0.34 returns 0.66 +float invertfloat(float input) { + if (input < 0) + return 0; // adjust to lower boundary + else if (input > 1) + return 1; // adjust to upper boundary + else + return (1 - input); +} + +void HUD_Screenflash (void) +{ + int r, g, b, a; + float flash_alpha; + + double percentage_complete = screenflash_worktime / (screenflash_duration - screenflash_starttime); + + // Fade Out + if (screenflash_type == SCREENFLASH_FADE_OUT) { + flash_alpha = invertfloat((float)percentage_complete); + } + // Fade In + else if (screenflash_type == SCREENFLASH_FADE_IN) { + flash_alpha = (float)percentage_complete; + } + // Fade In + Fade Out + else { + // Fade In + if (percentage_complete < 0.5) { + flash_alpha = (float)percentage_complete; + } + // Fade Out + else { + flash_alpha = invertfloat((float)percentage_complete); + } + } + + // Obtain the flash color + switch(screenflash_color) { + case SCREENFLASH_COLOR_BLACK: r = 0; g = 0; b = 0; a = (int)(flash_alpha * 255); break; + case SCREENFLASH_COLOR_WHITE: r = 255; g = 255; b = 255; a = (int)(flash_alpha * 255); break; + default: r = 255; g = 0; b = 0; a = 255; break; + } + + screenflash_worktime += host_frametime; + Draw_FillByColor(0, 0, vid.width, vid.height, r, g, b, a); +} + /* =============== HUD_Draw @@ -1430,8 +1504,12 @@ void HUD_Draw (void) if (scr_con_current == vid.height) return; // console is full screen - if (key_dest == key_menu_pause) + if (key_dest == key_menu_pause) { + // Make sure we still draw the screen flash. + if (screenflash_duration > sv.time) + HUD_Screenflash(); return; + } scr_copyeverything = 1; @@ -1452,6 +1530,10 @@ void HUD_Draw (void) if (cl.stats[STAT_HEALTH] <= 0) { HUD_EndScreen (); + + // Make sure we still draw the screen flash. + if (screenflash_duration > sv.time) + HUD_Screenflash(); return; } @@ -1484,4 +1566,8 @@ void HUD_Draw (void) } HUD_MaxAmmo(); } + + // This should always come last! + if (screenflash_duration > sv.time) + HUD_Screenflash(); } \ No newline at end of file diff --git a/source/cl_hud.h b/source/cl_hud.h index aeb6cdb..11f6378 100644 --- a/source/cl_hud.h +++ b/source/cl_hud.h @@ -52,4 +52,10 @@ extern qpic_t *achievement_locked; extern char player_name[16]; extern double nameprint_time; +extern int screenflash_color; +extern double screenflash_duration; +extern int screenflash_type; +extern double screenflash_worktime; +extern double screenflash_starttime; + void HUD_Parse_Achievement (int ach); diff --git a/source/cl_parse.c b/source/cl_parse.c index 6d8a74e..1a0a43c 100644 --- a/source/cl_parse.c +++ b/source/cl_parse.c @@ -1125,6 +1125,14 @@ void CL_ParseServerMessage (void) doubletap_has_damage_buff = MSG_ReadByte(); break; + case svc_screenflash: + screenflash_color = MSG_ReadByte(); + screenflash_duration = sv.time + MSG_ReadByte(); + screenflash_type = MSG_ReadByte(); + screenflash_worktime = 0; + screenflash_starttime = sv.time; + break; + case svc_bettyprompt: bettyprompt_time = sv.time + 4; break; diff --git a/source/host_cmd.c b/source/host_cmd.c index d68a687..4b42b3c 100644 --- a/source/host_cmd.c +++ b/source/host_cmd.c @@ -1313,7 +1313,6 @@ void Host_Spawn_f (void) Sys_Printf ("%s entered the game\n", host_client->name); PR_ExecuteProgram (pr_global_struct->PutClientInServer); - S_LocalSound ("sounds/rounds/splash.wav"); // since this won't execute in progs... } diff --git a/source/pr_cmds.c b/source/pr_cmds.c index 2563fce..ea7e2da 100644 --- a/source/pr_cmds.c +++ b/source/pr_cmds.c @@ -3318,6 +3318,44 @@ void PF_SetDoubleTapVersion(void) MSG_WriteByte (&client->message, state); } +/* +================= +PF_ScreenFlash + +Server tells client to flash on screen +for a short (but specified) moment. + +nzp_screenflash(target, color, duration, type) +================= +*/ +void PF_ScreenFlash(void) +{ + client_t *client; + int entnum; + int color, duration, type; + + entnum = G_EDICTNUM(OFS_PARM0); + color = G_FLOAT(OFS_PARM1); + duration = G_FLOAT(OFS_PARM2); + type = G_FLOAT(OFS_PARM3); + + // Specified world, or something. Send to everyone. + if (entnum < 1 || entnum > svs.maxclients) { + MSG_WriteByte(&sv.reliable_datagram, svc_screenflash); + MSG_WriteByte(&sv.reliable_datagram, color); + MSG_WriteByte(&sv.reliable_datagram, duration); + MSG_WriteByte(&sv.reliable_datagram, type); + } + // Send to specific user + else { + client = &svs.clients[entnum-1]; + MSG_WriteByte (&client->message, svc_screenflash); + MSG_WriteByte (&client->message, color); + MSG_WriteByte (&client->message, duration); + MSG_WriteByte (&client->message, type); + } +} + /* ================= PF_BettyPrompt @@ -3992,6 +4030,7 @@ PF_MaxZombies, // #503 PF_BettyPrompt, // #504 PF_SetPlayerName, // #505 PF_SetDoubleTapVersion, // #506 +PF_ScreenFlash, // #507 PF_Fixme, }; diff --git a/source/protocol.h b/source/protocol.h index afd3023..e83ad15 100644 --- a/source/protocol.h +++ b/source/protocol.h @@ -158,6 +158,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define svc_bettyprompt 47 #define svc_playername 48 #define svc_doubletap 49 +#define svc_screenflash 50 // [byte] color [byte] duration [byte] type // // client to server