Flat functions |
exitfunc | void exitfunc() |
MapXYtoCtl | static void MapXYtoCtl(int x,int y) Convert X/Y coords to controller input |
event | bool event(QEvent *e) |
class if(e->type!=QEvent | .h |
if | MOTIONNOTIFY) qdbg("event %d, n=%d\n",e->type,e->n); #endif |
Flat functions |
SetupViewport | void SetupViewport(int w,int h) |
GGetDrawable | QDraw *GGetDrawable() |
GGetCV | QCanvas *GGetCV() |
GSwap | void GSwap() |
Camera | static void Camera() |
PaintVar | static void PaintVar(cstring name,int value,int *x,int *y) |
PaintVar | static void PaintVar(cstring name,double value,int *x,int *y) |
PaintVar | static void PaintVar(cstring name,cstring value,int *x,int *y) |
PaintControllerStatus | static void PaintControllerStatus() Show different vars |
SceneAnimate | void SceneAnimate() Animate all things upto the current time |
UpdateControllers | void UpdateControllers() |
idlefunc | void idlefunc() |
Setup | void Setup() |
Run | void Run() |
DBG_TRACE_ON | DBG_TRACE_ON() #endif |
/*
* Racer - Carlab
* 01-12-00: Created!
* NOTES:
* - Modifying existing and creating new cars
* (C) MarketGraph/RvG
*/
#include "main.h"
#pragma hdrstop
#include <d3/global.h>
#include <qlib/timer.h>
#include <qlib/dxjoy.h>
#include <GL/glu.h>
#include <qlib/debug.h>
DEBUG_ENABLE
#define DRW Q_BC
#define CAR_NAME "devtest"
//#define CONTROLS_FILE "controls.ini"
// Use some default things to get the car running
// at something near-real life.
#define TIME_PER_INTEGRATION 10
// Maximum time to emulate per gfx frame
#define MAX_SIMTIME_PER_FRAME 100
#define DEBUG_INI "debug.ini"
DGlobal dglobal;
RCar *car;
RTrackFlat *trackFlat;
QTimer *tmr;
// Controller info
int ctlSteer;
int ctlThrottle;
int ctlBrakes;
static int tSimTime; // Simulated time in milliseconds
static bool fAnimatePhysics=TRUE;
// Editing
int curCam,
curWheel,
curSusp;
int curMode,curSubMode;
cstring sMode[]={ "Drive","Camera" };
cstring sSubMode[]={ "Offset","Angle" };
void exitfunc()
{
if(RMGR)delete RMGR;
}
/*********
* EVENTS *
*********/
static void MapXYtoCtl(int x,int y)
// Convert X/Y coords to controller input
{
x-=DRW->GetWidth()/2;
y-=DRW->GetHeight()/2;
#ifndef WIN32
//if(!(rdbg->flags&RF_NO_STEERING))
{
// Mouse
ctlSteer=-x*3;
}
{
// Combined axis simulation
if(y<0)
{ ctlThrottle=-y*4;
ctlBrakes=0;
if(ctlThrottle>1000)
ctlThrottle=1000;
} else
{ ctlThrottle=0;
ctlBrakes=y*4;
if(ctlBrakes>1000)
ctlBrakes=1000;
}
}
#endif
}
bool event(QEvent *e)
{
static int butsDown;
static int dragX,dragY;
RCamera *cam;
#ifdef OBS
if(e->type!=QEvent::MOTIONNOTIFY)
qdbg("event %d, n=%d\n",e->type,e->n);
#endif
if(PartsEvent(e))return TRUE;
cam=car->GetCamera(curCam);
if(e->type==QEvent::MOTIONNOTIFY)
{
if(e->win!=Q_BC)return FALSE;
if(curMode==MODE_DRIVE)
{
// Only move when the mouse is down; it's a drag otherwise
if((butsDown&1)==1)
MapXYtoCtl(e->x,e->y);
} else if(curMode==MODE_CAM)
{
// Edit the camera
if(butsDown&1)
{
if(curSubMode==SUBMODE_OFFSET)
{
cam->offset.x+=((rfloat)(e->x-dragX))*1./640.;
cam->offset.y+=((rfloat)(dragY-e->y))*1./480.;
} else
{
cam->angle.y+=((float)(e->x-dragX))*100./576.;
cam->angle.x+=((float)(e->y-dragY))*100./720.;
}
} else if(butsDown&4)
{
if(curSubMode==SUBMODE_OFFSET)
{
cam->offset.z+=(e->x-dragX)*.005;
} else
{
cam->angle.z+=(e->x-dragX)*50./576.;
}
}
dragX=e->x;
dragY=e->y;
}
} else if(e->type==QEvent::BUTTONPRESS)
{
butsDown|=(1<<(e->n-1));
dragX=e->x; dragY=e->y;
} else if(e->type==QEvent::BUTTONRELEASE)
{
butsDown&=~(1<<(e->n-1));
} else if(e->type==QEvent::KEYPRESS)
{
if(e->n==QK_ESC)
app->Exit(0);
}
return FALSE;
}
/***********
* HANDLING *
***********/
void SetupViewport(int w,int h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(65.0,(GLfloat)w/(GLfloat)h,0.1,1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
QDraw *GGetDrawable()
{
return DRW;
}
QCanvas *GGetCV()
{
return DRW->GetCanvas();
}
void GSwap()
{ DRW->Swap();
}
static void Camera()
{
car->GetCamera(curCam)->Go();
}
/*************
* CONTROLLER *
*************/
static void PaintVar(cstring name,int value,int *x,int *y)
{
QCanvas *cv=GGetCV();
char buf[80];
sprintf(buf,"%s: %d",name,value);
cv->Text(buf,*x,*y);
*y+=16;
}
static void PaintVar(cstring name,double value,int *x,int *y)
{
QCanvas *cv=GGetCV();
char buf[80];
sprintf(buf,"%s: %.3f",name,value);
cv->Text(buf,*x,*y);
*y+=16;
}
static void PaintVar(cstring name,cstring value,int *x,int *y)
{
QCanvas *cv=GGetCV();
char buf[80];
sprintf(buf,"%s: %s",name,value);
cv->Text(buf,*x,*y);
*y+=16;
}
#define _PV(s,v) PaintVar(s,v,&x,&y)
static void PaintControllerStatus()
// Show different vars
{
QCanvas *cv=GGetCV();
char buf[80];
int x,y;
cv->Set3D();
cv->Set2D();
x=20; y=20;
cv->SetFont(app->GetSystemFont());
_PV("Simulated time (s)",tSimTime/1000);
_PV("Current part",partName[curPart]);
_PV("Mouse mode",sMode[curMode]);
_PV("Submode",sSubMode[curSubMode]);
}
/*******
* IDLE *
*******/
void SceneAnimate()
// Animate all things upto the current time
{
static int lastTime;
int curTime,diffTime;
double diffTimeDbl;
// Make sure time is running
if(!tmr->IsRunning())
{ tmr->Start();
// Get some start time
GSwap();
//return;
}
// Calculate time from last to current situation
curTime=tmr->GetMilliSeconds();
diffTime=curTime-lastTime;
diffTimeDbl=((double)(curTime-lastTime))/1000.0f;
// Frequency of simulation is constant; the drawing of gfx
// frames is NOT
if(diffTime>MAX_SIMTIME_PER_FRAME)
{
diffTime=MAX_SIMTIME_PER_FRAME;
}
// Calculate physics until we are at the last realtime checkpoint
int integrations=0;
//qdbg("controller input: %d %d %d\n",ctlSteer,ctlThrottle,ctlBrakes);
car->SetInput(ctlSteer,ctlThrottle,ctlBrakes,0);
while(tSimTime<curTime)
{
integrations++;
//qdbg("-----------------------\n");
car->Animate();
// Keep total SIMULATED time (in case of slomo, this is NOT
// the same as real time)
tSimTime+=TIME_PER_INTEGRATION;
break; // $DEV; draw every frame
}
// Update other sim stuff that are out of the integration loop
car->OnGfxFrame();
// Audio
if(integrations>0)
{ // Actual sim rate
RMGR->audio->Run(RMGR->time->span*integrations);
}
// We are now with the simulation near 'curTime'
lastTime=curTime;
}
void UpdateControllers()
{
RMGR->controls->Update();
#ifdef WIN32
// Add both steering controls
ctlSteer=RMGR->controls->control[RControls::T_STEER_LEFT]->value-
RMGR->controls->control[RControls::T_STEER_RIGHT]->value;
ctlThrottle=RMGR->controls->control[RControls::T_THROTTLE]->value;
ctlBrakes=RMGR->controls->control[RControls::T_BRAKES]->value;
#endif
}
void idlefunc()
{
DVector3 *v;
// Update controller status
UpdateControllers();
// Physics
if(fAnimatePhysics)
SceneAnimate();
GGetCV()->Select();
SetupViewport(DRW->GetWidth(),DRW->GetHeight());
GGetCV()->SetFont(app->GetSystemFont());
glClearColor(.1,.4,.1,0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glEnable(GL_CULL_FACE);
//glCullFace(GL_FRONT);
//glFrontFace(GL_CW);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
float lightDir[3]={ 0,-.1,-1 };
//float lightPos[4]={ 1,1,1,0 };
float lightPos[4]={ 0.01,.01,-1000,0 };
//glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,lightDir);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_FLAT);
// Camera
Camera();
glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
//glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,lightDir);
v=car->GetPosition();
RGfxAxes(v->x,v->y+.01,v->z,1);
//glTranslatef(0,-1.66,-5.0);
//glRotatef(15,1,0,0);
#ifdef ND_MOVING_CAM
static float vx=.05;
static float y=2.5;
y+=vx; if(y>5||y<1)vx=-vx;
gluLookAt(y*2-6,y /*1.66*/,-5.0, 0,0,0, 0,1,0);
#endif
// Cars
car->Paint();
car->SetDefaultMaterial();
RMGR->scene->Paint();
// Info
PaintControllerStatus();
GSwap();
}
void Setup()
{
float v;
qstring s;
// Create Racer manager
new RManager();
RMGR->Create();
// Create a scene
RMGR->scene->env=new REnvironment();
RMGR->LoadTrack(info->GetStringDirect("misc.track"));
#ifdef OBS
trackFlat=new RTrackFlat();
trackFlat->SetName("devflat");
if(!trackFlat->Load())
{ qerr("Can't load 'devflat' track");
app->Exit(0);
}
RMGR->scene->SetTrack(trackFlat);
#endif
// Load last used car
info->GetString("misc.lastcar",s,"devtest");
car=new RCar(s);
car->Warp(&RMGR->track->gridPos[0]);
tmr=new QTimer();
// Start debug info
ctlSteer=RMGR->infoDebug->GetInt("car.steer");
ctlThrottle=RMGR->infoDebug->GetInt("engine.throttle");
ctlBrakes=RMGR->infoDebug->GetInt("engine.brakes");
DRW->GetCanvas()->SetMode(QCanvas::DOUBLEBUF);
PartsSetup();
// Get window up
app->RunPoll();
app->SetIdleProc(idlefunc);
app->SetExitProc(exitfunc);
app->SetEventProc(event);
// Now that the window is up, we can continue with some things
RMGR->controls->LoadConfig();
}
void Run()
{
#ifdef OBS
DBG_TRACE_ON()
#endif
Q_BC->GetQXWindow()->SetCursor(app->GetShellCursor());
Setup();
app->Run();
}