Redline/source/infodisplay.cpp
maride 02061d74c2 Original 1.0.5 code
(as received from Jonas Echterhoff)
2016-04-02 14:43:55 +02:00

1243 lines
46 KiB
C++

#include <OpenGL/gl.h>
#include <math.h>
#include "text.h"
#include "entities.h"
#include "config.h"
#include "carphysics.h"
#include "gameframe.h"
#include "gamesystem.h"
#include "interfaceutil.h"
#include "rendercar.h"
#include "renderframe.h"
#include "environment.h"
#include "textures.h"
#include "controls.h"
#include "networkphysics.h"
#include "screen.h"
#include "gametime.h"
#include "network.h"
#include "tracker.h"
#define kOverviewSize 0.22
#define kDotSize 0.01
#define kWhiteDotFile "whitedot.pct"
#define kWhiteDiamondFile "whitediamond.pct"
#define kCornerSignSize 0.1
#define kCornerSignYPos 0.28
void RenderCornerSign()
{
gTexturesQualityModifier=-255;
float corner=(fabs(gAccelSignDisplayCorner)-3)/5;
if(corner<0)corner=0;
if(corner>1)corner=1;
float r=0.5+0.5*corner;
float g=1.0-corner;
float b=0;
float a=1;
if(gAccelSignDisplayIntensity>1.3)
a=1-(gAccelSignDisplayIntensity-1.3)/0.2;
else if(gAccelSignDisplayIntensity<0.8)
a=gAccelSignDisplayIntensity/0.8;
if(!gConfig->guideSigns)
a=0;
TexturesSelectTex(FileGetReference("cornersign.pct"));
tCarPhysics *phys=(tCarPhysics*)gViewedEntity->physics;
if(phys->wrongDriectionFrames*kFrameTime>2)
{
a=(phys->wrongDriectionFrames*kFrameTime-2)*0.3>1?1:(phys->wrongDriectionFrames*kFrameTime-2)*0.3;
r=1;
g=0;
TexturesSelectTex(FileGetReference("wrongdirsign.pct"));
}
if(gFrameCount-phys->crashTime>kFPS*1)
if(sqr(gViewedEntity->velo)<sqr(2)||(phys->collision&&sqr(gViewedEntity->velo)<sqr(15)))
{
a=((gFrameCount-phys->crashTime)*kFrameTime-1)*0.5>1?1:((gFrameCount-phys->crashTime)*kFrameTime-1)*0.5;
r=1;
g=0.5;
TexturesSelectTex(FileGetReference("towsign.pct"));
}
if(a==0)
return;
glPushMatrix();
glPushAttrib(GL_DEPTH_BUFFER_BIT+GL_LIGHTING_BIT+GL_COLOR_BUFFER_BIT+GL_TEXTURE_BIT+GL_CURRENT_BIT);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glLoadIdentity();
glTranslatef(0.0f,0.0f,-1.0f);
glTranslatef(0,kCornerSignYPos,0);
glScalef(kCornerSignSize*0.5,kCornerSignSize*0.5,0);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
glColor4f(r,g,b,a*(1-gConfig->hudTransparency));
glBegin(GL_TRIANGLE_STRIP);
if(gAccelSignDisplayCorner<0)
{
glTexCoord2d(1,1); glVertex2f(1,-1);
glTexCoord2d(1,0); glVertex2f(1,1);
glTexCoord2d(0,1); glVertex2f(-1,-1);
glTexCoord2d(0,0); glVertex2f(-1,1);
}
else
{
glTexCoord2d(0,1); glVertex2f(1,-1);
glTexCoord2d(0,0); glVertex2f(1,1);
glTexCoord2d(1,1); glVertex2f(-1,-1);
glTexCoord2d(1,0); glVertex2f(-1,1);
}
glEnd();
glPopAttrib();
glPopMatrix();
gTexturesQualityModifier=0;
}
#include "random.h"
void RenderOverview(float opacity,float x,float y)
{
if(opacity==0)
return;
if(!gMapInfo->hasOverview)
return;
glPushMatrix();
gTexturesQualityModifier=-255;
glPushAttrib(GL_DEPTH_BUFFER_BIT+GL_LIGHTING_BIT+GL_COLOR_BUFFER_BIT+GL_TEXTURE_BIT+GL_CURRENT_BIT);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
float ratio=(gMapInfo->overviewBotRight.y-gMapInfo->overviewTopLeft.y)/(gMapInfo->overviewBotRight.x-gMapInfo->overviewTopLeft.x);
glColor4f(gEnvironment->instrumentColor.x,gEnvironment->instrumentColor.y,gEnvironment->instrumentColor.z,(1-gConfig->hudTransparency)*opacity);
glLoadIdentity();
glTranslatef(0.0f,0.0f,-1.0f);
glTranslatef(x,y,0);
glScalef(kOverviewSize*0.5,kOverviewSize*ratio*0.5,0);
TexturesSelectTex(gMapInfo->overview);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2d(1,1); glVertex2f(1,-2);
glTexCoord2d(1,0); glVertex2f(1,0);
glTexCoord2d(0,1); glVertex2f(-1,-2);
glTexCoord2d(0,0); glVertex2f(-1,0);
glEnd();
TexturesSelectTex(FileGetReference(kWhiteDotFile));
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
for(int i=0;i<gGameInfo->numPlayers;i++)
if(gCarEntities[i]!=gCarEntities[gReplayViewedEntityID])
{
float posX=(gCarEntities[i]->pos.x-gMapInfo->overviewTopLeft.x)/(gMapInfo->overviewBotRight.x-gMapInfo->overviewTopLeft.x)-0.5;
float posY=(gCarEntities[i]->pos.z-gMapInfo->overviewTopLeft.y)/(gMapInfo->overviewBotRight.y-gMapInfo->overviewTopLeft.y);
glLoadIdentity();
glTranslatef(0.0f,0.0f,-1.0f);
glTranslatef(x+posX*kOverviewSize,y-posY*kOverviewSize*ratio,0);
glScalef(kDotSize*0.5,kDotSize*0.5,0);
tCarPhysics *phys=(tCarPhysics*)(gCarEntities[i]->physics);
tCarDefinition *car=&(phys->car);
if(car->numColors)
glColor4f(car->colors[phys->color].x,car->colors[phys->color].y,car->colors[phys->color].z,(1-gConfig->hudTransparency)*opacity);
else
glColor4f(1,1,1,1);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2d(1,1); glVertex2f(1,-1);
glTexCoord2d(1,0); glVertex2f(1,1);
glTexCoord2d(0,1); glVertex2f(-1,-1);
glTexCoord2d(0,0); glVertex2f(-1,1);
glEnd();
}
glColor4f(1,1,1,1);
if(gGameInfo->numLaps==-1)
{
glColor4f(gEnvironment->instrumentColor.x,gEnvironment->instrumentColor.y,gEnvironment->instrumentColor.z,(1-gConfig->hudTransparency)*opacity);
float posX=(gGhostEntity->pos.x-gMapInfo->overviewTopLeft.x)/(gMapInfo->overviewBotRight.x-gMapInfo->overviewTopLeft.x)-0.5;
float posY=(gGhostEntity->pos.z-gMapInfo->overviewTopLeft.y)/(gMapInfo->overviewBotRight.y-gMapInfo->overviewTopLeft.y);
glLoadIdentity();
glTranslatef(0.0f,0.0f,-1.0f);
glTranslatef(x+posX*kOverviewSize,y-posY*kOverviewSize*ratio,0);
glScalef(kDotSize*0.5,kDotSize*0.5,0);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2d(1,1); glVertex2f(1,-1);
glTexCoord2d(1,0); glVertex2f(1,1);
glTexCoord2d(0,1); glVertex2f(-1,-1);
glTexCoord2d(0,0); glVertex2f(-1,1);
glEnd();
}
TexturesSelectTex(FileGetReference(kWhiteDiamondFile));
// TexturesSelectTex(FileGetReference("dot2.pct"));
float posX=(gCarEntities[gReplayViewedEntityID]->pos.x-gMapInfo->overviewTopLeft.x)/(gMapInfo->overviewBotRight.x-gMapInfo->overviewTopLeft.x)-0.5;
float posY=(gCarEntities[gReplayViewedEntityID]->pos.z-gMapInfo->overviewTopLeft.y)/(gMapInfo->overviewBotRight.y-gMapInfo->overviewTopLeft.y);
glLoadIdentity();
glTranslatef(0.0f,0.0f,-1.0f);
glTranslatef(x+posX*kOverviewSize,y-posY*kOverviewSize*ratio,0);
glScalef(kDotSize*1*0.5,kDotSize*1*0.5,0);
/* glColor4f(RandomFl(0,1),RandomFl(0,1),RandomFl(0,1),1);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2d(1,1); glVertex2f(1,-1);
glTexCoord2d(1,0); glVertex2f(1,1);
glTexCoord2d(0,1); glVertex2f(-1,-1);
glTexCoord2d(0,0); glVertex2f(-1,1);
glEnd();*/
glLoadIdentity();
glTranslatef(0.0f,0.0f,-1.0f);
glTranslatef(x+posX*kOverviewSize,y-posY*kOverviewSize*ratio,0);
glScalef(kDotSize*2*0.5,kDotSize*2*0.5,0);
tCarPhysics *phys=(tCarPhysics*)(gCarEntities[gReplayViewedEntityID]->physics);
tCarDefinition *car=&(phys->car);
if(car->numColors)
glColor4f(car->colors[phys->color].x,car->colors[phys->color].y,car->colors[phys->color].z,(1-gConfig->hudTransparency)*opacity);
else
glColor4f(1,1,1,1);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2d(1,1); glVertex2f(1,-1);
glTexCoord2d(1,0); glVertex2f(1,1);
glTexCoord2d(0,1); glVertex2f(-1,-1);
glTexCoord2d(0,0); glVertex2f(-1,1);
glEnd();
glPopAttrib();
glPopMatrix();
gTexturesQualityModifier=0;
}
#include "error.h"
//display in-game stats
void RaceInfoDisplay(float inOpacity)
{
if(!gGameInfo->demolition)
{
tCarPhysics *phys=(tCarPhysics*)gViewedEntity->physics;
if(inOpacity==0)
return;
//if someone has finished the game, print a message on screen
if(gDisqualified)
TextPrintfToBufferFormatedColored(Vector(0,1),0.1,kTextAlignMiddle,1,1,1,inOpacity,"Disqualified!");
//if the race has started, print statistics
float opacity=inOpacity*(gFrameCount*kFrameTime-kStartGameDelaySeconds);
if(gGameInfo->maxTime!=0)opacity=inOpacity;
if(opacity>inOpacity)opacity=inOpacity;
if(opacity<0)opacity=0;
RenderOverview(opacity,0.42,0.3);
RenderCornerSign();
if(gMapInfo->loop&&gGameInfo->maxTime==0)
if(gGameInfo->numLaps!=-1)
{
//print last lap time
float lastLapTime=phys->lapCount>1?(phys->lapTimes[phys->lapCount-1]-phys->lapTimes[phys->lapCount-2])*kFrameTime:0;
TextPrintfToBufferFormatedColored(Vector(-1,0.92),0.03,kTextAlignLeft,1,1,1,opacity,"Last Lap: %d:%02d'%02d",((int)lastLapTime)/60,((int)lastLapTime)%60,((int)(lastLapTime*100))%100);
//print lap counter
if(phys->lapCount<=gGameInfo->numLaps)
TextPrintfToBufferFormatedColored(Vector(1,1),0.05,kTextAlignRight,1,1,1,opacity,"Lap: %d/%d",phys->lapCount,gGameInfo->numLaps);
else
TextPrintfToBufferFormatedColored(Vector(1,1),0.05,kTextAlignRight,1,1,1,opacity,"Lap: %d/%d",gGameInfo->numLaps,gGameInfo->numLaps);
}
else
{
//print last lap time
float lastLapTime=gLastLapTime*kFrameTime;
TextPrintfToBufferFormatedColored(Vector(-1,0.92),0.03,kTextAlignLeft,1,1,1,opacity,"Last Lap: %d:%02d'%02d",((int)lastLapTime)/60,((int)lastLapTime)%60,((int)(lastLapTime*100))%100);
float bestLapTime=gBestLapTime*kFrameTime;
TextPrintfToBufferFormatedColored(Vector(-1,0.84),0.03,kTextAlignLeft,1,1,1,opacity,"Best Lap: %d:%02d'%02d",((int)bestLapTime)/60,((int)bestLapTime)%60,((int)(bestLapTime*100))%100);
float offset=gConfig->registerLapTimes?0.32:0.24;
if(gConfig->registerLapTimes)
if(gWorldRecord!=-1)
{
float worldRecord=gWorldRecord*kFrameTime;
if(worldRecord)
{
TextPrintfToBufferFormatedColored(Vector(-1,0.76),0.03,kTextAlignLeft,1,1,1,opacity,"World Record: %d:%02d'%02d (set by %s\255#n\255)",((int)worldRecord)/60,((int)worldRecord)%60,((int)(worldRecord*100))%100,gRecordName);
// TextPrintfToBufferFormatedColored(Vector(-0.95,0.68),0.03,kTextAlignLeft,1,1,1,opacity,"set by: %s",gRecordName);
}
else if(gWaitingForRecord)
TextPrintfToBufferFormatedColored(Vector(-1,0.76),0.03,kTextAlignLeft,1,1,1,opacity,"World Record: not set");
else
TextPrintfToBufferFormatedColored(Vector(-1,0.76),0.03,kTextAlignLeft,1,1,1,opacity,"World Record: unavailable");
}
else
TextPrintfToBufferFormatedColored(Vector(-1,0.76),0.03,kTextAlignLeft,1,1,1,opacity,"World Record: Fetching...");
float localRecord=gLocalRecord*kFrameTime;
if(localRecord==0)
TextPrintfToBufferFormatedColored(Vector(-1.0,1.0-offset),0.03,kTextAlignLeft,1,1,1,opacity,"Personal Record: not set");
else
TextPrintfToBufferFormatedColored(Vector(-1.0,1.0-offset),0.03,kTextAlignLeft,1,1,1,opacity,"Personal Record: %d:%02d'%02d",((int)localRecord)/60,((int)localRecord)%60,((int)(localRecord*100))%100);
//print lap counter
TextPrintfToBufferFormatedColored(Vector(1,1),0.05,kTextAlignRight,1,1,1,opacity,"Lap: %d",phys->lapCount);
}
//print current lap time
if(gGameInfo->maxTime==0)
{
float lapTime=phys->lapCount?(gFrameCount-(gGameInfo->numLaps!=-1?(phys->lapTimes[phys->lapCount-1]):gCurrentLapStart))*kFrameTime:0;
TextPrintfToBufferFormatedColored(Vector(-1,1),0.03,kTextAlignLeft,1,1,1,opacity,"This Lap: %d:%02d'%02d",((int)lapTime)/60,((int)lapTime)%60,((int)(lapTime*100))%100);
}
else
{
float timeTaken=gFrameCount*kFrameTime-kStartGameDelaySeconds;
if(timeTaken<0)
timeTaken=0;
TextPrintfToBufferFormatedColored(Vector(-1,1),0.03,kTextAlignLeft,1,1,1,opacity,"Time Taken: %d:%02d'%02d",((int)timeTaken)/60,((int)timeTaken)%60,((int)(timeTaken*100))%100);
float offset=gConfig->registerLapTimes?0.16:0.08;
if(gConfig->registerLapTimes)
if(gWorldRecord!=-1)
{
float worldRecord=gWorldRecord*kFrameTime;
if(worldRecord==0)
TextPrintfToBufferFormatedColored(Vector(-1,0.92),0.03,kTextAlignLeft,1,1,1,opacity,"World Record: not set");
else if((phys->lapCount<=1?timeTaken:(phys->lapTimes[1]*kFrameTime-kStartGameDelaySeconds))<worldRecord)
TextPrintfToBufferFormatedColored(Vector(-1,0.92),0.03,kTextAlignLeft,1,1,1,opacity,"World Record: %d:%02d'%02d (set by %s\255#n\255)",((int)worldRecord)/60,((int)worldRecord)%60,((int)(worldRecord*100))%100,gRecordName);
else
TextPrintfToBufferFormatedColored(Vector(-1.0,0.92),0.03,kTextAlignLeft,1,1,1,opacity,"World Record: failed");
}
else
TextPrintfToBufferFormatedColored(Vector(-1.0,0.92),0.03,kTextAlignLeft,1,1,1,opacity,"World Record: Fetching...");
float localRecord=gLocalRecord*kFrameTime;
if(localRecord==0)
TextPrintfToBufferFormatedColored(Vector(-1.0,1.0-offset),0.03,kTextAlignLeft,1,1,1,opacity,"Personal Record: not set");
else if((phys->lapCount<=1?timeTaken:(phys->lapTimes[1]*kFrameTime-kStartGameDelaySeconds))<localRecord)
TextPrintfToBufferFormatedColored(Vector(-1.0,1.0-offset),0.03,kTextAlignLeft,1,1,1,opacity,"Personal Record: %d:%02d'%02d",((int)localRecord)/60,((int)localRecord)%60,((int)(localRecord*100))%100);
else
TextPrintfToBufferFormatedColored(Vector(-1.0,1.0-offset),0.03,kTextAlignLeft,1,1,1,opacity,"Personal Record: failed");
if((phys->lapCount<=1?timeTaken:(phys->lapTimes[1]*kFrameTime-kStartGameDelaySeconds))<gGameInfo->goldTime)
TextPrintfToBufferFormatedColored(Vector(-1.0,0.92-offset),0.03,kTextAlignLeft,1,1,1,opacity,"\255goldmedal.pct\255: %d:%02d'%02d",((int)gGameInfo->goldTime)/60,((int)gGameInfo->goldTime)%60,((int)(gGameInfo->goldTime*100))%100);
else
TextPrintfToBufferFormatedColored(Vector(-1.0,0.92-offset),0.03,kTextAlignLeft,1,1,1,opacity,"\255goldmedal.pct\255: failed");
if((phys->lapCount<=1?timeTaken:(phys->lapTimes[1]*kFrameTime-kStartGameDelaySeconds))<gGameInfo->silverTime)
TextPrintfToBufferFormatedColored(Vector(-1.0,0.84-offset),0.03,kTextAlignLeft,1,1,1,opacity,"\255silvermedal.pct\255: %d:%02d'%02d",((int)gGameInfo->silverTime)/60,((int)gGameInfo->silverTime)%60,((int)(gGameInfo->silverTime*100))%100);
else
TextPrintfToBufferFormatedColored(Vector(-1.0,0.84-offset),0.03,kTextAlignLeft,1,1,1,opacity,"\255silvermedal.pct\255: failed");
if((phys->lapCount<=1?timeTaken:(phys->lapTimes[1]*kFrameTime-kStartGameDelaySeconds))<gGameInfo->maxTime)
TextPrintfToBufferFormatedColored(Vector(-1.0,0.76-offset),0.03,kTextAlignLeft,1,1,1,opacity,"\255bronzemedal.pct\255: %d:%02d'%02d",((int)gGameInfo->maxTime)/60,((int)gGameInfo->maxTime)%60,((int)(gGameInfo->maxTime*100))%100);
else
{
TextPrintfToBufferFormatedColored(Vector(-1.0,0.76-offset),0.03,kTextAlignLeft,1,1,1,opacity,"\255bronzemedal.pct\255: failed");
if(!gDisqualified)
TextPrintfToBufferFormatedColored(Vector(0,1),0.1,kTextAlignMiddle,1,1,1,opacity,"Time Up!");
}
}
//print lead/trail
if(gGameInfo->maxTime==0)
{
tVector2 leadPos=Vector(-1,gGameInfo->numLaps!=-1?0.84:(gConfig->registerLapTimes?0.6:0.68));
if(phys->lead>=0)
TextPrintfToBufferFormatedColored(leadPos,0.03,kTextAlignLeft,1,1,1,opacity,"Lead: %3.1f",phys->lead);
else
TextPrintfToBufferFormatedColored(leadPos,0.03,kTextAlignLeft,1,1,1,opacity,"Trail: %3.1f",-phys->lead);
if(gGameInfo->numPlayers>1&&gGameInfo->numLaps!=-1)
for(int i=0;i<gGameInfo->numPlayers;i++)
{
tCarPhysics *phys2=(tCarPhysics*)gCarEntities[i]->physics;
if(phys2->lead>=0&&phys->lead<0)
{
if(gGameInfo->network)
TextPrintfToBufferFormatedColored(leadPos-Vector(0,0.08),0.03,kTextAlignLeft,1,1,1,opacity,"Leader: %s",gGameInfo->playerNames[i]);
else
TextPrintfToBufferFormatedColored(leadPos-Vector(0,0.08),0.03,kTextAlignLeft,1,1,1,opacity,"Leader: %s",phys2->car.carName);
break;
}
else if(phys2->lead==-phys->lead)
{
if(gGameInfo->network)
TextPrintfToBufferFormatedColored(leadPos-Vector(0,0.08),0.03,kTextAlignLeft,1,1,1,opacity,"Follower: %s",gGameInfo->playerNames[i]);
else
TextPrintfToBufferFormatedColored(leadPos-Vector(0,0.08),0.03,kTextAlignLeft,1,1,1,opacity,"Follower: %s",phys2->car.carName);
break;
}
}
if(gGameInfo->numLaps!=-1)
{
/*if(GetInterfaceKey(kInterfaceKeyEasterEgg))
{
for(int i=0;i<gGameInfo->numPlayers;i++)
{
if(gCarEntities[i]->id>=0)
{
tCarPhysics *phys2=(tCarPhysics*)gCarEntities[i]->physics;
PrintConsoleString("%s: lap %d,pos %f, lead %f",FileGetName(gGameInfo->playerCars[i]),phys2->lap,phys2->position,phys2->lead);
}
}
}*/
//print position
int position=0;
for(int i=0;i<gGameInfo->numPlayers;i++)
{
if(gCarEntities[i]->id>=0)
{
tCarPhysics *phys2=(tCarPhysics*)gCarEntities[i]->physics;
if(phys2->lap>phys->lap)position++;
else if(gGameInfo->reverse)
{if(phys2->lap==phys->lap&&phys2->position<=phys->position)position++;}
else
{if(phys2->lap==phys->lap&&phys2->position>=phys->position)position++;}
}
}
int numPlayers=0;
for(int i=0;i<gGameInfo->numPlayers;i++)
if(gCarEntities[i]->id>=0)
numPlayers++;
TextPrintfToBufferFormatedColored(Vector(1,0.9),0.05,kTextAlignRight,1,1,1,opacity,"Position: %d/%d",position,numPlayers);
}
}
/* if(phys->arcadeDraftBoost>0.2)
{
float a=phys->arcadeDraftBoost;
TextPrintfToBufferFormatedColored(Vector(0,0.7),0.09,kTextAlignMiddle,0,1,0,a,"Drafting");
}*/
if(!gReplay)
//if the race has not yet started print countdown
if(gFrameCount*kFrameTime<kStartGameDelaySeconds+1)
if(gFrameCount*kFrameTime>=kStartGameDelaySeconds)
TextPrintfToBufferFormatedColored(Vector(0,0.15),0.2+0.1*(gFrameCount%(int)kFPS)/kFPS,kTextAlignMiddle,1,1,1,inOpacity*(1-(gFrameCount%(int)kFPS)/kFPS),"GO!");
else if(gFrameCount*kFrameTime>=kStartGameDelaySeconds-3)
TextPrintfToBufferFormatedColored(Vector(0,0.15),0.05+0.02*(gFrameCount/kFPS)+0.1*(gFrameCount%(int)kFPS)/kFPS,kTextAlignMiddle,1,1,1,inOpacity*(1-(gFrameCount%(int)kFPS)/kFPS),"%d",(int)kStartGameDelaySeconds-gFrameCount/(int)kFPS);
}
else
{
int numDisabled=0;
for(int i=0;i<gGameInfo->numPlayers;i++)
{
if(gCarEntities[i]->id>=0)
{
tCarPhysics *phys=(tCarPhysics*)gCarEntities[i]->physics;
if(phys->damage>=kFatalDamage)
numDisabled++;
}
}
if(numDisabled>0&&numDisabled>=gGameInfo->numPlayers-1)
{
if(numDisabled==gGameInfo->numPlayers)
TextPrintfToBufferFormatedColored(Vector(0,0.2),0.1,kTextAlignMiddle,1,1,1,inOpacity,"Everyone wrecked!");
for(int i=0;i<gGameInfo->numPlayers;i++)
{
if(gCarEntities[i]->id>=0)
{
tCarPhysics *phys=(tCarPhysics*)gCarEntities[i]->physics;
if(phys->damage<kFatalDamage)
TextPrintfToBufferFormatedColored(Vector(0,0.2),0.1,kTextAlignMiddle,1,1,1,inOpacity,"%s \255#w\255won!",gGameInfo->playerNames[i]);
}
}
}
else
{
tCarPhysics *phys=(tCarPhysics*)gCarEntities[gGameInfo->playerID]->physics;
if(phys->damage>=kFatalDamage)
TextPrintfToBufferFormatedColored(Vector(0,0.2),0.1,kTextAlignMiddle,1,1,1,inOpacity,"You're wrecked!");
TextPrintfToBufferFormatedColored(Vector(-1,1),0.03,kTextAlignLeft,1,1,1,inOpacity,"Wrecked: %d/%d",numDisabled,gGameInfo->numPlayers);
}
}
}
/*
void SpeedStatsDisplay(float opacity)
{
tCarPhysics *phys=(tCarPhysics*)gCarEntities[gGameInfo->playerID]->physics;
//Print Top Speed and average speed.
if(gConfig->metricUnits){
TextPrintfToBufferFormatedColored(Vector(0,-0.75),0.03,kTextAlignMiddle,1,1,1,opacity,"Top Speed: %3.0f km/h",phys->maxSpeed*3.6);
TextPrintfToBufferFormatedColored(Vector(0,-0.65),0.03,kTextAlignMiddle,1,1,1,opacity,"Average Speed: %3.0f km/h",phys->averageSpeed*3.6);
}
else{
TextPrintfToBufferFormatedColored(Vector(0,-0.75),0.03,kTextAlignMiddle,1,1,1,opacity,"Top Speed: %3.0f M.P.H.",phys->maxSpeed*2.2369);
TextPrintfToBufferFormatedColored(Vector(0,-0.65),0.03,kTextAlignMiddle,1,1,1,opacity,"Average Speed: %3.0f M.P.H.",phys->averageSpeed*2.2369);
}
}
void BestLapsDisplay(float opacity)
{
if(gMapInfo->loop)
{
tCarPhysics *phys=(tCarPhysics*)gCarEntities[gGameInfo->playerID]->physics;
//print 5 best laps of player
TextPrintfToBufferFormatedColored(Vector(-0.5,0.5),0.03,kTextAlignLeft,1,1,1,opacity,"Best Laps:");
int bestLaps[5];
for(int i=0;i<5&&i<gGameInfo->numLaps;i++)
{
float bestLapTime=INFINITY;
bestLaps[i]=0;
for(int j=0;j<gGameInfo->numLaps;j++)
{
float lapTime=(phys->lapTimes[j+1]-phys->lapTimes[j]);
if(lapTime<=0)
lapTime=10000000;
if(lapTime<bestLapTime)
{
int check=true;
for(int k=0;k<i;k++)
if(bestLaps[k]==j)
check=false;
if(check){
bestLapTime=lapTime;
bestLaps[i]=j;
}
}
}
char str[8];
MakeNumString(bestLaps[i]+1,str);
if(phys->lapTimes[bestLaps[i]+1]-phys->lapTimes[bestLaps[i]]>0)
{
float bestTime=(phys->lapTimes[bestLaps[i]+1]-phys->lapTimes[bestLaps[i]])*kFrameTime;
TextPrintfToBufferFormatedColored(Vector(-0.5,0.4-0.05*i),0.025,kTextAlignLeft,1,1,1,opacity,"%s Lap: %d:%02d'%02d",str,((int)bestTime)/60,((int)bestTime)%60,((int)(bestTime*100))%100);
}
else
TextPrintfToBufferFormatedColored(Vector(-0.5,0.4-0.05*i),0.025,kTextAlignLeft,1,1,1,opacity,"%s Lap: Retired",str);
}
}
}
void BestDriversDisplay(float opacity)
{
//print best players
TextPrintfToBufferFormatedColored(Vector(-0.5,-0.1),0.03,kTextAlignLeft,1,1,1,opacity,"Best Drivers:");
int bestDrivers[kMaxPlayers];
int numPlayersFinished=0;
for(int i=0;i<gGameInfo->numPlayers;i++)
{
tCarPhysics *phys=(tCarPhysics*)gCarEntities[i]->physics;
if(phys->lapCount>gGameInfo->numLaps)
{
numPlayersFinished++;
if(!phys->finishTime)
phys->finishTime=phys->lapTimes[gGameInfo->numLaps];
}
}
if(gReplay)
{
float leaderTime=0;
float time=0;
for(int i=0;i<kNumCheckPoints;i++)
for(int j=0;j<gGameInfo->numLaps;j++)
if(gCheckPoints[i].passTimes[j].time>time)
time=gCheckPoints[i].passTimes[j].time;
float raceLength=kNumCheckPoints*gGameInfo->numLaps+1;
for(int i=0;i<gGameInfo->numPlayers;i++)
{
tCarPhysics *phys=(tCarPhysics*)gCarEntities[i]->physics;
if(phys->lead>0)
{
float racePosition=phys->checkPoint+(phys->lapCount>1?phys->lapCount-1:0)*kNumCheckPoints+1;
float completeness=racePosition/raceLength;
leaderTime=time*kFPS/completeness;
}
}
for(int i=0;i<gGameInfo->numPlayers;i++)
if(gCarEntities[i]->controlType==kControlTypeAIInput)
{
tCarPhysics *phys=(tCarPhysics*)gCarEntities[i]->physics;
if(phys->lapCount<=gGameInfo->numLaps)
{
phys->lapCount=gGameInfo->numLaps+1;
phys->finishTime=leaderTime-phys->lead*kFPS;
numPlayersFinished++;
}
}
}
for(int i=0;i<(gReplay?gGameInfo->numPlayers:numPlayersFinished);i++)
{
int bestTime=0x7fffffff;
bestDrivers[i]=0;
for(int j=0;j<gGameInfo->numPlayers;j++)
{
tCarPhysics *phys=(tCarPhysics*)gCarEntities[j]->physics;
int finishTime=phys->finishTime;
if(finishTime<=0)
finishTime=0x7ffffffe;
if(finishTime<bestTime)
{
int check=true;
for(int k=0;k<i;k++)
if(bestDrivers[k]==j)
check=false;
if(check)
{
bestTime=finishTime;
bestDrivers[i]=j;
}
}
}
tCarPhysics *phys=(tCarPhysics*)gCarEntities[bestDrivers[i]]->physics;
tCarDefinition *car=&(phys->car);
char *carName=gGameInfo->network?gGameInfo->playerNames[bestDrivers[i]]:car->carName;
if(bestTime!=0x7ffffffe)
{
float t=bestTime*kFrameTime-kStartGameDelaySeconds;
TextPrintfToBufferFormatedColored(Vector(-0.5,-0.2-0.05*i),0.025,kTextAlignLeft,1,1,1,opacity,"%s: %d:%02d'%02d",carName,((int)t)/60,((int)t)%60,((int)(t*100))%100);
}
else
TextPrintfToBufferFormatedColored(Vector(-0.5,-0.2-0.05*i),0.025,kTextAlignLeft,1,1,1,opacity,"%s: Retired",carName);
//print players place
if(bestDrivers[i]==gGameInfo->playerID)
if(bestTime!=0x7ffffffe)
{
char str[8];
MakeNumString(i+1,str);
TextPrintfToBufferFormatedColored(Vector(0.0,0.8),0.07,kTextAlignMiddle,1,1,1,opacity,"%s Place!",str);
}
else
TextPrintfToBufferFormatedColored(Vector(0.0,0.8),0.07,kTextAlignMiddle,1,1,1,opacity,"Retired!");
}
}
//displays game stats when the player has finished the race
void EndTextDisplay(float opacity)
{
if(opacity==0)
return;
SpeedStatsDisplay(opacity);
RenderOverview(opacity);
if(gGameInfo->numLaps!=-1)
{
if(gGameInfo->maxTime>0)
{
tCarPhysics *phys=(tCarPhysics*)gViewedEntity->physics;
if(phys->lapCount<=1)
TextPrintfToBufferFormatedColored(Vector(0,1),0.1,kTextAlignMiddle,1,1,1,opacity,"Time Up!");
else if(phys->lapTimes[1]*kFrameTime-kStartGameDelaySeconds>gGameInfo->maxTime)
TextPrintfToBufferFormatedColored(Vector(0,1),0.1,kTextAlignMiddle,1,1,1,opacity,"Time Up!");
else
{
if(phys->lapTimes[1]*kFrameTime-kStartGameDelaySeconds<=gGameInfo->goldTime)
TextPrintfToBufferFormatedColored(Vector(0,1),0.1,kTextAlignMiddle,1,1,1,opacity,"\255goldmedal.pct\255Gold Medal!");
else if(phys->lapTimes[1]*kFrameTime-kStartGameDelaySeconds<=gGameInfo->silverTime)
TextPrintfToBufferFormatedColored(Vector(0,1),0.1,kTextAlignMiddle,1,1,1,opacity,"\255silvermedal.pct\255Silver Medal!");
else
TextPrintfToBufferFormatedColored(Vector(0,1),0.1,kTextAlignMiddle,1,1,1,opacity,"\255bronzemedal.pct\255Bronze Medal!");
float t=phys->lapTimes[1]*kFrameTime-kStartGameDelaySeconds;
TextPrintfToBufferFormatedColored(Vector(0.0,0.6),0.035,kTextAlignMiddle,1,1,1,opacity,"Time taken: %d:%02d'%02d",((int)t)/60,((int)t)%60,((int)(t*100))%100);
}
}
else
{
BestLapsDisplay(opacity);
BestDriversDisplay(opacity);
}
if(gGameInfo->network&&gGameInfo->playerID!=0)
TextPrintfToBufferFormatedColored(Vector(0,-0.86),0.05,kTextAlignMiddle,1,1,1,opacity,"Hit esc to leave game.");
else
TextPrintfToBufferFormatedColored(Vector(0,-0.86),0.05,kTextAlignMiddle,1,1,1,opacity,"Hit esc to exit.");
}
}
*/
void SpeedStatsDisplay(float opacity)
{
tCarPhysics *phys=(tCarPhysics*)gCarEntities[gGameInfo->playerID]->physics;
//Print Top Speed and average speed.
if(gConfig->metricUnits){
TextPrintfToBufferFormatedColored(Vector(-0.9,-0.5),0.03,kTextAlignLeft,1,1,1,opacity,"Top Speed: %3.0f km/h",phys->maxSpeed*3.6);
TextPrintfToBufferFormatedColored(Vector(-0.9,-0.6),0.03,kTextAlignLeft,1,1,1,opacity,"Average Speed: %3.0f km/h",phys->averageSpeed*3.6);
}
else{
TextPrintfToBufferFormatedColored(Vector(-0.9,-0.5),0.03,kTextAlignLeft,1,1,1,opacity,"Top Speed: %3.0f M.P.H.",phys->maxSpeed*2.2369);
TextPrintfToBufferFormatedColored(Vector(-0.9,-0.6),0.03,kTextAlignLeft,1,1,1,opacity,"Average Speed: %3.0f M.P.H.",phys->averageSpeed*2.2369);
}
}
void BestLapsDisplay(float opacity)
{
if(gMapInfo->loop)
{
tCarPhysics *phys=(tCarPhysics*)gCarEntities[gGameInfo->playerID]->physics;
//print 5 best laps of player
TextPrintfToBufferFormatedColored(Vector(0.9,0.45),0.03,kTextAlignRight,1,1,1,opacity,"Best Laps:");
int bestLaps[5];
for(int i=0;i<5&&i<gGameInfo->numLaps;i++)
{
float bestLapTime=INFINITY;
bestLaps[i]=0;
for(int j=0;j<gGameInfo->numLaps;j++)
{
float lapTime=(phys->lapTimes[j+1]-phys->lapTimes[j]);
if(lapTime<=0)
lapTime=10000000;
if(lapTime<bestLapTime)
{
int check=true;
for(int k=0;k<i;k++)
if(bestLaps[k]==j)
check=false;
if(check){
bestLapTime=lapTime;
bestLaps[i]=j;
}
}
}
char str[8];
MakeNumString(bestLaps[i]+1,str);
if(phys->lapTimes[bestLaps[i]+1]-phys->lapTimes[bestLaps[i]]>0)
{
float bestTime=(phys->lapTimes[bestLaps[i]+1]-phys->lapTimes[bestLaps[i]])*kFrameTime;
TextPrintfToBufferFormatedColored(Vector(0.9,0.35-0.05*i),0.025,kTextAlignRight,1,1,1,opacity,"%s Lap: %d:%02d'%02d",str,((int)bestTime)/60,((int)bestTime)%60,((int)(bestTime*100))%100);
}
else
TextPrintfToBufferFormatedColored(Vector(0.9,0.35-0.05*i),0.025,kTextAlignRight,1,1,1,opacity,"%s Lap: Retired",str);
}
}
}
void BestDriversDisplay(float opacity)
{
//print best players
TextPrintfToBufferFormatedColored(Vector(0.9,-0.05),0.03,kTextAlignRight,1,1,1,opacity,"Best Drivers:");
int bestDrivers[kMaxPlayers];
int numPlayersFinished=0;
for(int i=0;i<gGameInfo->numPlayers;i++)
{
tCarPhysics *phys=(tCarPhysics*)gCarEntities[i]->physics;
if(phys->lapCount>gGameInfo->numLaps)
numPlayersFinished++;
}
if(gReplay)
{
float leaderTime=0;
float time=0;
for(int i=0;i<kNumCheckPoints;i++)
for(int j=0;j<gGameInfo->numLaps;j++)
if(gCheckPoints[i].passTimes[j].time>time)
time=gCheckPoints[i].passTimes[j].time;
float raceLength=kNumCheckPoints*gGameInfo->numLaps+1;
for(int i=0;i<gGameInfo->numPlayers;i++)
{
tCarPhysics *phys=(tCarPhysics*)gCarEntities[i]->physics;
if(phys->lead>0)
{
float racePosition=phys->checkPoint+(phys->lapCount>1?phys->lapCount-1:0)*kNumCheckPoints+1;
float completeness=racePosition/raceLength;
leaderTime=time*kFPS/completeness;
}
}
/* for(int i=0;i<gGameInfo->numPlayers;i++)
if(gCarEntities[i]->controlType==kControlTypeAIInput)
{
tCarPhysics *phys=(tCarPhysics*)gCarEntities[i]->physics;
if(phys->lapCount<=gGameInfo->numLaps)
{
phys->lapCount=gGameInfo->numLaps+1;
phys->finishTime=leaderTime-phys->lead*kFPS;
numPlayersFinished++;
}
}*/
}
for(int i=0;i<(gReplay?gGameInfo->numPlayers:numPlayersFinished);i++)
{
int bestTime=0x7fffffff;
bestDrivers[i]=0;
for(int j=0;j<gGameInfo->numPlayers;j++)
{
tCarPhysics *phys=(tCarPhysics*)gCarEntities[j]->physics;
int finishTime=phys->finishTime;
if(finishTime<=0)
finishTime=0x7ffffffe;
if(finishTime<bestTime)
{
int check=true;
for(int k=0;k<i;k++)
if(bestDrivers[k]==j)
check=false;
if(check)
{
bestTime=finishTime;
bestDrivers[i]=j;
}
}
}
tCarPhysics *phys=(tCarPhysics*)gCarEntities[bestDrivers[i]]->physics;
tCarDefinition *car=&(phys->car);
char *carName=gGameInfo->network?gGameInfo->playerNames[bestDrivers[i]]:car->carName;
if(bestTime!=0x7ffffffe)
{
float t=bestTime*kFrameTime-kStartGameDelaySeconds;
if(bestDrivers[i]==gGameInfo->playerID)
TextPrintfToBufferFormatedColored(Vector(0.9,-0.15-0.05*i),0.025,kTextAlignRight,0,1,0,opacity,"%s: %d:%02d'%02d",carName,((int)t)/60,((int)t)%60,((int)(t*100))%100);
else
TextPrintfToBufferFormatedColored(Vector(0.9,-0.15-0.05*i),0.025,kTextAlignRight,1,1,1,opacity,"%s: \255#w\255%d:%02d'%02d",carName,((int)t)/60,((int)t)%60,((int)(t*100))%100);
}
else
if(bestDrivers[i]==gGameInfo->playerID)
TextPrintfToBufferFormatedColored(Vector(0.9,-0.15-0.05*i),0.025,kTextAlignRight,0,1,0,opacity,"%s: Retired",carName);
else
TextPrintfToBufferFormatedColored(Vector(0.9,-0.15-0.05*i),0.025,kTextAlignRight,1,1,1,opacity,"%s: \255#w\255Retired",carName);
//print players place
if(bestDrivers[i]==gGameInfo->playerID)
if(bestTime!=0x7ffffffe)
{
char str[8];
MakeNumString(i+1,str);
TextPrintfToBufferFormatedColored(Vector(-0.9,0.95),0.08,kTextAlignLeft,1,1,1,opacity,"%s Place!",str);
}
else
TextPrintfToBufferFormatedColored(Vector(-0.9,0.95),0.08,kTextAlignLeft,1,1,1,opacity,"Retired!");
}
}
//displays game stats when the player has finished the race
void EndTextDisplay(float opacity)
{
if(opacity==0)
return;
if(!gReplay)
SpeedStatsDisplay(opacity);
RenderOverview(opacity,0.42,0.36);
if(gGameInfo->numLaps!=-1)
{
if(gGameInfo->maxTime>0)
{
tCarPhysics *phys=(tCarPhysics*)gViewedEntity->physics;
float t=phys->lapTimes[1]*kFrameTime-kStartGameDelaySeconds;
if(gDisqualified)
TextPrintfToBufferFormatedColored(Vector(0,1),0.1,kTextAlignMiddle,1,1,1,opacity,"Disqualified!");
else if(phys->lapCount<=1)
TextPrintfToBufferFormatedColored(Vector(0,1),0.1,kTextAlignMiddle,1,1,1,opacity,"Time Up!");
else
{
if(t<=gGameInfo->goldTime)
TextPrintfToBufferFormatedColored(Vector(0,1),0.1,kTextAlignMiddle,1,1,1,opacity,"\255goldmedal.pct\255 Gold Medal!");
else if(t<=gGameInfo->silverTime)
TextPrintfToBufferFormatedColored(Vector(0,1),0.1,kTextAlignMiddle,1,1,1,opacity,"\255silvermedal.pct\255 Silver Medal!");
else if(t<=gGameInfo->maxTime)
TextPrintfToBufferFormatedColored(Vector(0,1),0.1,kTextAlignMiddle,1,1,1,opacity,"\255bronzemedal.pct\255 Bronze Medal!");
else
TextPrintfToBufferFormatedColored(Vector(0,1),0.1,kTextAlignMiddle,1,1,1,opacity,"Time Up!");
}
if(phys->lapCount>1)
{
TextPrintfToBufferFormatedColored(Vector(0.0,0.6),0.035,kTextAlignMiddle,1,1,1,opacity,"Time taken: %d:%02d'%02d",((int)t)/60,((int)t)%60,((int)(t*100))%100);
if(t>gGameInfo->maxTime&&!gDisqualified)
{
t=t-gGameInfo->maxTime;
TextPrintfToBufferFormatedColored(Vector(0.0,0.52),0.035,kTextAlignMiddle,1,1,1,opacity,"Improve by: %d:%02d'%02d",((int)t)/60,((int)t)%60,((int)(t*100))%100);
}
}
}
else
{
BestLapsDisplay(opacity);
BestDriversDisplay(opacity);
}
if(gGameInfo->network&&gGameInfo->playerID!=0)
TextPrintfToBufferFormatedColored(Vector(-0.9,-0.77),0.029,kTextAlignLeft,1,1,1,opacity,"Hit esc to leave game.");
else
TextPrintfToBufferFormatedColored(Vector(-0.9,-0.77),0.029,kTextAlignLeft,1,1,1,opacity,"Hit esc to exit.");
if(gGameInfo->network)
TextPrintfToBufferFormatedColored(Vector(0.9,-0.77),0.029,kTextAlignRight,1,1,1,opacity,"Watching %s",gGameInfo->playerNames[gReplayViewedEntityID]);
else
{
tCarDefinition *car=(tCarDefinition*)FileGetParsedDataPtr(gGameInfo->playerCars[gReplayViewedEntityID],kParserTypeCarDesc,sizeof(tCarDefinition));
TextPrintfToBufferFormatedColored(Vector(0.9,-0.77),0.029,kTextAlignRight,1,1,1,opacity,"Watching %s",car->carName);
}
}
}
void DimScreen(float opacity)
{
if(opacity==0)
return;
glPushAttrib(GL_DEPTH_BUFFER_BIT+GL_LIGHTING_BIT+GL_COLOR_BUFFER_BIT+GL_TEXTURE_BIT+GL_CURRENT_BIT);
glColor4f(0,0,0,0.3*opacity*(1-gConfig->hudTransparency));
glLoadIdentity();
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBegin(GL_TRIANGLE_STRIP);
glVertex3f(-1.0f, 1.0f,-1.00f);
glVertex3f(-1.0f,-1.0f,-1.00f);
glVertex3f( 1.0f, 1.0f,-1.00f);
glVertex3f( 1.0f,-1.0f,-1.00f);
glEnd();
glPopAttrib();
}
#define kChatScreenTime 9.0
#define kChatFadeTime 6.0
void ChatDisplay()
{
if(gInputChatMode)
{
int offset=0;
while(TextWidth(gGameChatMessage+offset,0.04)>1.5*kTextXPos)
offset++;
TextPrintfToBufferFormated(Vector(-0.75,0.5),0.04,kTextAlignLeft,"chat: %s%s",gGameChatMessage+offset,(int)(gFrameCount*kFrameTime*4)%2?"_":"");
}
float t=TimeGetSeconds();
while((t-gGameChatMessagesRecv[0].timestamp)>kChatScreenTime&&gNumGameChatMessages)
GameChatMessagesScroll();
int pos=0;
for(int i=0;i<gNumGameChatMessages;i++)
{
float a=1-((t-gGameChatMessagesRecv[i].timestamp)-kChatFadeTime)/(kChatScreenTime-kChatFadeTime);
if(a>1)a=1;
if(a<0)a=0;
if((t-gGameChatMessagesRecv[i].timestamp)<0.2)
a=(t-gGameChatMessagesRecv[i].timestamp)/0.2;
char str[256];
int offset=0;
do{
strcpy(str,gGameChatMessagesRecv[i].message+offset);
int word=true;
while(TextWidth(str,0.03)>0.9*kTextXPos)
{
word=str[strlen(str)-1]==' ';
str[strlen(str)-1]='\0';
}
if(!word)
{
int i=strlen(str)-1;
while(str[i]!=' '&&i>0)
i--;
if(i>0)
str[i]='\0';
}
offset+=strlen(str);
if(offset)
TextPrintfToBufferFormatedColored(Vector(-0.4,1.0-pos*0.07),0.03,kTextAlignLeft,1,1,1,a,"\255#a\255%s",str);
else
TextPrintfToBufferFormatedColored(Vector(-0.4,1.0-pos*0.07),0.03,kTextAlignLeft,1,1,1,a,str);
pos++;
}while(offset<strlen(gGameChatMessagesRecv[i].message));
// TextPrintfToBufferFormatedColored(Vector(-0.4,1.0-i*0.07),0.03,kTextAlignLeft,1,1,1,a,gGameChatMessagesRecv[i].message);
}
}
void EscDisplay(float opacity)
{
if(opacity==0)
return;
/* if(gReplay)
TextPrintfToBufferFormatedColored(Vector(-0.8,0.7),0.06,kTextAlignLeft,1,1,1,opacity,"Are you sure you want to end the replay?");
else*/
if(gInputEscMode==kInputEscModeQuit)
TextPrintfToBufferFormatedColored(Vector(-0.8,0.7),0.06,kTextAlignLeft,1,1,1,opacity,"Are you sure you want to quit Redline?");
else if(gGameInfo->network&&gGameInfo->playerID!=0)
TextPrintfToBufferFormatedColored(Vector(-0.8,0.7),0.06,kTextAlignLeft,1,1,1,opacity,"Are you sure you want to leave the game?");
else
TextPrintfToBufferFormatedColored(Vector(-0.8,0.7),0.06,kTextAlignLeft,1,1,1,opacity,"Are you sure you want to end the game?");
TextPrintfToBufferFormatedColored(Vector(-0.6,0.35),0.05,kTextAlignLeft,1,1,1,opacity,"Cancel");
if(gInputEscMode==kInputEscModeQuit)
TextPrintfToBufferFormatedColored(Vector(-0.6,0.5),0.05,kTextAlignLeft,1,1,1,opacity,"Quit");
else
TextPrintfToBufferFormatedColored(Vector(-0.6,0.5),0.05,kTextAlignLeft,1,1,1,opacity,"Exit");
if(!gGameInfo->network)
TextPrintfToBufferFormatedColored(Vector(-0.6,0.2),0.05,kTextAlignLeft,1,1,1,opacity,"Retry");
glLoadIdentity();
glTranslatef(0.0f,0.0f,-1.0f);
glPushAttrib(GL_DEPTH_BUFFER_BIT+GL_LIGHTING_BIT+GL_COLOR_BUFFER_BIT+GL_CURRENT_BIT);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
TexturesSelectTex(FileGetReference(kInterfaceMenuPointerTexture));
glColor4f(1,1,1,opacity);
glBegin(GL_TRIANGLE_STRIP);
float y=((gInputEscSelection?0.5:0.35)-0.05)*kScreenYPos;
if(!gGameInfo->network&&gInputEscSelection==2)
y=(0.2-0.05)*kScreenYPos;
glTexCoord2d(1,1); glVertex2f((-0.6-0.05)*kScreenXPos+kInterfaceMenuPointerSize,y-kInterfaceMenuPointerSize);
glTexCoord2d(1,0); glVertex2f((-0.6-0.05)*kScreenXPos+kInterfaceMenuPointerSize,y+kInterfaceMenuPointerSize);
glTexCoord2d(0,1); glVertex2f((-0.6-0.05)*kScreenXPos-kInterfaceMenuPointerSize,y-kInterfaceMenuPointerSize);
glTexCoord2d(0,0); glVertex2f((-0.6-0.05)*kScreenXPos-kInterfaceMenuPointerSize,y+kInterfaceMenuPointerSize);
glEnd();
glPopAttrib();
}
void ReplayDisplay(float opacity)
{
TextPrintfToBufferFormatedColored(Vector(-0.9,0.95),0.08,kTextAlignLeft,1,1,1,opacity*(sin(TimeGetSeconds()*3)*0.5+0.5),"Replay");
if(gReplayAutoCam)
TextPrintfToBufferFormatedColored(Vector(-0.9,0.77),0.029,kTextAlignLeft,1,1,1,opacity,"camera automatic");
{
tCarDefinition *car=(tCarDefinition*)FileGetParsedDataPtr(gGameInfo->playerCars[gReplayViewedEntityID],kParserTypeCarDesc,sizeof(tCarDefinition));
tCarPhysics *phys=(tCarPhysics*)gCarEntities[gReplayViewedEntityID]->physics;
if(phys->plateName)
TextPrintfToBufferFormatedColored(Vector(0.9,-0.77),0.029,kTextAlignRight,1,1,1,opacity,"Watching %s",phys->plateName);
else
TextPrintfToBufferFormatedColored(Vector(0.9,-0.77),0.029,kTextAlignRight,1,1,1,opacity,"Watching %s",car->carName);
}
if(gGameInfo->playerID==0)
TextPrintfToBufferFormatedColored(Vector(-0.9,-0.77),0.029,kTextAlignLeft,1,1,1,opacity,"Hit esc to exit.");
if(gGameInfo->maxTime)
{
float timeTaken=gFrameCount*kFrameTime-kStartGameDelaySeconds;
tCarPhysics *phys=(tCarPhysics*)gViewedEntity->physics;
if(phys->lapCount>1)
timeTaken=phys->lapTimes[1]*kFrameTime-kStartGameDelaySeconds;
if(timeTaken<0)
timeTaken=0;
TextPrintfToBufferFormatedColored(Vector(0.5,0.9),0.03,kTextAlignLeft,1,1,1,opacity,"Time Taken: %d:%02d'%02d",((int)timeTaken)/60,((int)timeTaken)%60,((int)(timeTaken*100))%100);
}
if(gGameInfo->numPlayers>1)
{
TextPrintfToBufferFormatedColored(Vector(0.73,0.4),0.025,kTextAlignRight,1,1,1,opacity,"Player");
TextPrintfToBufferFormatedColored(Vector(0.8,0.4),0.025,kTextAlignRight,1,1,1,opacity,"Lap");
TextPrintfToBufferFormatedColored(Vector(0.9,0.4),0.025,kTextAlignRight,1,1,1,opacity,"Trail");
int playerRanks[kMaxPlayers];
for(int i=0;i<gGameInfo->numPlayers;i++)
playerRanks[i]=i;
for(int i=0;i<gGameInfo->numPlayers-1;i++)
for(int j=0;j<gGameInfo->numPlayers-1-i;j++)
{
tCarPhysics *phys2=(tCarPhysics*)gCarEntities[playerRanks[j]]->physics;
tCarPhysics *phys1=(tCarPhysics*)gCarEntities[playerRanks[j+1]]->physics;
if(phys1->finishTime>0&&phys2->finishTime<=0)
{
int tmp=playerRanks[j];
playerRanks[j]=playerRanks[j+1];
playerRanks[j+1]=tmp;
}
else if(phys2->finishTime>0&&phys1->finishTime<=0)
;
else if(phys2->finishTime>0&&phys1->finishTime>0)
{
if(phys2->finishTime>phys1->finishTime)
{
int tmp=playerRanks[j];
playerRanks[j]=playerRanks[j+1];
playerRanks[j+1]=tmp;
}
}
else if((phys1->lap>phys2->lap)||(gGameInfo->reverse&&(phys2->lap==phys1->lap&&phys1->position<phys2->position))||(!gGameInfo->reverse&&(phys2->lap==phys1->lap&&phys1->position>phys2->position)))
{
int tmp=playerRanks[j];
playerRanks[j]=playerRanks[j+1];
playerRanks[j+1]=tmp;
}
}
for(int i=0;i<gGameInfo->numPlayers;i++)
{
tCarPhysics *phys=(tCarPhysics*)gCarEntities[playerRanks[i]]->physics;
tCarDefinition *car=(tCarDefinition*)FileGetParsedDataPtr(gGameInfo->playerCars[playerRanks[i]],kParserTypeCarDesc,sizeof(tCarDefinition));
char name[512];
if(playerRanks[i]==gReplayViewedEntityID)
sprintf(name,"*%s",phys->plateName?phys->plateName:car->carName);
else
sprintf(name,phys->plateName?phys->plateName:car->carName);
if(playerRanks[i]==gGameInfo->playerID)
{
TextPrintfToBufferFormatedColored(Vector(0.73,0.33-0.05*i),0.025,kTextAlignRight,0,1,0,opacity,name);
if(phys->lapCount<=gGameInfo->numLaps)
TextPrintfToBufferFormatedColored(Vector(0.8,0.33-0.05*i),0.025,kTextAlignRight,0,1,0,opacity,"%d",phys->lapCount);
else
TextPrintfToBufferFormatedColored(Vector(0.8,0.33-0.05*i),0.025,kTextAlignRight,0,1,0,opacity,"F");
if(phys->lead<0)
TextPrintfToBufferFormatedColored(Vector(0.9,0.33-0.05*i),0.025,kTextAlignRight,0,1,0,opacity,"%03.1f",-phys->lead);
else
TextPrintfToBufferFormatedColored(Vector(0.9,0.33-0.05*i),0.025,kTextAlignRight,0,1,0,opacity,"%03.1f",0);
}
else
{
TextPrintfToBufferFormatedColored(Vector(0.73,0.33-0.05*i),0.025,kTextAlignRight,1,1,1,opacity,name);
if(phys->lapCount<=gGameInfo->numLaps)
TextPrintfToBufferFormatedColored(Vector(0.8,0.33-0.05*i),0.025,kTextAlignRight,1,1,1,opacity,"\255#a\255%d",phys->lapCount);
else
TextPrintfToBufferFormatedColored(Vector(0.8,0.33-0.05*i),0.025,kTextAlignRight,1,1,1,opacity,"\255#a\255F");
if(phys->lead<0)
TextPrintfToBufferFormatedColored(Vector(0.9,0.33-0.05*i),0.025,kTextAlignRight,1,1,1,opacity,"\255#a\255%03.1f",-phys->lead);
else
TextPrintfToBufferFormatedColored(Vector(0.9,0.33-0.05*i),0.025,kTextAlignRight,1,1,1,opacity,"\255#a\255%03.1f",0);
}
}
}
RenderOverview(opacity,0.42,0.36);
}
float gEscDisplay=0;
float gPauseDisplay=0;
float gEndDisplay=0;
float gInterfaceFadeDisplay=1;
float gLastDisplayTime=0;
float gReplayDisplay=0;
#define kFadeSpeed 1.5
void CalcFades()
{
float dt=TimeGetSeconds()-gLastDisplayTime;
gLastDisplayTime+=dt;
if(dt<0)dt=0;
if(gInputEscMode)
gEscDisplay+=dt*kFadeSpeed;
else
gEscDisplay-=dt*kFadeSpeed;
if(gEscDisplay>1)gEscDisplay=1;
else if(gEscDisplay<0)gEscDisplay=0;
tCarPhysics *phys=(tCarPhysics*)gViewedEntity->physics;
if(phys->lapCount>gGameInfo->numLaps&&gGameInfo->numLaps!=-1&&!gReplay)
gEndDisplay+=dt*kFadeSpeed;
else
gEndDisplay-=dt*kFadeSpeed;
if(gEndDisplay>1)gEndDisplay=1;
else if(gEndDisplay<0)gEndDisplay=0;
if(gPaused&&!gInputEscMode)
gPauseDisplay+=dt*kFadeSpeed;
else
gPauseDisplay-=dt*kFadeSpeed;
if(gPauseDisplay>1)gPauseDisplay=1;
else if(gPauseDisplay<0)gPauseDisplay=0;
if(dt<1)
gInterfaceFadeDisplay-=dt*kFadeSpeed;
if(gInterfaceFadeDisplay<0)gInterfaceFadeDisplay=0;
if(gReplay)
gReplayDisplay+=dt*kFadeSpeed;
else
gReplayDisplay-=dt*kFadeSpeed;
if(gReplayDisplay>1)gReplayDisplay=1;
else if(gReplayDisplay<0)gReplayDisplay=0;
}
void InitInfoDisplay()
{
gEscDisplay=0;
gPauseDisplay=0;
gEndDisplay=0;
gInterfaceFadeDisplay=1;
gReplayDisplay=0;
gLastDisplayTime=0;
}
//Show game stats
void GameShowInfo()
{
CalcFades();
//if enabled, print frame rate statistics on screen
if(gConfig->performanceStats)
{
TextPrintfToBufferFormated(Vector(-0.35,-0.95),0.025,kTextAlignLeft,"FPS :%5.1f",gFPS);
if(gGameInfo->network)
{
char netStr[7];
NetworkGetStatusString(netStr);
TextPrintfToBufferFormated(Vector(0.15,-0.95),0.025,kTextAlignLeft,netStr);
float rcv,snd;
NetworkGetBandwidth(&rcv,&snd);
TextPrintfToBufferFormated(Vector(-0.1,-0.95),0.025,kTextAlignLeft,"R%3.1f/S%3.1f",rcv,snd);
}
#ifdef __POLYCOUNT
TextPrintfToBufferFormated(Vector(-0.1,-0.95),0.025,kTextAlignLeft,"TPS :%7.0f",gPolyCount*gFPS);
TextPrintfToBufferFormated(Vector(0.15,-0.95),0.025,kTextAlignLeft,"Polys:%d",gPolyCount);
#endif
}
//are we still playing, or have we finished the race?
ChatDisplay();
EndTextDisplay(gEndDisplay);
CarRenderPanels(gViewedEntity,1-gPauseDisplay-gEscDisplay-gEndDisplay-gReplayDisplay);
RaceInfoDisplay(1-gPauseDisplay-gEscDisplay-gEndDisplay-gReplayDisplay);
TextPrintfToBufferFormatedColored(Vector(0,0.7),0.1,kTextAlignMiddle,1,1,1,gPauseDisplay,"Game Paused");
TextPrintfToBufferFormatedColored(Vector(0,-0.3),0.05,kTextAlignMiddle,1,1,1,gPauseDisplay,"Press \255#r\255%s\255#n\255 to Continue.",gConfig->keys[kInputPause].identifier);
ReplayDisplay(gReplayDisplay);
float dim=gEscDisplay+gPauseDisplay+gEndDisplay;
if(dim>1)dim=1;
DimScreen(dim);
EscDisplay(gEscDisplay);
float a=2-(TimeGetSeconds()-giTunesLastStatusUpdate)*0.4;
if(a>0)
{
TextPrintfToBufferFormatedColored(Vector(0,-0.5),0.25,kTextAlignMiddle,1,1,1,a,"\255stereo.pct\255");
if(giTunesPlaying==kITunesPlaying)
{
TextPrintfToBufferFormatedColored(Vector(0,-0.65),0.04,kTextAlignMiddle,1,1,1,a,giTunesArtist);
TextPrintfToBufferFormatedColored(Vector(0,-0.75),0.04,kTextAlignMiddle,1,1,1,a,giTunesSong);
}
else if(giTunesPlaying==kITunesPaused)
TextPrintfToBufferFormatedColored(Vector(0,-0.65),0.04,kTextAlignMiddle,1,1,1,a,"Paused");
else
TextPrintfToBufferFormatedColored(Vector(0,-0.65),0.04,kTextAlignMiddle,1,1,1,a,"Stopped");
}
TextPrintBuffer(1-gConfig->hudTransparency,true);
TextClearBuffer();
InterfaceDrawBackgroundFade(gInterfaceFadeDisplay,true);
}