]> icculus.org git repositories - taylor/freespace2.git/blob - src/network/multi_ping.cpp
The Great Newline Fix
[taylor/freespace2.git] / src / network / multi_ping.cpp
1 /*
2  * $Logfile: /Freespace2/code/Network/multi_ping.cpp $
3  * $Revision$
4  * $Date$
5  * $Author$
6  *
7  * $Log$
8  * Revision 1.2  2002/05/07 03:16:47  theoddone33
9  * The Great Newline Fix
10  *
11  * Revision 1.1.1.1  2002/05/03 03:28:10  root
12  * Initial import.
13  *  
14  * 
15  * 5     8/19/99 10:59a Dave
16  * Packet loss detection.
17  * 
18  * 4     11/17/98 11:12a Dave
19  * Removed player identification by address. Now assign explicit id #'s.
20  * 
21  * 3     11/05/98 5:55p Dave
22  * Big pass at reducing #includes
23  * 
24  * 2     10/07/98 10:53a Dave
25  * Initial checkin.
26  * 
27  * 1     10/07/98 10:50a Dave
28  * 
29  * 4     6/30/98 2:17p Dave
30  * Revised object update system. Removed updates for all weapons. Put
31  * button info back into control info packet.
32  * 
33  * 3     6/12/98 2:49p Dave
34  * Patch 1.02 changes.
35  * 
36  * 2     3/15/98 4:17p Dave
37  * Fixed oberver hud problems. Put in handy netplayer macros. Reduced size
38  * of network orientation matrices.
39  * 
40  * 1     3/03/98 5:09p Dave
41  *  
42  * $NoKeywords: $
43  */
44
45 #include "multi.h"
46 #include "multi_ping.h"
47 #include "multimsgs.h"
48 #include "timer.h"
49
50 // ------------------------------------------------------------------------------------
51 // MULTIPLAYER PING DEFINES/VARS
52 //
53
54
55 // ------------------------------------------------------------------------------------
56 // MULTIPLAYER PING FUNCTIONS
57 //
58
59 // initialize all player ping times
60 void multi_ping_reset_players()
61 {
62         int idx;
63
64         // reset the pings for all players
65         for(idx=0;idx<MAX_PLAYERS;idx++){
66                 multi_ping_reset(&Net_players[idx].s_info.ping);
67         }
68 }
69
70 // initialize the given ping struct
71 void multi_ping_reset(ping_struct *ps)
72 {
73         // blast the struct clear
74         memset(ps,0,sizeof(ping_struct));
75
76         ps->ping_add = 0;
77
78         // set the ping start to be -1
79         ps->ping_start = -1.0f;
80
81         ps->ping_avg = -1;
82
83         ps->num_pings = 0;
84 }
85
86 // evaluate a pong return on the given struct
87 void multi_ping_eval_pong(ping_struct *ps)
88 {       
89         int idx;
90         float ping_sum;
91         
92         // if the ping technically hasn't started,
93         if(ps->ping_start < 0.0f){
94                 nprintf(("Network","Processing pong for ping which hasn't started yet!\n"));
95                 return;
96         }
97         
98         // if we still have room to add a ping
99         if(ps->num_pings < MAX_PINGS){
100                 ps->ping_times[ps->ping_add++] = f2fl(timer_get_fixed_seconds()) - ps->ping_start;              
101                 ps->num_pings++;
102         } 
103         // otherwise if we've wrapped around
104         else {          
105                 // increment the place to add the ping time
106                 if(ps->ping_add >= MAX_PINGS - 1){
107                         ps->ping_add = 0;
108                 } else {
109                         ps->ping_add++;
110                 }
111
112                 ps->ping_times[ps->ping_add] = f2fl(timer_get_fixed_seconds()) - ps->ping_start;
113         }
114
115         // calculate the average ping time
116         ping_sum = 0.0f;
117         for(idx=0;idx<ps->num_pings;idx++){
118                 ping_sum += ps->ping_times[idx];
119         }
120         ps->ping_avg = (int)(1000.0f * (ping_sum / (float)ps->num_pings));      
121 }
122
123 // start a ping - call this when sending a ping packet
124 void multi_ping_start(ping_struct *ps)
125 {
126         ps->ping_start = f2fl(timer_get_fixed_seconds());
127 }
128
129 // send a ping to a specific player
130 void multi_ping_send(net_player *p)
131 {
132         multi_ping_start(&p->s_info.ping);
133         send_ping(&p->p_info.addr);
134 }
135
136 // send a ping to the specified address
137 void multi_ping_send(net_addr *addr,ping_struct *ps)
138 {
139         multi_ping_start(ps);
140         send_ping(addr);
141 }
142
143 // send a ping to all players
144 void multi_ping_send_all()
145 {
146         int idx;
147         for(idx = 0;idx < MAX_PLAYERS;idx++){
148                 if(MULTI_CONNECTED(Net_players[idx]) && (Net_player != NULL) && (Net_player->player_id != Net_players[idx].player_id)){
149                         // start the ping
150                         multi_ping_start(&Net_players[idx].s_info.ping);                        
151
152                         // send the ping packet
153                         send_ping(&Net_players[idx].p_info.addr);
154                 }
155         }
156 }
157
158 // get the lowest existing ping in the ping struct, returning -1 if no pings
159 int multi_ping_get_lowest(ping_struct *ps)
160 {
161         int idx, lowest_index;
162         float lowest;
163         
164         // if there are no recorded pings, return -1
165         if(ps->num_pings == 0){
166                 return -1;
167         }
168
169         // otherwise find the lowest
170         lowest = -1.0f;
171         for(idx=0;idx<ps->num_pings;idx++){
172                 // if we found a lower value
173                 if((lowest == -1) || (ps->ping_times[idx] < lowest)){
174                         lowest = ps->ping_times[idx];
175                         lowest_index = idx;
176                 }
177         }
178
179         // return the lowest val
180         return lowest < 0.0f ? -1 : (int)(lowest * 1000.0f)/2;
181 }
182
183 // (average ping + lowest ping)/2
184 int multi_ping_lowest_avg(ping_struct *ps)
185 {
186         int lowest = multi_ping_get_lowest(ps);
187
188         // if we couldn't get a valid lowest ping, bail
189         if(lowest == -1){
190                 return -1;
191         }
192
193         // if we have no average ping, bail
194         if(ps->ping_avg == -1){
195                 return -1;
196         }
197
198         // otherwise return the average of the 2
199         return (lowest + ps->ping_avg)/2;
200 }
201