27#include <racescreens.h>
28#include <robottools.h>
29#include <portability.h>
54 switch (car->_pitStopType) {
72 car->_penaltyTime = 0.0f;
73 ReInfo->_reSimItf.reconfig(car);
78 car->_penaltyTime = 0.0f;
128 static float color[] = {0.5, 0.5, 1.0, 1.0};
130 const int BUFSIZE = 1024;
135 if (car->_speed_x > car->_topSpeed) {
136 car->_topSpeed = car->_speed_x;
140 if (car->_speed_x > info->
topSpd) {
141 info->
topSpd = car->_speed_x;
144 if (car->_speed_x < info->
botSpd) {
145 info->
botSpd = car->_speed_x;
146 car->_currentMinSpeedForLap = car->_speed_x;
154 snprintf(car->
ctrl.
msg[2], 32,
"Can Pit");
156 snprintf(car->
ctrl.
msg[2], 32,
"Pit Occupied");
167 snprintf(buf, BUFSIZE,
"%s pit stop %.1fs", car->_name, info->
totalPitTime);
174 (s->_maxDammage == 0 || car->_dammage <= s->_maxDammage))
176 tdble lgFromStart = car->_trkPos.seg->lgfromstart;
178 switch (car->_trkPos.seg->type) {
180 lgFromStart += car->_trkPos.toStart;
183 lgFromStart += car->_trkPos.toStart * car->_trkPos.seg->radius;
187 if ((lgFromStart > car->_pit->lmin) && (lgFromStart < car->
_pit->lmax)) {
193 toBorder = car->_trkPos.toRight;
196 toBorder = car->_trkPos.toLeft;
199 sseg = car->_trkPos.seg->side[side];
201 if (sseg->
side[side]) {
202 sseg = sseg->
side[side];
205 if (((toBorder + wseg) < (
ReInfo->track->pits.width - car->_dimension_y / 2.0)) &&
206 (fabs(car->_speed_x) < 1.0) &&
207 (fabs(car->_speed_y) < 1.0))
215 for (i = 0; i < car->_pit->freeCarIndex; i++) {
216 if (car->_pit->car[i] == car) {
217 car->_pit->pitCarIndex = i;
222 snprintf(buf, BUFSIZE,
"%s in pits", car->_name);
243 car->_remainingLaps--;
244 if (car->_laps > 1) {
246 car->_curTime += car->_lastLapTime;
247 if (car->_bestLapTime != 0) {
248 car->_deltaBestLapTime = car->_lastLapTime - car->_bestLapTime;
250 if ((car->_lastLapTime < car->_bestLapTime) || (car->_bestLapTime == 0)) {
251 if (car->_commitBestLapTime) {
252 car->_bestLapTime = car->_lastLapTime;
256 car->_commitBestLapTime =
true;
258 if (car->_pos != 1) {
259 car->_timeBehindLeader = car->_curTime - s->
cars[0]->_curTime;
260 car->_lapsBehindLeader = s->
cars[0]->_laps - car->_laps;
261 car->_timeBehindPrev = car->_curTime - s->
cars[car->_pos - 2]->_curTime;
262 s->
cars[car->_pos - 2]->_timeBeforeNext = car->_timeBehindPrev;
264 car->_timeBehindLeader = 0;
265 car->_lapsBehindLeader = 0;
266 car->_timeBehindPrev = 0;
269 printf(
"Sim Time: %8.2f [s], Leader Laps: %4d, Leader Distance: %8.3f [km]\n", s->
currentTime, car->_laps - 1, car->_distRaced/1000.0f);
273 switch (
ReInfo->s->_raceType) {
276 ReInfo->_refreshDisplay = 1;
277 const int TIMEFMTSIZE=256;
278 char t1[TIMEFMTSIZE], t2[TIMEFMTSIZE];
279 GfTime2Str(t1, TIMEFMTSIZE, car->_lastLapTime, 0);
280 GfTime2Str(t2, TIMEFMTSIZE, car->_bestLapTime, 0);
281 snprintf(buf, BUFSIZE,
"lap: %02d time: %s best: %s top spd: %.2f min spd: %.2f damage: %d",
282 car->_laps - 1, t1, t2,
302 info->
topSpd = car->_speed_x;
303 info->
botSpd = car->_speed_x;
304 car->_currentMinSpeedForLap = car->_speed_x;
309 if (car->_pos == 1) {
310 snprintf(buf, BUFSIZE,
"Winner %s", car->_name);
313 const char *numSuffix =
"th";
314 if (abs(12 - car->_pos) > 1) {
315 switch (car->_pos % 10) {
329 snprintf(buf, BUFSIZE,
"%s Finished %d%s", car->_name, car->_pos, numSuffix);
336 for (i = 0; i < s->_ncars; i++) {
355 car->_distFromStartLine = car->_trkPos.seg->lgfromstart +
356 (car->_trkPos.seg->type ==
TR_STR ? car->_trkPos.toStart : car->_trkPos.toStart * car->_trkPos.seg->radius);
357 car->_distRaced = (car->_laps - (info->
lapFlag + 1)) *
ReInfo->track->length + car->_distFromStartLine;
374 for (i = 1; i < s->_ncars; i++) {
379 if (s->
cars[j]->_distRaced > s->
cars[j-1]->_distRaced) {
383 s->
cars[j]->_pos = j+1;
384 s->
cars[j-1]->_pos = j;
409 static float color[] = {0.0, 0.0, 1.0, 1.0};
417 if ((car->_curLapTime > 84.5 +
ReInfo->track->length/10.0) &&
424 const int BUFSIZE = 1024;
434 car->_commitBestLapTime =
false;
447 tdble toborder = 0.0f;
448 tdble minradius = 1.0f;
465 toborder = car->_trkPos.toLeft;
470 toborder = car->_trkPos.toRight;
476 tdble cuttinglimit = car->_dimension_y*0.7f;
477 if (toborder < -cuttinglimit) {
482 car->_commitBestLapTime =
false;
486 minradius -= cuttinglimit;
487 if (minradius > 1.0f) {
494 if (car->_skillLevel < 3) {
509 snprintf(car->
ctrl.
msg[3], 32,
"Drive Through Penalty");
512 snprintf(car->
ctrl.
msg[3], 32,
"Stop And Go Penalty");
529 snprintf(buf, BUFSIZE,
"%s DRIVE THROUGH PENALTY CLEANING", car->_name);
534 snprintf(buf, BUFSIZE,
"%s STOP&GO PENALTY CLEANING", car->_name);
560 snprintf(buf, BUFSIZE,
"%s penalty cleared", car->_name);
572 snprintf(buf, BUFSIZE,
"%s STOP&GO PENALTY", car->_name);
587 snprintf(buf, BUFSIZE,
"%s STOP&GO PENALTY", car->_name);
599 snprintf(buf, BUFSIZE,
"%s DRIVE THROUGH PENALTY", car->_name);
615 return (currentTime - lastTime) >= updateInterval;
623 raceEngineInfo->
lastTime = lastTime;
642 for (
int i = 0; i < s->_ncars; i++) {
675 ReInfo->_reCurTime += deltaTimeIncrement *
ReInfo->_reTimeMult;
692 ReInfo->_reSimItf.update(s, deltaTimeIncrement, -1);
693 for (i = 0; i < s->_ncars; i++) {
714 ReInfo->_reGraphicItf.muteformenu();
724 const int BUFSIZE = 1024;
728 img = (
unsigned char*)malloc(vw * vh * 3);
733 glPixelStorei(GL_PACK_ROW_LENGTH, 0);
734 glPixelStorei(GL_PACK_ALIGNMENT, 1);
735 glReadBuffer(GL_FRONT);
736 glReadPixels((sw-vw)/2, (sh-vh)/2, vw, vh, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)img);
751 const int MAXSTEPS = 2000;
754 ReInfo->_refreshDisplay = 0;
755 switch (
ReInfo->_displayMode) {
780 while ((t -
ReInfo->_reCurTime + 2.0) > 0.0) {
789 capture = &(
ReInfo->movieCapture);
803 while ((t -
ReInfo->_reCurTime + 2.0) > 0.0) {
820 ReInfo->_reTimeMult *= 2.0;
821 if (
ReInfo->_reTimeMult > 64.0) {
822 ReInfo->_reTimeMult = 64.0;
826 ReInfo->_reTimeMult *= 0.5;
827 if (
ReInfo->_reTimeMult < 1.0f/128.0f) {
828 ReInfo->_reTimeMult = 1.0f/128.0f;
833 ReInfo->_reTimeMult = 1.0;
837 const int BUFSIZE = 1024;
840 snprintf(buf, BUFSIZE,
"Time x%.2f", 1.0 /
ReInfo->_reTimeMult);
#define RM_PENALTY_DRIVETHROUGH
#define RM_CMD_PIT_ASKED
Race command: Pit asked.
#define RM_CAR_STATE_PIT
Car currently stopped in pits.
#define RM_CAR_STATE_NO_SIMU
Do not simulate the car.
#define SEM_COLLISION_XYSCENE
struct CarElt tCarElt
Car structure (tCarElt).
#define RM_CAR_STATE_FINISH
Car having passed the finish line.
struct CarPenalty tCarPenalty
One penalty.
#define RM_CAR_STATE_ELIMINATED
Eliminated due to rules infringement.
#define RM_PENALTY_STOPANDGO
float tdble
Floating point type used in TORCS.
void GfuiDisplay(void)
Draw the active GUI screen and swap the GLUT buffers.
void GfuiScreenActivate(void *screen)
Activate a screen and make it current.
int GfImgWritePngNoGamma(unsigned char *img, const char *filename, int width, int height)
Write a framebuffer capture to a png image on disk without gamma metadata.
struct RobotItf tRobotItf
Interface Structure for Robots.
void GfTime2Str(char *result, int resultSize, tdble sec, int sgn)
Convert a time in seconds (float) to an ascii string.
void GfScrGetSize(int *scrw, int *scrh, int *vieww, int *viewh)
Get the screen and viewport sizes.
#define GF_TAILQ_INSERT_TAIL(head, elm, field)
Insert an element at the tail.
#define GF_TAILQ_REMOVE(head, elm, field)
Remove an element.
#define GF_TAILQ_FIRST(head)
First element of a TAILQ.
struct trackSeg tTrackSeg
Track segment (tTrackSeg) The segments can be straights (type TR_STR): (the track goes from the right...
double GfTimeClock(void)
Get the time in seconds.
static void ReRaceBigMsgSet(const char *msg, double life)
static void ReRaceMsgUpdate(void)
static void ReUpdtPitCmd(tCarElt *car)
static void ReOneStep(double deltaTimeIncrement)
static void ReUpdtPitTime(tCarElt *car)
static bool isDriverUpdateDue(int driverType, double currentTime, tRaceEngineInfo *raceEngineInfo)
static void ReSortCars(void)
static void runDueDriverCallbacks(tSituation *s, tRaceEngineInfo *raceEngineInfo)
static void ReRaceRules(tCarElt *car)
static void reCapture(void)
static void resetDriverUpdateTimers(double lastTime, tRaceEngineInfo *raceEngineInfo)
static void ReRaceMsgSet(const char *msg, double life)
static void ReManage(tCarElt *car)
void ReSetRaceBigMsg(const char *msg)
void ReResScreenAddText(char *text)
void ReSetRaceMsg(const char *msg)
#define RCM_MAX_DT_ROBOTS
#define RM_RACE_FINISHING
struct RmInfo tRmInfo
Race Manager General Info.
struct RmMovieCapture tRmMovieCapture
#define RM_PNST_STOPANDGO
struct RmCarRules tRmCarRules
#define RM_PNST_DRIVETHROUGH
#define RM_PNST_STOPANDGO_OK
#define RM_DISP_MODE_CONSOLE
#define RM_DISP_MODE_CAPTURE
#define RM_DISP_MODE_NONE
struct Situation tSituation
cars situation used to inform the GUI and the drivers
#define RM_DISP_MODE_NORMAL
tdble ReComputePitStopServiceTime(const tCarElt *car, const tRmRaceRules *raceRules)
void ReNormalizePitStop(tCarElt *car)
Pit stop command normalization and timing helpers.
void ReUpdateQualifCurRes(tCarElt *car)
void ReSavePracticeLap(tCarElt *car)
#define ROB_PIT_MENU
Call the interactive menu for pit command.
struct RobotItf * robot
private
int lapToClear
the lap before the penalty has to be cleared
@ CORNER_CUTTING_TIME_INVALIDATE
@ CORNER_CUTTING_TIME_PENALTY
@ WALL_HIT_TIME_INVALIDATE
tCarElt ** cars
list of cars
double deltaTime
Legacy rbDrive delta for existing robot modules; normal robots use this value.
double driveDeltaTime[RM_DRV_ROBOT+1]
rbDrive delta indexed by RM_DRV_*; index 0 is unused.
double currentTime
current time in sec since the beginning of the simulation
float msgColor[4]
RGBA of text.
int raceCmd
command issued by the driver
char msg[4][32]
4 lines of 31 characters 0-1 from car 2-3 from race engine
int skillLevel
Driver's skill level (0=rookie -> 3=pro)
int simcollision
For rules etc.
int state
state of the car.
double lastDriveTime[RM_DRV_ROBOT+1]
Last time rbDrive call indexed by RM_DRV_*; index 0 is unused.
double lastTime
Legacy last time rbDrive call for existing robot modules.
Race Engine Car Information about the race.
tTrackSeg * pitEntry
Pit lane segment.
tTrackSeg * pitExit
Pit lane segment.
tTrackSeg * seg
Track segment.
int type
Geometrical type:
tdble radiusr
Radius in meters of the right side of the track (>0)
unsigned int raceInfo
Type of segment regarding the race: Mask value in:
tdble radiusl
Radius in meters of the left side of the track (>0)
struct trackSeg * side[2]
#define TR_START
Segment after start line.
#define TR_LAST
Segment before start line.
#define TR_PITEND
Car pit End.
#define TR_PITSTART
Car pit Star.
#define TR_PIT_STATE_FREE
#define TR_SPEEDLIMIT
Segment where the speed is limited.
#define TR_LFT
Left curve.
#define TR_PIT_ON_TRACK_SIDE
The pits are on the track side.
#define TR_RGT
Right curve.
int track(tModInfo *modInfo)