class RTrack | .h |
constructor | RTrack() |
destructor | ~RTrack() |
GetTimeLine | RTimeLine *GetTimeLine(int n) |
GetGridPos | RCarPos *GetGridPos(int n) |
GetPitPos | RCarPos *GetPitPos(int n) |
GetSurfaceInfo | void GetSurfaceInfo(DVector3 *pos,DVector3 *dir,RSurfaceInfo *si) Retrieves info on track surface Note that normally only pos->x and pos->z are used. In case of bridges like in Suzuka however, pos->y may be used to return either the track above or below the bridge. |
SetName | void SetName(cstring _trackName) Load a track (of any type) This is the base function; a derived class should override this function, call us first (and check the return code), then load the actual track from 'file'. |
Flat functions |
trackName.cstr() | trackName.cstr(),(cstring)trackDir); } |
class RTrack | .h |
LoadSpecial | bool LoadSpecial() Load positions and timelines etc |
Load | bool Load() Load a track (of any type) This is the base function; a derived class should override this function, call us first (and check the return code), then load the actual track from 'file'. |
SaveSpecial | bool SaveSpecial() Load positions and timelines etc |
Save | bool Save() |
Paint | void Paint() Painter; override in the derived class |
PaintHidden | void PaintHidden() Paint hidden parts; override in subclasses |
/*
* RTrack - base class for Racer tracks
* ??-11-00: Created!
* (c) Dolphinity
*/
#include <racer/racer.h>
#include <qlib/debug.h>
#pragma hdrstop
DEBUG_ENABLE
// Default track information file
#define TRACK_INI "track.ini"
// File with special things, like grid positions, pit positions and timelines
#define FILE_SPECIAL "special.ini"
RTrack::RTrack()
{
type="flat";
cbLoad=0;
timeLines=0;
gridPosCount=pitPosCount=0;
}
RTrack::~RTrack()
{
int i;
for(i=0;i<timeLines;i++)
if(timeLine[i])delete timeLine[i];
}
/**********
* Attribs *
**********/
RTimeLine *RTrack::GetTimeLine(int n)
{
if(n<0||n>=timeLines)
{ qwarn("RTrack:GetTimeLine(%d) out of bounds",n);
return 0;
}
return timeLine[n];
}
/****************
* Car positions *
****************/
RCarPos *RTrack::GetGridPos(int n)
{
QASSERT_0(n>=0&&n<gridPosCount);
return &gridPos[n];
}
RCarPos *RTrack::GetPitPos(int n)
{
QASSERT_0(n>=0&&n<pitPosCount);
return &pitPos[n];
}
/**********************
* SURFACE DESCRIPTION *
**********************/
void RTrack::GetSurfaceInfo(DVector3 *pos,DVector3 *dir,RSurfaceInfo *si)
// Retrieves info on track surface
// Note that normally only pos->x and pos->z are used. In case of
// bridges like in Suzuka however, pos->y may be used to return either
// the track above or below the bridge.
{
//qdbg("RTrack::GetSurfaceInfo()\n");
// Default is flat boring track
si->x=pos->x;
si->y=0;
si->z=pos->z;
si->grade=0;
si->bank=0;
si->friction=1.0;
}
/*********
* Naming *
*********/
void RTrack::SetName(cstring _trackName)
// Load a track (of any type)
// This is the base function; a derived class should override this
// function, call us first (and check the return code), then load the
// actual track from 'file'.
{
char buf[256];
cstring s;
trackName=_trackName;
// Deduce track directory
sprintf(buf,"data/tracks/%s",trackName.cstr());
strcpy(buf,RFindDir(buf));
#ifdef OBS
s=RFindFile(".",buf);
// Strip "."
strcpy(buf,s);
buf[strlen(buf)-2]=0;
#endif
trackDir=buf;
qdbg("RTrack:SetName(%s) => trackDir='%s'\n",
trackName.cstr(),(cstring)trackDir);
}
/**********
* LOADING *
**********/
bool RTrack::LoadSpecial()
// Load positions and timelines etc
{
QInfo *info;
char buf[256];
int i;
RCarPos *p;
sprintf(buf,"%s/%s",(cstring)trackDir,FILE_SPECIAL);
info=new QInfo(buf);
// Restore grid positions
gridPosCount=info->GetInt("grid.count");
if(gridPosCount>MAX_GRID_POS)gridPosCount=MAX_GRID_POS;
for(i=0;i<gridPosCount;i++)
{
p=&gridPos[i];
sprintf(buf,"grid.pos%d.from.x",i); p->from.x=info->GetFloat(buf);
sprintf(buf,"grid.pos%d.from.y",i); p->from.y=info->GetFloat(buf);
sprintf(buf,"grid.pos%d.from.z",i); p->from.z=info->GetFloat(buf);
sprintf(buf,"grid.pos%d.to.x",i); p->to.x=info->GetFloat(buf);
sprintf(buf,"grid.pos%d.to.y",i); p->to.y=info->GetFloat(buf);
sprintf(buf,"grid.pos%d.to.z",i); p->to.z=info->GetFloat(buf);
}
// Restore pit positions
pitPosCount=info->GetInt("pit.count");
if(pitPosCount>MAX_PIT_POS)pitPosCount=MAX_PIT_POS;
for(i=0;i<pitPosCount;i++)
{
p=&pitPos[i];
sprintf(buf,"pit.pos%d.from.x",i); p->from.x=info->GetFloat(buf);
sprintf(buf,"pit.pos%d.from.y",i); p->from.y=info->GetFloat(buf);
sprintf(buf,"pit.pos%d.from.z",i); p->from.z=info->GetFloat(buf);
sprintf(buf,"pit.pos%d.to.x",i); p->to.x=info->GetFloat(buf);
sprintf(buf,"pit.pos%d.to.y",i); p->to.y=info->GetFloat(buf);
sprintf(buf,"pit.pos%d.to.z",i); p->to.z=info->GetFloat(buf);
}
// Restore timelines
timeLines=info->GetInt("timeline.count");
if(timeLines>MAX_TIMELINE)timeLines=MAX_TIMELINE;
for(i=0;i<timeLines;i++)
{
RTimeLine *t;
DVector3 v1,v2;
v1.SetToZero(); v2.SetToZero();
timeLine[i]=new RTimeLine(&v1,&v2);
t=timeLine[i];
sprintf(buf,"timeline.line%d.from.x",i); v1.x=info->GetFloat(buf);
sprintf(buf,"timeline.line%d.from.y",i); v1.y=info->GetFloat(buf);
sprintf(buf,"timeline.line%d.from.z",i); v1.z=info->GetFloat(buf);
sprintf(buf,"timeline.line%d.to.x",i); v2.x=info->GetFloat(buf);
sprintf(buf,"timeline.line%d.to.y",i); v2.y=info->GetFloat(buf);
sprintf(buf,"timeline.line%d.to.z",i); v2.z=info->GetFloat(buf);
// Redefine to get variables right
t->Define(&v1,&v2);
}
//qdbg("RTrack:LoadSpecial(); timeLines=%d\n",timeLines);
delete info;
return TRUE;
}
bool RTrack::Load()
// Load a track (of any type)
// This is the base function; a derived class should override this
// function, call us first (and check the return code), then load the
// actual track from 'file'.
{
QInfo *infoTrk;
char buf[256];
// Find generic info on track
infoTrk=new QInfo(RFindFile(TRACK_INI,trackDir));
// Found the track.ini?
if(!infoTrk->FileExists())
{ qwarn("Can't find track.ini for track %s",trackName);
return FALSE;
}
infoTrk->GetString("track.type",type);
infoTrk->GetString("track.name",name);
infoTrk->GetString("track.creator",creator);
infoTrk->GetString("track.length",length);
infoTrk->GetString("track.file",file);
delete infoTrk;
if(!LoadSpecial())return FALSE;
#ifdef OBS
// Find actual track 3D file
strcpy(buf,RFindFile(file,trackDir));
file=buf;
if(!QFileExists(file))
{ qwarn("Can't find track file (%s) for track %s",(cstring)file,trackName);
return FALSE;
}
#endif
return TRUE;
}
/*********
* Saving *
*********/
bool RTrack::SaveSpecial()
// Load positions and timelines etc
{
QInfo *info;
int i;
RCarPos *p;
char buf[100];
sprintf(buf,"%s/%s",(cstring)trackDir,FILE_SPECIAL);
info=new QInfo(buf);
// Store grid positions
info->SetInt("grid.count",gridPosCount);
for(i=0;i<gridPosCount;i++)
{
p=&gridPos[i];
sprintf(buf,"grid.pos%d.from.x",i); info->SetFloat(buf,p->from.x);
sprintf(buf,"grid.pos%d.from.y",i); info->SetFloat(buf,p->from.y);
sprintf(buf,"grid.pos%d.from.z",i); info->SetFloat(buf,p->from.z);
sprintf(buf,"grid.pos%d.to.x",i); info->SetFloat(buf,p->to.x);
sprintf(buf,"grid.pos%d.to.y",i); info->SetFloat(buf,p->to.y);
sprintf(buf,"grid.pos%d.to.z",i); info->SetFloat(buf,p->to.z);
}
// Store pit positions
info->SetInt("pit.count",pitPosCount);
for(i=0;i<pitPosCount;i++)
{
p=&pitPos[i];
sprintf(buf,"pit.pos%d.from.x",i); info->SetFloat(buf,p->from.x);
sprintf(buf,"pit.pos%d.from.y",i); info->SetFloat(buf,p->from.y);
sprintf(buf,"pit.pos%d.from.z",i); info->SetFloat(buf,p->from.z);
sprintf(buf,"pit.pos%d.to.x",i); info->SetFloat(buf,p->to.x);
sprintf(buf,"pit.pos%d.to.y",i); info->SetFloat(buf,p->to.y);
sprintf(buf,"pit.pos%d.to.z",i); info->SetFloat(buf,p->to.z);
}
// Store timelines
info->SetInt("timeline.count",timeLines);
for(i=0;i<timeLines;i++)
{
RTimeLine *t;
t=timeLine[i];
sprintf(buf,"timeline.line%d.from.x",i); info->SetFloat(buf,t->from.x);
sprintf(buf,"timeline.line%d.from.y",i); info->SetFloat(buf,t->from.y);
sprintf(buf,"timeline.line%d.from.z",i); info->SetFloat(buf,t->from.z);
sprintf(buf,"timeline.line%d.to.x",i); info->SetFloat(buf,t->to.x);
sprintf(buf,"timeline.line%d.to.y",i); info->SetFloat(buf,t->to.y);
sprintf(buf,"timeline.line%d.to.z",i); info->SetFloat(buf,t->to.z);
}
delete info;
return TRUE;
}
bool RTrack::Save()
{
if(!SaveSpecial())return FALSE;
return TRUE;
}
/********
* PAINT *
********/
void RTrack::Paint()
// Painter; override in the derived class
{
}
void RTrack::PaintHidden()
// Paint hidden parts; override in subclasses
{
}