2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
4 * All source code herein is the property of Volition, Inc. You may not sell
5 * or otherwise commercially exploit the source or things you created based on
10 * $Logfile: /Freespace2/code/Network/multi_ping.cpp $
16 * Revision 1.4 2002/06/09 04:41:23 relnev
17 * added copyright header
19 * Revision 1.3 2002/05/27 00:40:47 theoddone33
20 * Fix net_addr vs net_addr_t
22 * Revision 1.2 2002/05/07 03:16:47 theoddone33
23 * The Great Newline Fix
25 * Revision 1.1.1.1 2002/05/03 03:28:10 root
29 * 5 8/19/99 10:59a Dave
30 * Packet loss detection.
32 * 4 11/17/98 11:12a Dave
33 * Removed player identification by address. Now assign explicit id #'s.
35 * 3 11/05/98 5:55p Dave
36 * Big pass at reducing #includes
38 * 2 10/07/98 10:53a Dave
41 * 1 10/07/98 10:50a Dave
43 * 4 6/30/98 2:17p Dave
44 * Revised object update system. Removed updates for all weapons. Put
45 * button info back into control info packet.
47 * 3 6/12/98 2:49p Dave
50 * 2 3/15/98 4:17p Dave
51 * Fixed oberver hud problems. Put in handy netplayer macros. Reduced size
52 * of network orientation matrices.
54 * 1 3/03/98 5:09p Dave
60 #include "multi_ping.h"
61 #include "multimsgs.h"
64 // ------------------------------------------------------------------------------------
65 // MULTIPLAYER PING DEFINES/VARS
69 // ------------------------------------------------------------------------------------
70 // MULTIPLAYER PING FUNCTIONS
73 // initialize all player ping times
74 void multi_ping_reset_players()
78 // reset the pings for all players
79 for(idx=0;idx<MAX_PLAYERS;idx++){
80 multi_ping_reset(&Net_players[idx].s_info.ping);
84 // initialize the given ping struct
85 void multi_ping_reset(ping_struct *ps)
87 // blast the struct clear
88 memset(ps,0,sizeof(ping_struct));
92 // set the ping start to be -1
93 ps->ping_start = -1.0f;
100 // evaluate a pong return on the given struct
101 void multi_ping_eval_pong(ping_struct *ps)
106 // if the ping technically hasn't started,
107 if(ps->ping_start < 0.0f){
108 nprintf(("Network","Processing pong for ping which hasn't started yet!\n"));
112 // if we still have room to add a ping
113 if(ps->num_pings < MAX_PINGS){
114 ps->ping_times[ps->ping_add++] = f2fl(timer_get_fixed_seconds()) - ps->ping_start;
117 // otherwise if we've wrapped around
119 // increment the place to add the ping time
120 if(ps->ping_add >= MAX_PINGS - 1){
126 ps->ping_times[ps->ping_add] = f2fl(timer_get_fixed_seconds()) - ps->ping_start;
129 // calculate the average ping time
131 for(idx=0;idx<ps->num_pings;idx++){
132 ping_sum += ps->ping_times[idx];
134 ps->ping_avg = (int)(1000.0f * (ping_sum / (float)ps->num_pings));
137 // start a ping - call this when sending a ping packet
138 void multi_ping_start(ping_struct *ps)
140 ps->ping_start = f2fl(timer_get_fixed_seconds());
143 // send a ping to a specific player
144 void multi_ping_send(net_player *p)
146 multi_ping_start(&p->s_info.ping);
147 send_ping(&p->p_info.addr);
150 // send a ping to the specified address
151 void multi_ping_send(net_addr_t *addr,ping_struct *ps)
153 multi_ping_start(ps);
157 // send a ping to all players
158 void multi_ping_send_all()
161 for(idx = 0;idx < MAX_PLAYERS;idx++){
162 if(MULTI_CONNECTED(Net_players[idx]) && (Net_player != NULL) && (Net_player->player_id != Net_players[idx].player_id)){
164 multi_ping_start(&Net_players[idx].s_info.ping);
166 // send the ping packet
167 send_ping(&Net_players[idx].p_info.addr);
172 // get the lowest existing ping in the ping struct, returning -1 if no pings
173 int multi_ping_get_lowest(ping_struct *ps)
178 // if there are no recorded pings, return -1
179 if(ps->num_pings == 0){
183 // otherwise find the lowest
185 for(idx=0;idx<ps->num_pings;idx++){
186 // if we found a lower value
187 if((lowest == -1.0f) || (ps->ping_times[idx] < lowest)){
188 lowest = ps->ping_times[idx];
192 // return the lowest val
193 return lowest < 0.0f ? -1 : (int)(lowest * 1000.0f)/2;
196 // (average ping + lowest ping)/2
197 int multi_ping_lowest_avg(ping_struct *ps)
199 int lowest = multi_ping_get_lowest(ps);
201 // if we couldn't get a valid lowest ping, bail
206 // if we have no average ping, bail
207 if(ps->ping_avg == -1){
211 // otherwise return the average of the 2
212 return (lowest + ps->ping_avg)/2;