/* * Read the faces from AC3D file * separate between interior and exterior lines */ static ssgBranch * hookNode(char *s) { tLine *line; line = (tLine*)calloc(1, sizeof(tLine)); line->branch = new ssgBranch(); if (strncmp(s, "interior", 8) == 0) { GF_TAILQ_INSERT_TAIL(&InteriorList, line, link); } else { GF_TAILQ_INSERT_TAIL(&ExteriorList, line, link); } return line->branch; }
static void reCarsAddPenalty(tCarElt *car, int penalty) { char msg[64]; tCarPenalty *newPenalty; if (penalty == RM_PENALTY_DRIVETHROUGH) snprintf(msg, sizeof(msg), "%s Drive-Through penalty", car->_name); else if (penalty == RM_PENALTY_STOPANDGO) snprintf(msg, sizeof(msg), "%s Stop-and-Go penalty", car->_name); else if (penalty == RM_PENALTY_10SEC_STOPANDGO) snprintf(msg, sizeof(msg), "%s 10s Stop-and-Go penalty", car->_name); else if (penalty == RM_PENALTY_DISQUALIFIED) snprintf(msg, sizeof(msg), "%s disqualified", car->_name); msg[sizeof(msg)-1] = 0; // Some snprintf implementations fail to do so. ReSituation::self().setRaceMessage(msg, 5); /* If disqualified, remove the car from the track */ if (penalty == RM_PENALTY_DISQUALIFIED) { car->_state |= RM_CAR_STATE_ELIMINATED; return; } // Add the penalty in the list. newPenalty = (tCarPenalty*)calloc(1, sizeof(tCarPenalty)); newPenalty->penalty = penalty; newPenalty->lapToClear = car->_laps + 5; GF_TAILQ_INSERT_TAIL(&(car->_penaltyList), newPenalty, link); //GfLogDebug("reCarsAddPenalty(car #%d) : Added penalty %p\n", car->index, newPenalty); }
void load_params(void) { int i, j; int nbcol; char *col; char buf[256]; tFace *curFace; char *s; ImgSize = (int)GfParmGetNum(ParamHandle, "image", "size", NULL, 256); NbRows = GfParmGetEltNb(ParamHandle, "faces"); Row = (tRow*)calloc(NbRows, sizeof(tRow)); GfParmListSeekFirst(ParamHandle, "faces"); for (i = 0; i < NbRows; i++) { col = GfParmListGetCurEltName(ParamHandle, "faces"); GF_TAILQ_INIT(&(Row[i].faces)); sprintf(buf, "faces/%s/col", col); nbcol = GfParmGetEltNb(ParamHandle, buf); GfParmListSeekFirst(ParamHandle, buf); for (j = 0; j < nbcol; j++) { curFace = (tFace*)calloc(1, sizeof(tFace)); GF_TAILQ_INSERT_TAIL(&(Row[i].faces), curFace, link); curFace->faceName = GfParmGetCurStr(ParamHandle, buf, "face name", NULL); if ((curFace->faceName != 0) && (strlen(curFace->faceName) != 0)) { curFace->isPresent = true; curFace->xform.hpr[1] = GfParmGetCurNum(ParamHandle, buf, "rotX", NULL, 0.0); curFace->xform.hpr[2] = -GfParmGetCurNum(ParamHandle, buf, "rotZ", NULL, 0.0); curFace->xform.hpr[0] = GfParmGetCurNum(ParamHandle, buf, "rotY", NULL, 0.0); curFace->lscale[0] = GfParmGetCurNum(ParamHandle, buf, "scaleX", NULL, 1.0); curFace->lscale[1] = GfParmGetCurNum(ParamHandle, buf, "scaleZ", NULL, 1.0); curFace->lscale[2] = GfParmGetCurNum(ParamHandle, buf, "scaleY", NULL, 1.0); s = GfParmGetCurStr(ParamHandle, buf, "align", ""); switch (s[0]) { case 'X': case 'x': curFace->align[0] = 1.0; break; case 'Y': case 'y': curFace->align[2] = 1.0; break; case 'Z': case 'z': curFace->align[1] = -1.0; break; } } GfParmListSeekNext(ParamHandle, buf); } GfParmListSeekNext(ParamHandle, "faces"); } }
/** 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); } } }