1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
|
/*
* Copyright (C) Volition, Inc. 1999. All rights reserved.
*
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* source.
*
*/
// -----------------------------------------------------------------------------------------------------------------------
// MULTI RATE DEFINES/VARS
//
#include "network/multi_rate.h"
#ifdef MULTI_RATE
#include "io/timer.h"
#include "globalincs/alphacolors.h"
// how many records in the past we'll keep track of
#define NUM_UPDATE_RECORDS 5
// rate monitoring info
typedef struct mr_info {
// type
char type[MAX_RATE_TYPE_LEN+1];
// all time info
int total_bytes; // total bytes alltime
// per second info
int stamp_second; // stamp for one second
int bytes_second; // how many bytes we've sent in the last second
int records_second[NUM_UPDATE_RECORDS]; // records
int records_second_count; // how many records we have
float avg_second; // avg bytes/sec
// per frame info
int bytes_frame; // how many bytes we've sent this frame
int records_frame[NUM_UPDATE_RECORDS]; // records
int records_frame_count; // how many records we have
float avg_frame; // avg bytes/frame
} mr_info;
// all records
mr_info Multi_rate[MAX_RATE_PLAYERS][MAX_RATE_TYPES];
// -----------------------------------------------------------------------------------------------------------------------
// MULTI RATE FUNCTIONS
//
// notify of a player join
void multi_rate_reset(int np_index)
{
int idx;
// sanity checks
if((np_index < 0) || (np_index >= MAX_RATE_PLAYERS)){
return;
}
// blast the index clear
for(idx=0; idx<MAX_RATE_TYPES; idx++){
memset(&Multi_rate[np_index][idx], 0, sizeof(mr_info));
Multi_rate[np_index][idx].stamp_second = -1;
}
}
// add data of the specified type to datarate processing, returns 0 on fail (if we ran out of types, etc, etc)
int multi_rate_add(int np_index, const char *type, int size)
{
int idx;
mr_info *m;
// sanity checks
if((np_index < 0) || (np_index >= MAX_RATE_PLAYERS)){
return 0;
}
if((type == NULL) || (strlen(type) <= 0)){
return 0;
}
// see if the type already exists
for(idx=0; idx<MAX_RATE_TYPES; idx++){
// empty slot
if(strlen(Multi_rate[np_index][idx].type) <= 0){
break;
}
// existing
else if(!stricmp(Multi_rate[np_index][idx].type, type)){
break;
}
}
// if we couldn't find a slot
if(idx >= MAX_RATE_TYPES){
return 0;
}
// otherwise add the data
m = &Multi_rate[np_index][idx];
// type string
strcpy_s(m->type, type);
// alltime
m->total_bytes += size;
// per-second
m->bytes_second += size;
// per-frame
m->bytes_frame += size;
// success
return 1;
}
// process
#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(false)
void multi_rate_process()
{
int idx, s_idx;
mr_info *m;
// process all active players
for(idx=0; idx<MAX_RATE_PLAYERS; idx++){
for(s_idx=0; s_idx<MAX_RATE_TYPES; s_idx++){
m = &Multi_rate[idx][s_idx];
// invalid entries
if(strlen(m->type) <= 0){
continue;
}
// process alltime
if(m->stamp_second == -1){
m->stamp_second = timestamp(1000);
} else if(timestamp_elapsed(m->stamp_second)){
// if we've reached max records
if(m->records_second_count >= NUM_UPDATE_RECORDS){
memmove(m->records_second, m->records_second+1, sizeof(int) * (NUM_UPDATE_RECORDS - 1));
m->records_second[NUM_UPDATE_RECORDS-1] = m->bytes_second;
}
// haven't reached max records
else {
m->records_second[m->records_second_count++] = m->bytes_second;
}
// recalculate the average
R_AVG(m->records_second_count, m->records_second, m->avg_second);
// reset bytes/second and timestamp
m->bytes_second = 0;
m->stamp_second = timestamp(1000);
}
// process per-frame
// if we've reached max records
if(m->records_frame_count >= NUM_UPDATE_RECORDS){
memmove(m->records_frame, m->records_frame+1, sizeof(int) * (NUM_UPDATE_RECORDS - 1));
m->records_frame[NUM_UPDATE_RECORDS-1] = m->bytes_frame;
}
// haven't reached max records
else {
m->records_frame[m->records_frame_count++] = m->bytes_frame;
}
// recalculate the average
R_AVG(m->records_frame_count, m->records_frame, m->avg_frame);
// reset bytes/frame
m->bytes_frame = 0;
}
}
}
// display
void multi_rate_display(int np_index, int x, int y)
{
int idx;
mr_info *m;
int line_height = gr_get_font_height() + 1;
// sanity checks
if((np_index < 0) || (np_index >= MAX_RATE_PLAYERS)){
return;
}
// get info
for(idx=0; idx<MAX_RATE_TYPES; idx++){
m = &Multi_rate[np_index][idx];
// if we have a 0 length string, we're done
if(strlen(m->type) <= 0){
break;
}
// display
gr_set_color_fast(&Color_red);
gr_printf_no_resize(x, y, "%s %d (%d/s) (%f/f)", m->type, m->total_bytes, (int)m->avg_second, m->avg_frame);
y += line_height;
}
}
#endif
|