3
*************************************************************************
5
ArmageTron -- Just another Tron Lightcycle Game in 3D.
6
Copyright (C) 2000 Manuel Moos (manuel@moosnet.de)
8
**************************************************************************
10
This program is free software; you can redistribute it and/or
11
modify it under the terms of the GNU General Public License
12
as published by the Free Software Foundation; either version 2
13
of the License, or (at your option) any later version.
15
This program is distributed in the hope that it will be useful,
16
but WITHOUT ANY WARRANTY; without even the implied warranty of
17
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
GNU General Public License for more details.
20
You should have received a copy of the GNU General Public License
21
along with this program; if not, write to the Free Software
22
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
***************************************************************************
28
// I don't know if these includes are needed, I'm brute-forcing it :) - Dave
41
#include "tRecorder.h"
52
REAL subby_SpeedGaugeSize=.175, subby_SpeedGaugeLocX=0.0, subby_SpeedGaugeLocY=-0.9;
53
REAL subby_BrakeGaugeSize=.175, subby_BrakeGaugeLocX=0.48, subby_BrakeGaugeLocY=-0.9;
54
REAL subby_RubberGaugeSize=.175, subby_RubberGaugeLocX=-0.48, subby_RubberGaugeLocY=-0.9;
55
bool subby_ShowHUD=true, subby_ShowSpeedFastest=true, subby_ShowScore=true, subby_ShowAlivePeople=true, subby_ShowPing=true, subby_ShowSpeedMeter=true, subby_ShowBrakeMeter=true, subby_ShowRubberMeter=true;
57
bool show24hour=false;
58
REAL subby_ScoreLocX=-0.95, subby_ScoreLocY=-0.85, subby_ScoreSize =.13;
59
REAL subby_FastestLocX=-0.0, subby_FastestLocY=-0.95, subby_FastestSize =.12;
60
REAL subby_AlivePeopleLocX=.45, subby_AlivePeopleLocY=-0.95, subby_AlivePeopleSize =.13;
61
REAL subby_PingLocX=.80, subby_PingLocY=-0.95, subby_PingSize =.13;
63
REAL max_player_speed=0;
67
void GLmeter_subby(float value,float max, float locx, float locy, float size, const char * t,bool displayvalue = true, bool reverse = false, REAL r=.5, REAL g=.5, REAL b=1)
79
value>max?value=max:1;
81
x= (reverse?-1:1) * cos(M_PI*value/max);
82
y= sin(M_PI*value/max);
83
if(y<size*.24) displayvalue = false; // dont display text when at minimum
85
/* Draws an ugly background on the gauge
88
Vertex(locx-size-.04,locy-.04,0);
89
Vertex(locx-size-.04,locy+size+.04,0);
90
Vertex(locx+size+.04,locy+size+.04,0);
91
Vertex(locx+size+.04,locy-.04,0);
94
Vertex(locx-size-.02,locy-.02,0);
95
Vertex(locx-size-.02,locy+size+.02,0);
96
Vertex(locx+size+.02,locy+size+.02,0);
97
Vertex(locx+size+.02,locy-.02,0);
101
glDisable(GL_TEXTURE_2D);
104
Vertex(-.1*x*size+locx,.1*y*size+locy,0);
105
Vertex(-x*size+locx,y*size+locy,0);
109
rTextField min_t(-size-(0.1*size)+locx,locy,.12*size,.24*size);
110
rTextField max_t(+size+(0.1*size)+locx,locy,.12*size,.24*size);
111
min_t << "0xcccccc" << (reverse?max:0);
112
max_t << "0xcccccc" << (reverse?0:max);
115
rTextField speed_t(-x*1.45*size+locx,y*1.35*size+locy,.1*size,.2*size);
116
sprintf(string,"%.1f",value);
117
speed_t << "0xccffff" << (string);
119
int length = title.Len();
122
rTextField titletext(locx-((.15*size*(length-1.5))/2.0),locy,.12*size,.24*size); //centre -1.0 for null char and -.5 for half a char width = -1.5
123
titletext << "0xff3333" << title;
131
: oldTime_( -100 ), oldRel_( -100 )
135
void Display( float value,float max, float locx, float locy, float size, const char * t,bool displayvalue = true, bool reverse = false, REAL r=.5, REAL g=.5, REAL b=1)
137
REAL rel = value/max;
138
REAL time = se_GameTime();
139
REAL change = rel - oldRel_;
141
// see if the gauge change is enough to warrant an update
142
if ( change * change * ( time - oldTime_ ) > .000001 || time < oldTime_ )
152
rDisplayListFiller filler( list_ );
153
GLmeter_subby(value, max, locx, locy, size, t, displayvalue, reverse, r, g, b );
157
REAL oldTime_; // last rendered game time
158
REAL oldRel_; // last rendered gauge position
159
rDisplayList list_; // caching display list
162
// caches stuff based on two float properties
167
: propa_(-1), propb_(-1)
171
bool Call( REAL propa, REAL propb )
173
if ( propa != propa_ || propb != propb_ )
191
static int alivepeople, alivemates, thetopscore, hudfpscount;
193
static void tank_display_hud( ePlayerNetID* me ){
195
static REAL lastTime = 0;
197
if (se_mainGameTimer &&
198
se_mainGameTimer->speed > .9 &&
199
se_mainGameTimer->speed < 1.1 &&
200
se_mainGameTimer->IsSynced() )
202
REAL newtime = tSysTimeFloat();
203
REAL ts = newtime - lastTime;
204
int newfps = static_cast<int>(se_AverageFPS());
205
if (fabs((newfps-fps)*ts)>4)
212
rTextField c(-.9,-.6);
214
// signed short int playerID = -1;
215
// unsigned short int alivepeople2 = 0;
216
unsigned short int max = se_PlayerNetIDs.Len();
217
// signed short int scores[16];
218
// signed short int teamID = -1;
220
bool dohudcrap = false;
221
if (hudfpscount >= fps) {
225
else { hudfpscount++; }
228
//Calculation, enemies (people not on me's team) alive
233
for(unsigned short int i=0;i<max;i++){
234
ePlayerNetID *p=se_PlayerNetIDs(i);
235
if (p->Object() && p->Object()->Alive()){
236
if (p->CurrentTeam() != me->CurrentTeam()){
246
/* int max = teams.Len();
247
for(int i=0;i<max;i++){
252
//Calculation, top player score
254
// unsigned short int maxscore = 0;
256
for(unsigned short int i=0;i<max;i++){
257
ePlayerNetID* p2=se_PlayerNetIDs(i);
258
// if (p2->TotalScore() > p->TotalScore() || p2->TotalScore() > thetopscore){
259
if (p2->TotalScore() > thetopscore){
260
thetopscore = p2->TotalScore();
265
eCoord pcpos; // = 0 implied
266
if (me->Object() && me->Object()->Alive()) {
267
pcpos = me->Object()->Position(); }
269
tString line1, line2, line3;
271
/* line1 << "HUD: " << p->name;
272
line1.SetPos(22, true);
273
line1 << "FPS: " << fps;
274
line1.SetPos(34, true);
275
line1 << "ENEMIES: " << alivepeople << "\n";
277
line2 << "SCORE: " << p->TotalScore() << ", " << thetopscore;
278
line2.SetPos(22, true);
279
line2 << "PING: " << int(p->ping*1000) << "\n";
281
line3 << "LOCATION: " << int(pcpos.x);
282
line3 << ", " << int(pcpos.y);
283
line3.SetPos(22, true);
284
// line3 << "RUBBER: " << int(p->rubberstatus*100);
287
c <<line1 << line2; */
294
static void display_hud_subby( ePlayer* player ){
297
ePlayerNetID *me = player->netPlayer;
299
if (se_mainGameTimer &&
300
se_mainGameTimer->speed > .9 &&
301
se_mainGameTimer->speed < 1.1 &&
302
se_mainGameTimer->IsSynced() )
305
rTextField c(-.9,-.85);
306
rTextField t(.6,.98);
308
// t << "0xffffffGame Time:" << int (se_GameTime())<< " s";
310
// static int max=0,lastmax=0;
311
// static int imax=-1,lastimax=0;
313
char fasteststring[50];
315
static float maxmeterspeed= 50;
317
static REAL max=max_player_speed;
319
static tString ultiname;
320
static bool wrotefastest = false;
321
static bool wrote10 =false;
322
static bool belowzero=false;
323
static REAL ultimax=0;
324
static REAL timelast;
325
static REAL myscore, topscore;
326
// tString realname = ePlayer::PlayerConfig(0)->Name();
328
// const tString& myname = me->name;
331
myscore = me->TotalScore();
333
const eGameObject *ret = NULL;
335
ret = player->cam->Center();
337
static bool firsttime =true;
339
if(se_GameTime()<0||!firsttime){
341
if((se_GameTime()<0)){
343
if(se_GameTime()<-1){
345
// message<< "Last Game Fastest: " << name << " with a top speed of " << max << "\n";
347
// sn_CenterMessage(message);
349
timelast = se_GameTime();
351
wrotefastest = false;
354
}else if(se_GameTime()>0&&belowzero){
360
for(int i =0 ; i< se_PlayerNetIDs.Len(); i++){
361
ePlayerNetID *p = se_PlayerNetIDs[i];
362
p->TotalScore()>topscore?topscore=p->TotalScore():1;
364
if(gCycle *h = (gCycle*)(p->Object())){
366
// change player so we always see the gauges of the cycle that is watched
370
// distance = h->distance;
371
// c << p-> name << " " << int((h ->Speed())) << " ";
373
max = (float) h->Speed(); // changed to float for more accuracy in reporting top speed
378
if( h->Speed()>ultimax){
379
ultimax = (float) h->Speed();
380
ultiname = p->GetName();
386
gCycle *h = dynamic_cast<gCycle *>(me->Object());
387
if (h && ( !player->netPlayer || !player->netPlayer->IsChatting()) && se_GameTime()>-2){
388
h->Speed()>maxmeterspeed?maxmeterspeed+=10:1;
389
// myscore=p->TotalScore();
392
if(subby_ShowSpeedMeter)
394
static gGLMeter meter[MAX_PLAYERS];
395
meter[player->ID()].Display(h->Speed(),maxmeterspeed,subby_SpeedGaugeLocX,subby_SpeedGaugeLocY,subby_SpeedGaugeSize,"Speed"); // easy to use configurable meters
397
if(subby_ShowRubberMeter)
399
static gGLMeter meter[MAX_PLAYERS];
400
meter[player->ID()].Display(h->GetRubber(),sg_rubberCycle,subby_RubberGaugeLocX,subby_RubberGaugeLocY,subby_RubberGaugeSize," Rubber Used");
401
if ( gCycle::RubberMalusActive() )
403
static gGLMeter meter2[MAX_PLAYERS];
404
meter2[player->ID()].Display(100/(1+h->GetRubberMalus()),100,subby_RubberGaugeLocX,subby_RubberGaugeLocY,subby_RubberGaugeSize,"",true, false, 1,.5,.5);
407
if(subby_ShowBrakeMeter)
409
static gGLMeter meter[MAX_PLAYERS];
410
meter[player->ID()].Display(h->GetBrakingReservoir(), 1.0,subby_BrakeGaugeLocX,subby_BrakeGaugeLocY,subby_BrakeGaugeSize, " Brakes");
413
// bool displayfastest = true;// put into global, set via menusytem... subby to do.make sr_DISPLAYFASTESTout
415
if(subby_ShowSpeedFastest)
417
static gTextCache cacheArray[MAX_PLAYERS];
418
gTextCache & cache = cacheArray[player->ID()];
419
if ( !cache.Call( max, 0 ) )
421
rDisplayListFiller filler( cache.list_ );
423
float size= subby_FastestSize;
424
tColoredString message,messageColor;
425
messageColor << "0xbf9d50";
427
sprintf(fasteststring,"%.1f",max);
428
message << " Fastest: " << name << " " << fasteststring;
429
message.RemoveHex(); //cheers tank;
430
int length = message.Len();
432
rTextField speed_fastest(subby_FastestLocX-((.15*size*(length-1.5))/2.0),subby_FastestLocY,.15*size,.3*size);
433
/* rTextField speed_fastest(.7-((.15*size*(length-1.5))/2.0),.65,.15*size,.3*size); */
435
speed_fastest << messageColor << message;
440
static gTextCache cacheArray[MAX_PLAYERS];
441
gTextCache & cache = cacheArray[player->ID()];
442
if ( !cache.Call( topscore, myscore ) )
444
rDisplayListFiller filler( cache.list_ );
447
if(myscore==topscore){
449
}else if (myscore > topscore){
455
float size = subby_ScoreSize;
456
rTextField score(subby_ScoreLocX,subby_ScoreLocY,.15*size,.3*size);
457
score << " Scores\n";
458
score << "0xefefef" << "Me: Top:\n";
459
score << colour << myscore << " 0xffff00" << topscore ;
463
if(subby_ShowAlivePeople){
464
static gTextCache cacheArray[MAX_PLAYERS];
465
gTextCache & cache = cacheArray[player->ID()];
466
if ( !cache.Call( alivepeople, alivemates ) )
468
rDisplayListFiller filler( cache.list_ );
471
message << "Enemies: " << alivepeople << " Friends: " << alivemates;
472
int length = message.Len();
473
float size = subby_AlivePeopleSize;
474
rTextField enemies_alive(subby_AlivePeopleLocX-((.15*size*(length-1.5))/2.0),subby_AlivePeopleLocY,.15*size,.3*size);
475
enemies_alive << "0xfefefe" << message;
480
static gTextCache cacheArray[MAX_PLAYERS];
481
gTextCache & cache = cacheArray[player->ID()];
482
if ( !cache.Call( 0, myping ) )
484
rDisplayListFiller filler( cache.list_ );
487
message << "Ping: " << int(myping * 1000) << " ms" ;
488
int length = message.Len();
489
float size = subby_PingSize;
490
rTextField ping(subby_PingLocX-((.15*size*(length-1.5))/2.0),subby_PingLocY,.15*size,.3*size);
491
ping << "0xfefefe" << message;
500
tank_display_hud( me ); // call tank's version
504
static void display_fps_subby()
506
if (!(se_mainGameTimer &&
507
se_mainGameTimer->speed > .9 &&
508
se_mainGameTimer->speed < 1.1 &&
509
se_mainGameTimer->IsSynced() ) )
513
static REAL lastTime = 0;
515
REAL newtime = tSysTimeFloat();
516
REAL ts = newtime - lastTime;
518
static gTextCache cache;
519
if ( cache.Call( fps, (int)tSysTimeFloat() ) )
523
if ( tRecorder::IsRunning() )
527
rDisplayListFiller filler( cache.list_ );
530
rTextField c2(.7,.85,.15*size, .3*size);
532
if ( tRecorder::IsRunning() )
534
std::stringstream time;
538
c2 << "0xffffffT:" << time.str() << "\n";
542
int newfps = static_cast<int>(se_AverageFPS());
543
if (fabs((newfps-fps)*ts)>4)
550
c2 << "0xffffffFPS: " <<fps;
554
static int lastTime=0;
555
static char theTime[13];
561
thisTime = localtime ( &rawtime );
563
if(thisTime->tm_min != lastTime) {
568
lastTime = thisTime->tm_min;
570
if(thisTime->tm_min < 10) {
571
sprintf(m, "0%d", thisTime->tm_min);
573
sprintf(m, "%d", thisTime->tm_min);
577
sprintf(h, "%d", thisTime->tm_hour);
581
if(thisTime->tm_hour > 12) {
582
newhour = thisTime->tm_hour-12;
583
sprintf(ampm,"%s","PM");
585
newhour = thisTime->tm_hour;
586
if(newhour == 0) newhour = 12;
587
sprintf(ampm,"%s","AM");
589
sprintf(h, "%d", newhour);
592
sprintf(theTime, "%s:%s %s",h,m,ampm);
595
// float timesize = subby_ScoreSize; // -((.15*timesize*(10-1.5))/2.0)
596
rTextField the_time(.7,.9,.15*size, .3*size);
598
the_time << "0xffffff" << theTime;
603
static void display_hud_subby_all()
605
sr_ResetRenderState(true);
608
rViewportConfiguration* viewportConfiguration = rViewportConfiguration::CurrentViewportConfiguration();
610
for ( int viewport = viewportConfiguration->num_viewports-1; viewport >= 0; --viewport )
612
// get the ID of the player in the viewport
613
int playerID = sr_viewportBelongsToPlayer[ viewport ];
616
ePlayer* player = ePlayer::PlayerConfig( playerID );
618
// select the corrected viewport
619
viewportConfiguration->Port( viewport )->CorrectAspectBottom().Select();
622
display_hud_subby( player );
626
static rPerFrameTask dfps(&display_hud_subby_all);