Beispiel #1
0
void save_database(void)
{
    int i;
    tFace	*curFace;
    sgMat4	m;
    ssgBranch	*b = new ssgBranch();
    

    sgMakeIdentMat4(m);
    for (i = 0; i < NbRows; i++) {
	curFace = GF_TAILQ_FIRST(&(Row[i].faces));
	while (curFace) {
	    if (curFace->isPresent) {
		curFace->branch->setTransform(m);
		ssgFlatten(curFace->branch);
		ssgStripify(curFace->branch);
	    }
	    curFace = GF_TAILQ_NEXT(curFace, link);
	}
    }
    

    b->addKid(Root);
    ssgFlatten(Root);
    ssgStripify(Root);

    myssgSaveAC(OutputFileName, b, SkinFileName);
}
Beispiel #2
0
void
CountRelief(int interior, int *nb_vert, int *nb_seg)
{
    tLine		*curLine;
    tRingListHead	*curHead;
    
    *nb_vert = *nb_seg = 0;
    
    if (Root == NULL) {
	return;
    }

    if (interior) {
	curHead = &InteriorList;
    } else {
	curHead = &ExteriorList;
    }
    
    curLine = GF_TAILQ_FIRST(curHead);
    while (curLine != NULL) {
	ssgBranch *br = curLine->branch->getParent(0);
	ssgBranch *br2 = new ssgBranch();
	
	br2->addKid(br);
	ssgFlatten(br);
	curLine->branch = br2;
	
	countRec((ssgEntity *)curLine->branch, nb_vert, nb_seg);

	curLine = GF_TAILQ_NEXT(curLine, link);
    }
}
Beispiel #3
0
/*
 * Recalculate the bounding box of the faces
 */
void calc_bbox(void)
{
    int		i, j;
    tFace	*curFace;
    ssgEntity	*e;
    sgVec3	min, max;
    int		nbcol;
    
    fprintf(stderr, "Bounding boxes:\n");
    NbMaxCols = 0;
    for (i = 0; i < NbRows; i++) {
	curFace = GF_TAILQ_FIRST(&(Row[i].faces));
	nbcol = 0;
	while (curFace) {
	    nbcol++;
	    if (curFace->isPresent) {
		e = curFace->branch;
		min[0] = min[1] = min[2] = INT_MAX;
		max[0] = max[1] = max[2] = -INT_MAX;
		updt_bbox(e, min, max);
		for (j = 0; j < 3; j++) {
		    curFace->lbbmin[j] = min[j];
		    curFace->lbbmax[j] = max[j];
		}
		fprintf(stderr, "      Face %s : %f %f %f  ---  %f %f %f\n", curFace->faceName, min[0], min[1], min[2], max[0], max[1], max[2]);
	    }
	    curFace = GF_TAILQ_NEXT(curFace, link);
	}
	NbMaxCols = MAX(NbMaxCols, nbcol);
    }
}
Beispiel #4
0
void draw(void)
{
    int i;
    tFace	*curFace;
    sgVec3	cam;
    

    cam[0] = cam[2] = 0;
    cam[1] = -10000;
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    ssgSetOrtho(ImgSize, ImgSize);
    for (i = 0; i < NbRows; i++) {
	curFace = GF_TAILQ_FIRST(&(Row[i].faces));
	while (curFace) {
	    if (curFace->isPresent) {
		printf("Drawing face %s\n", curFace->faceName);
		ssgSetNearFar(MIN(curFace->sbbmin[1], curFace->sbbmax[1]) - 1, 
			      MAX(curFace->sbbmin[1], curFace->sbbmax[1]) + 1);
		ssgCullAndDraw((ssgRoot*)curFace->branch);
	    }
	    curFace = GF_TAILQ_NEXT(curFace, link);
	}
    }
    //saveSkin();
}
Beispiel #5
0
static void
rmFreeDrvList(void)
{
	tDrvElt	*cur;

	while ((cur = GF_TAILQ_FIRST(&DrvList)) != NULL) {
		GF_TAILQ_REMOVE(&DrvList, cur, link);
		free(cur->name);
		free(cur->dname);
		GfParmReleaseHandle(cur->car);
		free(cur);
	}
}
Beispiel #6
0
void set_texture_coord(void)
{
    int		i;
    tFace	*curFace;

    for (i = 0; i < NbRows; i++) {
	curFace = GF_TAILQ_FIRST(&(Row[i].faces));
	while (curFace) {
	    if (curFace->isPresent) {
		/* now apply the matrix to the vertices */
		set_texcoord(curFace->branch, curFace->mat);
	    }
	    curFace = GF_TAILQ_NEXT(curFace, link);
	}
    }
    
}
Beispiel #7
0
void ReSituationUpdater::freezSituation(tRmInfo*& pSituation)
{
	if (pSituation)
	{
		// carList
		if (pSituation->carList)
		{
			for (int nCarInd = 0; nCarInd < _nInitDrivers; nCarInd++)
			{
				tCarElt* pTgtCar = &pSituation->carList[nCarInd];
		
				tCarPenalty *penalty;
				while ((penalty = GF_TAILQ_FIRST(&(pTgtCar->_penaltyList)))
					   != GF_TAILQ_END(&(pTgtCar->_penaltyList)))
				{
					GF_TAILQ_REMOVE (&(pTgtCar->_penaltyList), penalty, link);
					free(penalty);
				}
				free(pTgtCar->_curSplitTime);
				free(pTgtCar->_bestSplitTime);
			}
		
			free(pSituation->carList);
		}
		
		// s
		if (pSituation->s)
			free(pSituation->s);

		// rules
		if (pSituation->rules)
			free(pSituation->rules);

		// raceEngineInfo
		if (pSituation->_reMessage)
			free(pSituation->_reMessage);
		if (pSituation->_reBigMessage)
			free(pSituation->_reBigMessage);
		if (pSituation->_reCarInfo)
			free(pSituation->_reCarInfo);
		
		free(pSituation);
		pSituation = 0;
	}
}
Beispiel #8
0
/* Compute Pit stop time */
void
ReCarsUpdateCarPitTime(tCarElt *car)
{
	tSituation *s = ReInfo->s;
	tReCarInfo *info = &(ReInfo->_reCarInfo[car->index]);
	tCarPenalty *penalty;
	int i;

	// GfLogDebug("ReCarsUpdateCarPitTime(%s) : typ=%d, fuel=%f, rep=%d\n",
	// 		   car->_name, car->_pitStopType, car->_pitFuel, car->_pitRepair);

	switch (car->_pitStopType) {
		case RM_PIT_REPAIR:
			info->totalPitTime = 2.0f + fabs((double)(car->_pitFuel)) / 8.0f + (tdble)(fabs((double)(car->_pitRepair))) * 0.007f;
			car->_scheduledEventTime = s->currentTime + info->totalPitTime;
			RePhysicsEngine().reconfigureCar(car);

			for (i=0; i<4; i++) {
				car->_tyreCondition(i) = 1.01f;
				car->_tyreT_in(i) = 50.0f;
				car->_tyreT_mid(i) = 50.0f;
				car->_tyreT_out(i) = 50.0f;
			}
			GfLogInfo("%s in repair pit stop for %.1f s (refueling by %.1f l, repairing by %d).\n",
					  car->_name, info->totalPitTime, car->_pitFuel, car->_pitRepair);
			break;
		case RM_PIT_STOPANDGO:
			penalty = GF_TAILQ_FIRST(&(car->_penaltyList));
			if (penalty && penalty->penalty == RM_PENALTY_10SEC_STOPANDGO)
				info->totalPitTime = 10.0;
			else
				info->totalPitTime = 0.0;
			car->_scheduledEventTime = s->currentTime + info->totalPitTime;

			// Prevent car->_state & RM_CAR_STATE_PIT from being true for a too short delay,
			// in order for the penalty management to detect it.
			if (car->_scheduledEventTime < s->currentTime + RCM_MAX_DT_SIMU)
				car->_scheduledEventTime += RCM_MAX_DT_SIMU;
														 
			GfLogInfo("%s in Stop-and-Go pit stop for %.1f s.\n", car->_name, info->totalPitTime);
			break;
	}
}
Beispiel #9
0
/*
 * Read the faces from AC3D file
 */
