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_rate.cpp $
16 * Revision 1.3 2002/06/09 04:41:23 relnev
17 * added copyright header
19 * Revision 1.2 2002/05/07 03:16:47 theoddone33
20 * The Great Newline Fix
22 * Revision 1.1.1.1 2002/05/03 03:28:10 root
26 * 6 7/15/99 9:20a Andsager
27 * FS2_DEMO initial checkin
29 * 5 4/25/99 3:02p Dave
30 * Build defines for the E3 build.
32 * 4 4/09/99 2:21p Dave
33 * Multiplayer beta stuff. CD checking.
35 * 3 3/20/99 5:09p Dave
36 * Fixed release build fred warnings and unhandled exception.
38 * 2 3/09/99 6:24p Dave
39 * More work on object update revamping. Identified several sources of
40 * unnecessary bandwidth.
48 #include "alphacolors.h"
49 #include "multi_rate.h"
51 // -----------------------------------------------------------------------------------------------------------------------
52 // MULTI RATE DEFINES/VARS
55 // keep this defined to compile in rate checking
56 #if !defined(NDEBUG) || defined(MULTIPLAYER_BETA_BUILD) || defined(FS2_DEMO)
60 // how many records in the past we'll keep track of
61 #define NUM_UPDATE_RECORDS 5
63 // rate monitoring info
64 typedef struct mr_info {
66 char type[MAX_RATE_TYPE_LEN+1];
69 int total_bytes; // total bytes alltime
72 int stamp_second; // stamp for one second
73 int bytes_second; // how many bytes we've sent in the last second
74 int records_second[NUM_UPDATE_RECORDS]; // records
75 int records_second_count; // how many records we have
76 float avg_second; // avg bytes/sec
79 int bytes_frame; // how many bytes we've sent this frame
80 int records_frame[NUM_UPDATE_RECORDS]; // records
81 int records_frame_count; // how many records we have
82 float avg_frame; // avg bytes/frame
87 mr_info Multi_rate[MAX_RATE_PLAYERS][MAX_RATE_TYPES];
91 // -----------------------------------------------------------------------------------------------------------------------
92 // MULTI RATE FUNCTIONS
95 // notify of a player join
96 void multi_rate_reset(int np_index)
105 if((np_index < 0) || (np_index >= MAX_RATE_PLAYERS)){
109 // blast the index clear
110 for(idx=0; idx<MAX_RATE_TYPES; idx++){
111 memset(&Multi_rate[np_index][idx], 0, sizeof(mr_info));
112 Multi_rate[np_index][idx].stamp_second = -1;
117 // add data of the specified type to datarate processing, returns 0 on fail (if we ran out of types, etc, etc)
118 int multi_rate_add(int np_index, const char *type, int size)
127 if((np_index < 0) || (np_index >= MAX_RATE_PLAYERS)){
130 if((type == NULL) || (strlen(type) <= 0)){
134 // see if the type already exists
135 for(idx=0; idx<MAX_RATE_TYPES; idx++){
137 if(strlen(Multi_rate[np_index][idx].type) <= 0){
141 else if(!SDL_strcasecmp(Multi_rate[np_index][idx].type, type)){
146 // if we couldn't find a slot
147 if(idx >= MAX_RATE_TYPES){
151 // otherwise add the data
152 m = &Multi_rate[np_index][idx];
155 strcpy(m->type, type);
158 m->total_bytes += size;
161 m->bytes_second += size;
164 m->bytes_frame += size;
172 #define R_AVG(ct, ar, avg) do {int av_idx; float av_sum = 0.0f; if(ct == 0){ avg = 0;} else { for(av_idx=0; av_idx<ct; av_idx++){ av_sum += (float)ar[av_idx]; } avg = av_sum / (float)ct; } }while(0)
173 void multi_rate_process()
183 // process all active players
184 for(idx=0; idx<MAX_RATE_PLAYERS; idx++){
185 for(s_idx=0; s_idx<MAX_RATE_TYPES; s_idx++){
186 m = &Multi_rate[idx][s_idx];
189 if(strlen(m->type) <= 0){
194 if(m->stamp_second == -1){
195 m->stamp_second = timestamp(1000);
196 } else if(timestamp_elapsed(m->stamp_second)){
197 // if we've reached max records
198 if(m->records_second_count >= NUM_UPDATE_RECORDS){
199 memmove(m->records_second, m->records_second+1, sizeof(int) * (NUM_UPDATE_RECORDS - 1));
200 m->records_second[NUM_UPDATE_RECORDS-1] = m->bytes_second;
202 // haven't reached max records
204 m->records_second[m->records_second_count++] = m->bytes_second;
207 // recalculate the average
208 R_AVG(m->records_second_count, m->records_second, m->avg_second);
210 // reset bytes/second and timestamp
212 m->stamp_second = timestamp(1000);
216 // if we've reached max records
217 if(m->records_frame_count >= NUM_UPDATE_RECORDS){
218 memmove(m->records_frame, m->records_frame+1, sizeof(int) * (NUM_UPDATE_RECORDS - 1));
219 m->records_frame[NUM_UPDATE_RECORDS-1] = m->bytes_frame;
221 // haven't reached max records
223 m->records_frame[m->records_frame_count++] = m->bytes_frame;
226 // recalculate the average
227 R_AVG(m->records_frame_count, m->records_frame, m->avg_frame);
237 void multi_rate_display(int np_index, int x, int y)
248 if((np_index < 0) || (np_index >= MAX_RATE_PLAYERS)){
253 for(idx=0; idx<MAX_RATE_TYPES; idx++){
254 m = &Multi_rate[np_index][idx];
256 // if we have a 0 length string, we're done
257 if(strlen(m->type) <= 0){
262 gr_set_color_fast(&Color_red);
263 gr_printf(x, y, "%s %d (%d/s) (%f/f)", m->type, m->total_bytes, (int)m->avg_second, m->avg_frame);