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