static ssgBranch *
hookNode(char *s)
{
    int		i;
    tFace	*curFace;
    
    for (i = 0; i < NbRows; i++) {
	curFace = GF_TAILQ_FIRST(&(Row[i].faces));
	while (curFace) {
	    if (!strcmp(s, curFace->faceName)) {
		printf("Face %s found\n", s);
		curFace->branch = new ssgTransform();
		curFace->branch->setName(s);
		BrNb++;
		return (ssgBranch*)curFace->branch;
	    }
	    curFace = GF_TAILQ_NEXT(curFace, link);
	}
    }
    
    return (ssgBranch*)NULL;
}
Beispiel #10
0
void
GenRelief(int interior)
{
    tLine		*curLine;
    tRingListHead	*curHead;
    
    
    if (Root == NULL) {
	return;
    }

    if (interior) {
	curHead = &InteriorList;
    } else {
	curHead = &ExteriorList;
    }
    
    curLine = GF_TAILQ_FIRST(curHead);
    while (curLine != NULL) {
	genRec((ssgEntity *)curLine->branch);

	curLine = GF_TAILQ_NEXT(curLine, link);
    }
}
Beispiel #11
0
/* Compute the race rules and penalties */
static void
reCarsApplyRaceRules(tCarElt *car)
{
	char msg[64];
    tCarPenalty		*penalty;
    tTrack		*track = ReInfo->track;
    tRmCarRules		*rules = &(ReInfo->rules[car->index]);
    tTrackSeg		*seg = RtTrackGetSeg(&(car->_trkPos));
    tReCarInfo		*info = &(ReInfo->_reCarInfo[car->index]);
    tTrackSeg		*prevSeg = RtTrackGetSeg(&(info->prevTrkPos));
    static const float	ctrlMsgColor[] = {0.0, 0.0, 1.0, 1.0};

	// DNF cars which need too much time for the current lap, this is mainly to avoid
	// that a "hanging" driver can stop the quali from finishing.
	// Allowed time is longest pitstop possible + time for tracklength with speed???
	// (currently fixed 10 [m/s]).
	// For simplicity. Human driver is an exception to this rule, to allow explorers
	// to enjoy the landscape.
	// Also - don't remove cars that are currently being repaired in pits
	// TODO: Make it configurable.
	if ((car->_curLapTime > 84.5 + ReInfo->track->length/10.0) &&
	    !(car->_state & RM_CAR_STATE_PIT) &&
	    (car->_driverType != RM_DRV_HUMAN))
	{
		if (!(car->_state & RM_CAR_STATE_ELIMINATED))
			GfLogInfo("%s eliminated (too long to finish the lap).\n", car->_name);
		car->_state |= RM_CAR_STATE_ELIMINATED;
	    return;
	}

	// Stop here (no more rules) if not in "Pro" skill level.
	if (car->_skillLevel < 3)
		return;

	// Stop here (no more rules) if "penalties" feature not enables for this race.
	if (! (ReInfo->s->_features & RM_FEATURE_PENALTIES) )
		return;
	
	// Otherwise, update control board and do the referee job.
	// 1) Update control board message about the current penalty if any.
	//    TODO: Optimization : Add penalty->timeStamp and car->ctrl.timeStamp fields
	//          to avoid doing this again and again as long as the penalty is not cleared
	//          whereas it's only needed when the penalty reaches the _penaltyList head.
	penalty = GF_TAILQ_FIRST(&(car->_penaltyList));
    if (penalty) {
		switch (penalty->penalty) {
			case RM_PENALTY_DRIVETHROUGH:
				snprintf(car->ctrl.msg[3], RM_CMD_MAX_MSG_SIZE, "Drive-Through Penalty");
				break;
			case RM_PENALTY_STOPANDGO:
				snprintf(car->ctrl.msg[3], RM_CMD_MAX_MSG_SIZE, "Stop-and-Go Penalty");
				break;
			case RM_PENALTY_10SEC_STOPANDGO:
				snprintf(car->ctrl.msg[3], RM_CMD_MAX_MSG_SIZE, "10s Stop-and-Go Penalty");
				break;
			default:
				*(car->ctrl.msg[3]) = 0;
				break;
		}
		car->ctrl.msg[3][RM_CMD_MAX_MSG_SIZE - 1] = 0; // Some snprintf implementations fail to do so.
		memcpy(car->ctrl.msgColor, ctrlMsgColor, sizeof(car->ctrl.msgColor));
    } else {
		// No penalty => no message.
		*(car->ctrl.msg[3]) = 0;
	}
    
	// 2) Check if not too late for the 1st penalty if any.
    if (penalty) {
		if (car->_laps > penalty->lapToClear) {
			// The penalty was not "executed" : too late to clear => disqualified (out of race)
			reCarsAddPenalty(car, RM_PENALTY_DISQUALIFIED);
			GfLogInfo("%s disqualified (penalty not executed after 5 laps).\n", car->_name);
			return;
		}
	}

	// 3) Check if we can hopefuly clear the penalty because just entered the pit lane.
	//    (means that we enter the clearing process, but that it may fail ; nothing sure)
    if (prevSeg->raceInfo & TR_PITSTART) {

		//if (seg->raceInfo & TR_PIT)
		//	GfLogDebug("%s crossed pit lane entry.\n", car->_name);
		if (penalty) {
			// just entered the pit lane
			if (seg->raceInfo & TR_PIT) {
				switch (penalty->penalty) {
					case RM_PENALTY_DRIVETHROUGH:
						snprintf(msg, sizeof(msg), "%s Drive-Through penalty clearing", car->_name);
						msg[sizeof(msg)-1] = 0; // Some snprintf implementations fail to do so.
						ReSituation::self().setRaceMessage(msg, 5);
						rules->ruleState |= RM_PNST_DRIVETHROUGH;
						GfLogInfo("%s might get its Drive-Through penalty cleared.\n", car->_name);
						break;
					case RM_PENALTY_STOPANDGO:
					case RM_PENALTY_10SEC_STOPANDGO:
						snprintf(msg, sizeof(msg), "%s Stop-and-Go penalty clearing", car->_name);
						msg[sizeof(msg)-1] = 0; // Some snprintf implementations fail to do so.
						ReSituation::self().setRaceMessage(msg, 5);
						rules->ruleState |= RM_PNST_STOPANDGO;
						GfLogInfo("%s might get his Stop-and-Go Penalty cleared.\n", car->_name);
						break;
				}
			}
		}
		
	// 4) If in pit lane for more than 1 segment :
    } else if (prevSeg->raceInfo & TR_PIT) {
		
		if (seg->raceInfo & TR_PIT) {
			// 4a) Check if we can go on with clearing the penalty because stopped in pit.
			if (car->_state & RM_CAR_STATE_PIT) {
				//GfLogDebug("%s is pitting.\n", car->_name);
				if (rules->ruleState & RM_PNST_STOPANDGO && car->_pitStopType == RM_PIT_STOPANDGO) {
					GfLogInfo("%s Stop-and-Go accepted.\n", car->_name);
					rules->ruleState |= RM_PNST_STOPANDGO_OK; // Stop-and-Go really done.
				}
			}
		} else if (seg->raceInfo & TR_PITEND) {
			//GfLogDebug("%s crossing pit lane exit.\n", car->_name);
			// 4b) Check if the penalty can really and finally be removed because exiting pit lane
			//     and everything went well in the clearing process til then.
			if (rules->ruleState & (RM_PNST_DRIVETHROUGH | RM_PNST_STOPANDGO_OK)) {
				snprintf(msg, sizeof(msg), "%s penalty cleared", car->_name);
				msg[sizeof(msg)-1] = 0; // Some snprintf implementations fail to do so.
				ReSituation::self().setRaceMessage(msg, 5);
				penalty = GF_TAILQ_FIRST(&(car->_penaltyList));
				reCarsRemovePenalty(car, penalty);
				GfLogInfo("%s %s penalty cleared.\n", car->_name,
						  (rules->ruleState & RM_PNST_DRIVETHROUGH) ? "Drive-Through" : "Stop-and-Go");
			}
			rules->ruleState = 0;
		} else {
			// 4c) Exiting pit lane the wrong way : add new stop and go penalty if possible.
			//GfLogDebug("%s exiting pit lane by a side (bad).\n", car->_name);
			if (!(rules->ruleState & RM_PNST_STOPANDGO)) {
				reCarsAddPenalty(car, RM_PENALTY_STOPANDGO);
				rules->ruleState = RM_PNST_STOPANDGO;
				GfLogInfo("%s got a Stop-and-Go penalty (went out the pits at a wrong place).\n",
						  car->_name);
			}
		}
		
	// 5) Still crossing pit lane exit (probably a long PITEND segment) : Nothing bad.
    } else if (seg->raceInfo & TR_PITEND) {

		rules->ruleState = 0;
		
	// 6) Entering the pits at a wrong place, add new stop and go penalty if possible.
    } else if (seg->raceInfo & TR_PIT) {
		//GfLogDebug("%s entering pit lane by a side (bad).\n", car->_name);
		if (!(rules->ruleState & RM_PNST_STOPANDGO)) {
			reCarsAddPenalty(car, RM_PENALTY_STOPANDGO);
			rules->ruleState = RM_PNST_STOPANDGO;
			GfLogInfo("%s got a Stop-and-Go penalty (went in the pits at a wrong place).\n",
					  car->_name);
		}
    }

	// 7) If too fast in a speed limited section, add new drive-through penalty if possible.
    if (seg->raceInfo & TR_SPEEDLIMIT) {
		if (!(rules->ruleState & (RM_PNST_OVERSPEED | RM_PNST_STOPANDGO))
			&& car->_speed_x > track->pits.speedLimit) {
			rules->ruleState |= RM_PNST_OVERSPEED;
			reCarsAddPenalty(car, RM_PENALTY_DRIVETHROUGH);
			GfLogInfo("%s got a Drive-Through penalty (too fast in the pits).\n", car->_name);
		}
    }

    // Check for jumping starting lights
    if (ReInfo->s->_raceState & RM_RACE_PRESTART  && car->_speed_x > 1) {
		if (!(rules->ruleState & (RM_PNST_STOPANDGO))) {
			reCarsAddPenalty(car, RM_PENALTY_STOPANDGO);
			rules->ruleState = RM_PNST_STOPANDGO;
			GfLogInfo("%s got a Stop-and-Go penalty (jumped starting lights).\n",
				car->_name);
		}
    }
}
Beispiel #12
0
/** Interactive Drivers list selection
    @param	vs	Pointer on tRmDrvSelect structure (cast to void)
    @warning	The race manager params are modified but not saved.
 */
void
RmDriversSelect(void *vs)
{
    tModList	*list;
    tModList	*curmod;
    char	dname[256];
    char	*sp;
    char	*cardllname;
    int		i, index;
    tDrvElt	*curDrv;
    int		nCars, robotIdx;
    void	*robhdle;
    struct stat st;
    char	*carName;
    void	*carhdle;
    int		human;

#define B_BASE  380
#define B_HT    30

    ds = (tRmDrvSelect*)vs;

    GF_TAILQ_INIT(&DrvList);

    scrHandle = GfuiScreenCreateEx((float*)NULL, NULL, rmdsActivate, NULL, (tfuiCallback)NULL, 1);
    GfuiScreenAddBgImg(scrHandle, "data/img/splash-qrdrv.png");

    GfuiTitleCreate(scrHandle, "Select Drivers", sizeof("Select Drivers"));

    GfuiLabelCreate(scrHandle,
		    "Selected",
		    GFUI_FONT_LARGE,
		    120, 400, GFUI_ALIGN_HC_VB,
		    0);

    GfuiLabelCreate(scrHandle,
		    "Not Selected",
		    GFUI_FONT_LARGE,
		    496, 400, GFUI_ALIGN_HC_VB,
		    0);

    selectedScrollList = GfuiScrollListCreate(scrHandle, GFUI_FONT_MEDIUM_C, 20, 80, GFUI_ALIGN_HL_VB,
					      200, 310, GFUI_SB_RIGHT, NULL, rmdsClickOnDriver);
    unselectedScrollList = GfuiScrollListCreate(scrHandle, GFUI_FONT_MEDIUM_C, 396, 80, GFUI_ALIGN_HL_VB,
						200, 310, GFUI_SB_RIGHT, NULL, rmdsClickOnDriver);


    GfuiButtonCreate(scrHandle, "Accept", GFUI_FONT_LARGE, 210, 40, 150, GFUI_ALIGN_HC_VB, GFUI_MOUSE_UP,
		     NULL, rmdsSelect, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL);

    GfuiButtonCreate(scrHandle, "Cancel", GFUI_FONT_LARGE, 430, 40, 150, GFUI_ALIGN_HC_VB, GFUI_MOUSE_UP,
		     ds->prevScreen, rmdsDeactivate, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL);

    GfuiButtonCreate(scrHandle, "Move Up", GFUI_FONT_MEDIUM, 320, B_BASE, 100, GFUI_ALIGN_HC_VB, GFUI_MOUSE_UP,
		     (void*)-1, rmMove, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL);

    GfuiButtonCreate(scrHandle, "Move Down", GFUI_FONT_MEDIUM, 320, B_BASE - B_HT, 100, GFUI_ALIGN_HC_VB, GFUI_MOUSE_UP,
		     (void*)1, rmMove, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL);
    
    GfuiButtonCreate(scrHandle, "(De)Select", GFUI_FONT_MEDIUM, 320, B_BASE - 2 * B_HT, 100, GFUI_ALIGN_HC_VB, GFUI_MOUSE_UP,
		     (void*)0, rmSelectDeselect, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL);
    
    GfuiButtonCreate(scrHandle, "Set Focus", GFUI_FONT_MEDIUM, 320, B_BASE - 3 * B_HT, 100, GFUI_ALIGN_HC_VB, GFUI_MOUSE_UP,
		     NULL, rmdsSetFocus, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL);
    
    list = (tModList *)NULL;
    sprintf(buf, "%sdrivers", GetLibDir ());
    GfModInfoDir(CAR_IDENT, buf, 1, &list);

    curmod = list;
	if (curmod != NULL) {
		do {
			curmod = curmod->next;
			for (i = 0; i < MAX_MOD_ITF; i++) {
				if (curmod->modInfo[i].name) {
					sp = strrchr(curmod->sopath, '/');
					if (sp == NULL) {
						sp = curmod->sopath;
					} else {
						sp++;
					}
					strcpy(dname, sp);
					dname[strlen(dname) - strlen(DLLEXT) - 1] = 0; /* cut .so or .dll */
					sprintf(buf, "%sdrivers/%s/%s.xml", GetLocalDir(), dname, dname);
					robhdle = GfParmReadFile(buf, GFPARM_RMODE_STD);
					if (!robhdle) {
						sprintf(buf, "drivers/%s/%s.xml", dname, dname);
						robhdle = GfParmReadFile(buf, GFPARM_RMODE_STD);
					}
					sprintf(path, "%s/%s/%d", ROB_SECT_ROBOTS, ROB_LIST_INDEX, curmod->modInfo[i].index);
					carName = GfParmGetStr(robhdle, path, ROB_ATTR_CAR, "");
					if (strcmp(GfParmGetStr(robhdle, path, ROB_ATTR_TYPE, ROB_VAL_ROBOT), ROB_VAL_ROBOT)) {
						human = 1;
					} else {
						human = 0;
					}
					sprintf(path, "cars/%s/%s.xml", carName, carName);
					if (!stat(path, &st)) {
						carhdle = GfParmReadFile(path, GFPARM_RMODE_STD);
						if (carhdle) {
							curDrv = (tDrvElt*)calloc(1, sizeof(tDrvElt));
							curDrv->index = curmod->modInfo[i].index;
							curDrv->dname = strdup(dname);
							curDrv->name = strdup(curmod->modInfo[i].name);
							curDrv->car = carhdle;
							if (human) {
								curDrv->human = 1;
								GF_TAILQ_INSERT_HEAD(&DrvList, curDrv, link);
							} else {
								curDrv->human = 0;
								GF_TAILQ_INSERT_TAIL(&DrvList, curDrv, link);
							}
						} else {
							GfOut("Driver %s not selected because car %s is not readable\n", curmod->modInfo[i].name, carName);
						}
					} else {
						GfOut("Driver %s not selected because car %s is not present\n", curmod->modInfo[i].name, carName);
					}
					GfParmReleaseHandle(robhdle);
				}
			}
		} while (curmod != list);
	}

    nbSelectedDrivers = 0;
    nbMaxSelectedDrivers = (int)GfParmGetNum(ds->param, RM_SECT_DRIVERS, RM_ATTR_MAXNUM, NULL, 0);
    nCars = GfParmGetEltNb(ds->param, RM_SECT_DRIVERS);
    index = 1;
    for (i = 1; i < nCars+1; i++) {
	sprintf(dname, "%s/%d", RM_SECT_DRIVERS, i);
	cardllname = GfParmGetStr(ds->param, dname, RM_ATTR_MODULE, "");
	robotIdx = (int)GfParmGetNum(ds->param, dname, RM_ATTR_IDX, (char*)NULL, 0);

	curDrv = GF_TAILQ_FIRST(&DrvList);
	if (curDrv != NULL) {
	    do {
		if ((curDrv->index == robotIdx) && (strcmp(curDrv->dname, cardllname) == 0)) {
		    if (nbSelectedDrivers < nbMaxSelectedDrivers) {
			GfuiScrollListInsertElement(scrHandle, selectedScrollList, curDrv->name, index, (void*)curDrv);
			curDrv->sel = index++;
			nbSelectedDrivers++;
		    }
		    break;
		}
	    } while ((curDrv = GF_TAILQ_NEXT(curDrv, link)) != NULL);
	}
    }

    curDrv = GF_TAILQ_FIRST(&DrvList);
    if (curDrv != NULL) {
	do {
	    if (curDrv->sel == 0) {
		GfuiScrollListInsertElement(scrHandle, unselectedScrollList, curDrv->name, 1000, (void*)curDrv);
	    }
	} while ((curDrv = GF_TAILQ_NEXT(curDrv, link)) != NULL);
    }

    GfuiLabelCreate(scrHandle, "Focused:", GFUI_FONT_MEDIUM, 320, B_BASE - 5 * B_HT, GFUI_ALIGN_HC_VB, 0);
    cardllname = GfParmGetStr(ds->param, RM_SECT_DRIVERS, RM_ATTR_FOCUSED, "");
    robotIdx = (int)GfParmGetNum(ds->param, RM_SECT_DRIVERS, RM_ATTR_FOCUSEDIDX, (char*)NULL, 0);
    curDrv = GF_TAILQ_FIRST(&DrvList);
    if (curDrv != NULL) {
	do {
	    if ((curDrv->index == robotIdx) && (strcmp(curDrv->dname, cardllname) == 0)) {
		break;
	    }
	} while ((curDrv = GF_TAILQ_NEXT(curDrv, link)) != NULL);
    }
    if (curDrv == NULL) {
	curDrv = GF_TAILQ_FIRST(&DrvList);
    }
    if (curDrv == NULL) {
	FocDrvLabelId = GfuiLabelCreate(scrHandle, "", GFUI_FONT_MEDIUM_C,
					320, B_BASE - 5 * B_HT - GfuiFontHeight(GFUI_FONT_MEDIUM), GFUI_ALIGN_HC_VB, 256);
    } else {
	FocDrvLabelId = GfuiLabelCreate(scrHandle, curDrv->name, GFUI_FONT_MEDIUM_C,
					320, B_BASE - 5 * B_HT - GfuiFontHeight(GFUI_FONT_MEDIUM), GFUI_ALIGN_HC_VB, 256);
    }

    /* Picked Driver Info */
    GfuiLabelCreate(scrHandle, "Driver:", GFUI_FONT_MEDIUM, 320, B_BASE - 7 * B_HT, GFUI_ALIGN_HC_VB, 0);
    PickDrvNameLabelId = GfuiLabelCreateEx(scrHandle, "", aColor, GFUI_FONT_MEDIUM_C,
					   320, B_BASE - 7 * B_HT - GfuiFontHeight(GFUI_FONT_MEDIUM), GFUI_ALIGN_HC_VB, 256);
    GfuiLabelCreate(scrHandle, "Car:", GFUI_FONT_MEDIUM, 320, B_BASE - 8 * B_HT, GFUI_ALIGN_HC_VB, 0);
    PickDrvCarLabelId = GfuiLabelCreateEx(scrHandle, "", aColor, GFUI_FONT_MEDIUM_C,
					  320, B_BASE - 8 * B_HT - GfuiFontHeight(GFUI_FONT_MEDIUM), GFUI_ALIGN_HC_VB, 256);
    GfuiLabelCreate(scrHandle, "Category:", GFUI_FONT_MEDIUM, 320, B_BASE - 9 * B_HT, GFUI_ALIGN_HC_VB, 0);
    PickDrvCategoryLabelId = GfuiLabelCreateEx(scrHandle, "", aColor, GFUI_FONT_MEDIUM_C,
					       320, B_BASE - 9 * B_HT - GfuiFontHeight(GFUI_FONT_MEDIUM), GFUI_ALIGN_HC_VB, 256);
    GfuiMenuDefaultKeysAdd(scrHandle);
    rmdsAddKeys();

    GfuiScreenActivate(scrHandle);
}
/* Compute the race rules and penalties */
static void
ReRaceRules(tCarElt *car)
{
    tCarPenalty		*penalty;
    tTrack		*track = ReInfo->track;
    tRmCarRules		*rules = &(ReInfo->rules[car->index]);
    tTrackSeg		*seg = RtTrackGetSeg(&(car->_trkPos));
    tReCarInfo		*info = &(ReInfo->_reCarInfo[car->index]);
    tTrackSeg		*prevSeg = RtTrackGetSeg(&(info->prevTrkPos));
    static float	color[] = {0.0, 0.0, 1.0, 1.0};

	// DNF cars which need too much time for the current lap, this is mainly to avoid
	// that a "hanging" driver can stop the quali from finishing.
	// Allowed time is longest pitstop possible + time for tracklength with speed??? (currently fixed 10 [m/s]).
	// for simplicity. Human driver is an exception to this rule, to allow explorers
	// to enjoy the landscape.
	// TODO: Make it configurable.
	if ((car->_curLapTime > 84.5 + ReInfo->track->length/10.0) &&
		(car->_driverType != RM_DRV_HUMAN))
	{
		car->_state |= RM_CAR_STATE_ELIMINATED;
	    return;
	}

	if (car->_skillLevel < 3) {
	/* only for the pros */
	return;
    }

	penalty = GF_TAILQ_FIRST(&(car->_penaltyList));
    if (penalty) {
	if (car->_laps > penalty->lapToClear) {
	    /* too late to clear the penalty, out of race */
	    car->_state |= RM_CAR_STATE_ELIMINATED;
	    return;
	}
	switch (penalty->penalty) {
	case RM_PENALTY_DRIVETHROUGH:
	    sprintf(car->ctrl.msg[3], "Drive Through Penalty");
	    break;
	case RM_PENALTY_STOPANDGO:
	    sprintf(car->ctrl.msg[3], "Stop And Go Penalty");
	    break;
	default:
	    *(car->ctrl.msg[3]) = 0;
	    break;
	}
	memcpy(car->ctrl.msgColor, color, sizeof(car->ctrl.msgColor));
    }
    

    if (prevSeg->raceInfo & TR_PITSTART) {
	/* just entered the pit lane */
	if (seg->raceInfo & TR_PIT) {
	    /* may be a penalty can be cleaned up */
	    if (penalty) {
		switch (penalty->penalty) {
		case RM_PENALTY_DRIVETHROUGH:
		    sprintf(buf, "%s DRIVE THROUGH PENALTY CLEANING", car->_name);
		    ReRaceMsgSet(buf, 5);
		    rules->ruleState |= RM_PNST_DRIVETHROUGH;
		    break;
		case RM_PENALTY_STOPANDGO:
		    sprintf(buf, "%s STOP&GO PENALTY CLEANING", car->_name);
		    ReRaceMsgSet(buf, 5);
		    rules->ruleState |= RM_PNST_STOPANDGO;
		    break;
		}
	    }
	}
    } else if (prevSeg->raceInfo & TR_PIT) {
	if (seg->raceInfo & TR_PIT) {
	    /* the car stopped in pits */
	    if (car->_state & RM_CAR_STATE_PIT) {
		if (rules->ruleState & RM_PNST_DRIVETHROUGH) {
		    /* it's not more a drive through */
		    rules->ruleState &= ~RM_PNST_DRIVETHROUGH;
		} else if (rules->ruleState & RM_PNST_STOPANDGO) {
		    rules->ruleState |= RM_PNST_STOPANDGO_OK;
		}
	    } else {
                if(rules->ruleState & RM_PNST_STOPANDGO_OK && car->_pitStopType != RM_PIT_STOPANDGO) {
		    rules->ruleState &= ~ ( RM_PNST_STOPANDGO | RM_PNST_STOPANDGO_OK );
		}
	    }
	} else if (seg->raceInfo & TR_PITEND) {
	    /* went out of the pit lane, check if the current penalty is cleared */
	    if (rules->ruleState & (RM_PNST_DRIVETHROUGH | RM_PNST_STOPANDGO_OK)) {
		/* clear the penalty */
		sprintf(buf, "%s penalty cleared", car->_name);
		ReRaceMsgSet(buf, 5);
		penalty = GF_TAILQ_FIRST(&(car->_penaltyList));
		GF_TAILQ_REMOVE(&(car->_penaltyList), penalty, link);
		FREEZ(penalty);
	    }
	    rules->ruleState = 0;
	} else {
	    /* went out of the pit lane illegally... */
	    /* it's a new stop and go... */
	    if (!(rules->ruleState & RM_PNST_STNGO)) {
		sprintf(buf, "%s STOP&GO PENALTY", car->_name);
		ReRaceMsgSet(buf, 5);
		penalty = (tCarPenalty*)calloc(1, sizeof(tCarPenalty));
		penalty->penalty = RM_PENALTY_STOPANDGO;
		penalty->lapToClear = car->_laps + 5;
		GF_TAILQ_INSERT_TAIL(&(car->_penaltyList), penalty, link);
		rules->ruleState = RM_PNST_STNGO;
	    }
	}
    } else if (seg->raceInfo & TR_PITEND) {
	rules->ruleState = 0;
    } else if (seg->raceInfo & TR_PIT) {
	/* entrered the pits not from the pit entry... */
	/* it's a new stop and go... */
	if (!(rules->ruleState & RM_PNST_STNGO)) {
	    sprintf(buf, "%s STOP&GO PENALTY", car->_name);
	    ReRaceMsgSet(buf, 5);
	    penalty = (tCarPenalty*)calloc(1, sizeof(tCarPenalty));
	    penalty->penalty = RM_PENALTY_STOPANDGO;
	    penalty->lapToClear = car->_laps + 5;
	    GF_TAILQ_INSERT_TAIL(&(car->_penaltyList), penalty, link);
	    rules->ruleState = RM_PNST_STNGO;
	}
    }

    if (seg->raceInfo & TR_SPEEDLIMIT) {
	if (!(rules->ruleState & (RM_PNST_SPD | RM_PNST_STNGO)) && (car->_speed_x > track->pits.speedLimit)) {
	    sprintf(buf, "%s DRIVE THROUGH PENALTY", car->_name);
	    ReRaceMsgSet(buf, 5);
	    rules->ruleState |= RM_PNST_SPD;
	    penalty = (tCarPenalty*)calloc(1, sizeof(tCarPenalty));
	    penalty->penalty = RM_PENALTY_DRIVETHROUGH;
	    penalty->lapToClear = car->_laps + 5;
	    GF_TAILQ_INSERT_TAIL(&(car->_penaltyList), penalty, link);
	}
    }


}
Beispiel #14
0
void calc_coord(void)
{
    sgMat4	m, m2;
    int		i, j;
    tFace	*curFace;
    float	width, height;
    float	scale, offX, offY;
    int		largerRow;
    float	maxWidth;
    int		col;
    ssgBranch	*branch;

    ColWidth = (float*)calloc(NbMaxCols, sizeof(float));

    fprintf(stderr, "After Rotation:\n");
    largerRow = 0;
    maxWidth = 0;
    for (i = 0; i < NbRows; i++) {
	curFace = GF_TAILQ_FIRST(&(Row[i].faces));
	while (curFace) {
	    if (curFace->isPresent) {
		branch = curFace->branch->getParent(0);
		if (branch->isAKindOf(_SSG_TYPE_BASETRANSFORM)) {
		    ((ssgBaseTransform*)branch)->getTransform(m2);
		    curFace->align[0] *= m2[3][0];
		    curFace->align[1] *= m2[3][1];
		    curFace->align[2] *= m2[3][2];
		    fprintf(stderr, "Align face %s : %f %f %f\n", curFace->faceName, curFace->align[0], curFace->align[1], curFace->align[2]);
		}
		sgMakeTransMat4(m, curFace->align);


		sgMakeIdentMat4(m2);
		for (j = 0; j < 3; j++) {
		    m2[j][j] = curFace->lscale[j];
		}
		sgPostMultMat4(m, m2);

		sgMakeRotMat4(m2, curFace->xform.hpr);
		sgPostMultMat4(m, m2);

		sgCopyMat4(curFace->mat, m);

		sgXformPnt3(curFace->sbbmin, curFace->lbbmin, m);
		sgXformPnt3(curFace->sbbmax, curFace->lbbmax, m);

		fprintf(stderr, "      Face %s : %f %f %f  ---  %f %f %f\n",
			curFace->faceName, curFace->sbbmin[0], curFace->sbbmin[1], curFace->sbbmin[2],
			curFace->sbbmax[0], curFace->sbbmax[1], curFace->sbbmax[2]);
		curFace->lwidth = 2.0 * MAX(fabs(curFace->sbbmin[0]), fabs(curFace->sbbmax[0]));
		curFace->lheight = 2.0 * MAX(fabs(curFace->sbbmin[2]), fabs(curFace->sbbmax[2]));
		//curFace->lwidth = fabs(curFace->sbbmin[0] - curFace->sbbmax[0]);
		//curFace->lheight = fabs(curFace->sbbmin[2] - curFace->sbbmax[2]);
		Row[i].lwidth += curFace->lwidth;
		Row[i].lheight = MAX(Row[i].lheight, curFace->lheight);
	    }
	    curFace = GF_TAILQ_NEXT(curFace, link);
	}
	if (Row[i].lwidth > maxWidth) {
	    maxWidth = Row[i].lwidth;
	    largerRow = i;
	}
    }

    height = 0;
    fprintf(stderr, "After Scaling:\n");
    for (i = 0; i < NbRows; i++) {
	height += Row[i].lheight;
    }
    width = maxWidth;
    scale = (float)ImgSize / MAX(width, height);

    curFace = GF_TAILQ_FIRST(&(Row[largerRow].faces));
    i = 0;
    fprintf(stderr, "Columns : ");
    while (curFace) {
	ColWidth[i] = curFace->lwidth * scale;
	fprintf(stderr, "%.2f  ", ColWidth[i]);
	curFace = GF_TAILQ_NEXT(curFace, link);
	i++;
    }
    fprintf(stderr, "\n");

    fprintf(stderr, "Total Width = %.2f   Height = %.2f\n", width, height);
    fprintf(stderr, "Image Width = %.2f   Height = %.2f\n", width*scale, height*scale);

    offY = - (float)ImgSize / 2.0;
    for (i = 0; i < NbRows; i++) {
	curFace = GF_TAILQ_FIRST(&(Row[i].faces));
	offY += Row[i].lheight*scale / 2.0;
	col = 0;
	offX = - (float)ImgSize / 2.0;
	while (curFace) {
	    if (curFace->isPresent) {
		sgCopyMat4(m, curFace->mat);
		curFace->texScale = scale;
		sgMakeIdentMat4(m2);
		for (j = 0; j < 3; j++) {
		    m2[j][j] = scale;
		}
		sgPostMultMat4(m, m2);
		sgXformPnt3(curFace->sbbmin, curFace->lbbmin, m);
		sgXformPnt3(curFace->sbbmax, curFace->lbbmax, m);
		offX += ColWidth[col] / 2.0;
		curFace->offset[0] = offX;
		curFace->offset[2] = offY;
		offX += ColWidth[col] / 2.0;
		sgMakeTransMat4(m2, curFace->offset);
		sgPostMultMat4(m, m2);
		sgCopyMat4(curFace->mat, m);

		curFace->branch->setTransform(m);
	    } else {
		offX += ColWidth[col];
	    }
	    col++;

	    curFace = GF_TAILQ_NEXT(curFace, link);
	}
	offY += Row[i].lheight*scale / 2.0;
    }
}