/** Recentre the mouse on the screen. @ingroup ctrl @return none */ void GfctrlMouseCenter(void) { int sw, sh, vw, vh; GfScrGetSize(&sw, &sh, &vw, &vh); GfuiMouseSetPos(sw / 2, sh / 2); }
static void onActivate2(void * /* dummy */) { int dummy; GfScrGetSize(&scrw, &scrh, &dummy, &dummy); CalState = 0; GetNextAxis(); GfuiLabelSetText(scrHandle2, InstId, Instructions[CalState]); if (CalState < 4) { glutIdleFunc(IdleMouseInit); GfctrlMouseCenter(); } }
bool LegacyMenu::setupGraphicsView() { // Initialize the graphics view. if (!_piGraphicsEngine) return false; // Retrieve the screen dimensions. int sw, sh, vw, vh; GfScrGetSize(&sw, &sh, &vw, &vh); _bfGraphicsState |= eViewSetup; // Setup the graphics view. return _piGraphicsEngine->setupView((sw - vw) / 2, (sh - vh) / 2, vw, vh, _hscrGame); }
/** Save a screen shot in png format. @ingroup screen */ void GfuiScreenShot(void * /* notused */) { unsigned char *img; const int BUFSIZE = 1024; char buf[BUFSIZE]; struct tm *stm; time_t t; int sw, sh, vw, vh; char path[BUFSIZE]; snprintf(path, BUFSIZE, "%sscreenshots", GetLocalDir()); // Ensure that screenshot directory exists. if (GfCreateDir(path) == GF_DIR_CREATED) { GfScrGetSize(&sw, &sh, &vw, &vh); img = (unsigned char*)malloc(vw * vh * 3); if (img == NULL) { return; } glPixelStorei(GL_PACK_ROW_LENGTH, 0); glPixelStorei(GL_PACK_ALIGNMENT, 1); glReadBuffer(GL_FRONT); glReadPixels((sw-vw)/2, (sh-vh)/2, vw, vh, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)img); t = time(NULL); stm = localtime(&t); snprintf(buf, BUFSIZE, "%s/torcs-%4d%02d%02d%02d%02d%02d.png", path, stm->tm_year+1900, stm->tm_mon+1, stm->tm_mday, stm->tm_hour, stm->tm_min, stm->tm_sec); GfImgWritePng(img, buf, vw, vh); free(img); } }
static void reCapture(void) { unsigned char *img; int sw, sh, vw, vh; tRmMovieCapture *capture = &(ReInfo->movieCapture); GfScrGetSize(&sw, &sh, &vw, &vh); img = (unsigned char*)malloc(vw * vh * 3); if (img == NULL) { return; } glPixelStorei(GL_PACK_ROW_LENGTH, 0); glPixelStorei(GL_PACK_ALIGNMENT, 1); glReadBuffer(GL_FRONT); glReadPixels((sw-vw)/2, (sh-vh)/2, vw, vh, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)img); sprintf(buf, "%s/torcs-%4.4d-%8.8d.png", capture->outputBase, capture->currentCapture, capture->currentFrame++); GfImgWritePng(img, buf, vw, vh); free(img); }
/** Display function for the GUI to be called during redisplay of glut. @ingroup gui */ void GfuiDisplay(void) { tGfuiObject *curObj; glDisable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); glDisable(GL_CULL_FACE); glDisable(GL_ALPHA_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GfScrGetSize(&ScrW, &ScrH, &ViewW, &ViewH); glViewport((ScrW-ViewW) / 2, (ScrH-ViewH) / 2, ViewW, ViewH); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0, GfuiScreen->width, 0, GfuiScreen->height); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if (GfuiScreen->bgColor[3] != 0.0) { glClearColor(GfuiScreen->bgColor[0], GfuiScreen->bgColor[1], GfuiScreen->bgColor[2], GfuiScreen->bgColor[3]); glClear(GL_COLOR_BUFFER_BIT); } if (glIsTexture(GfuiScreen->bgImage) == GL_TRUE) { GLfloat tx1 = 0.0f, tx2 = 1.0f, ty1 = 0.0f, ty2 = 1.0f; // All background images are 16:10 images which are stored as quadratic images. // Compute texture coordinates to ensure proper unskewed/unstretched display of // image content. tdble rfactor = (16.0f*ViewH)/(10.0f*ViewW); if (rfactor >= 1.0f) { // Aspect ratio of view is smaller than 16:10, "cut off" sides tdble tdx = (1.0f-1.0f/rfactor)/2.0f; tx1 += tdx; tx2 -= tdx; } else { // Aspect ratio of view is larger than 16:10, "cut off" top and bottom tdble tdy = (1.0f-rfactor)/2.0f; ty1 += tdy; ty2 -= tdy; } glDisable(GL_BLEND); glEnable(GL_TEXTURE_2D); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glColor3f(0.0, 0.0, 1.0); glBindTexture(GL_TEXTURE_2D, GfuiScreen->bgImage); glBegin(GL_QUADS); glTexCoord2f(tx1, ty1); glVertex3f(0.0, 0.0, 0.0); glTexCoord2f(tx1, ty2); glVertex3f(0.0, GfuiScreen->height, 0.0); glTexCoord2f(tx2, ty2); glVertex3f(GfuiScreen->width, GfuiScreen->height, 0.0); glTexCoord2f(tx2, ty1); glVertex3f(GfuiScreen->width, 0.0, 0.0); glEnd(); glDisable(GL_TEXTURE_2D); glEnable(GL_BLEND); } curObj = GfuiScreen->objects; if (curObj) { do { curObj = curObj->next; GfuiDraw(curObj); } while (curObj != GfuiScreen->objects); } if (!GfuiMouseHW && GfuiMouseVisible && GfuiScreen->mouseAllowed) { GfuiDrawCursor(); } glDisable(GL_BLEND); glutSwapBuffers(); }
static void common_drive(int index, tCarElt* car, tSituation *s) { tdble slip; tdble ax0; tdble brake; tdble clutch; tdble throttle; tdble leftSteer; tdble rightSteer; int scrw, scrh, dummy; int idx = index - 1; tControlCmd *cmd = HCtx[idx]->CmdControl; const int BUFSIZE = 1024; char sstring[BUFSIZE]; static int firstTime = 1; if (firstTime) { if (HCtx[idx]->MouseControlUsed) { GfuiMouseShow(); GfctrlMouseInitCenter(); } GfuiKeyEventRegisterCurrent(onKeyAction); GfuiSKeyEventRegisterCurrent(onSKeyAction); firstTime = 0; } HCtx[idx]->distToStart = RtGetDistFromStart(car); HCtx[idx]->Gear = (tdble)car->_gear; /* telemetry */ GfScrGetSize(&scrw, &scrh, &dummy, &dummy); memset(&(car->ctrl), 0, sizeof(tCarCtrl)); car->_lightCmd = HCtx[idx]->lightCmd; if (car->_laps != HCtx[idx]->LastPitStopLap) { car->_raceCmd = RM_CMD_PIT_ASKED; } if (lastKeyUpdate != s->currentTime) { /* Update the controls only once for all the players */ updateKeys(); if (joyPresent) { GfctrlJoyGetCurrent(joyInfo); } GfctrlMouseGetCurrent(mouseInfo); lastKeyUpdate = s->currentTime; } if (((cmd[CMD_ABS].type == GFCTRL_TYPE_JOY_BUT) && joyInfo->edgeup[cmd[CMD_ABS].val]) || ((cmd[CMD_ABS].type == GFCTRL_TYPE_KEYBOARD) && keyInfo[cmd[CMD_ABS].val].edgeUp) || ((cmd[CMD_ABS].type == GFCTRL_TYPE_SKEYBOARD) && skeyInfo[cmd[CMD_ABS].val].edgeUp)) { HCtx[idx]->ParamAbs = 1 - HCtx[idx]->ParamAbs; snprintf(sstring, BUFSIZE, "%s/%s/%d", HM_SECT_PREF, HM_LIST_DRV, index); GfParmSetStr(PrefHdle, sstring, HM_ATT_ABS, Yn[1 - HCtx[idx]->ParamAbs]); GfParmWriteFile(NULL, PrefHdle, "Human"); } if (((cmd[CMD_ASR].type == GFCTRL_TYPE_JOY_BUT) && joyInfo->edgeup[cmd[CMD_ASR].val]) || ((cmd[CMD_ASR].type == GFCTRL_TYPE_KEYBOARD) && keyInfo[cmd[CMD_ASR].val].edgeUp) || ((cmd[CMD_ASR].type == GFCTRL_TYPE_SKEYBOARD) && skeyInfo[cmd[CMD_ASR].val].edgeUp)) { HCtx[idx]->ParamAsr = 1 - HCtx[idx]->ParamAsr; snprintf(sstring, BUFSIZE, "%s/%s/%d", HM_SECT_PREF, HM_LIST_DRV, index); GfParmSetStr(PrefHdle, sstring, HM_ATT_ASR, Yn[1 - HCtx[idx]->ParamAsr]); GfParmWriteFile(NULL, PrefHdle, "Human"); } const int bufsize = sizeof(car->_msgCmd[0]); snprintf(car->_msgCmd[0], bufsize, "%s %s", (HCtx[idx]->ParamAbs ? "ABS" : ""), (HCtx[idx]->ParamAsr ? "ASR" : "")); memcpy(car->_msgColorCmd, color, sizeof(car->_msgColorCmd)); if (((cmd[CMD_SPDLIM].type == GFCTRL_TYPE_JOY_BUT) && (joyInfo->levelup[cmd[CMD_SPDLIM].val] == 1)) || ((cmd[CMD_SPDLIM].type == GFCTRL_TYPE_KEYBOARD) && (keyInfo[cmd[CMD_SPDLIM].val].state == GFUI_KEY_DOWN)) || ((cmd[CMD_SPDLIM].type == GFCTRL_TYPE_SKEYBOARD) && (skeyInfo[cmd[CMD_SPDLIM].val].state == GFUI_KEY_DOWN))) { speedLimiter = 1; snprintf(car->_msgCmd[1], bufsize, "Speed Limiter On"); } else { speedLimiter = 0; snprintf(car->_msgCmd[1], bufsize, "Speed Limiter Off"); } if (((cmd[CMD_LIGHT1].type == GFCTRL_TYPE_JOY_BUT) && joyInfo->edgeup[cmd[CMD_LIGHT1].val]) || ((cmd[CMD_LIGHT1].type == GFCTRL_TYPE_KEYBOARD) && keyInfo[cmd[CMD_LIGHT1].val].edgeUp) || ((cmd[CMD_LIGHT1].type == GFCTRL_TYPE_SKEYBOARD) && skeyInfo[cmd[CMD_LIGHT1].val].edgeUp)) { if (HCtx[idx]->lightCmd & RM_LIGHT_HEAD1) { HCtx[idx]->lightCmd &= ~(RM_LIGHT_HEAD1 | RM_LIGHT_HEAD2); } else { HCtx[idx]->lightCmd |= RM_LIGHT_HEAD1 | RM_LIGHT_HEAD2; } } switch (cmd[CMD_LEFTSTEER].type) { case GFCTRL_TYPE_JOY_AXIS: ax0 = joyInfo->ax[cmd[CMD_LEFTSTEER].val] + cmd[CMD_LEFTSTEER].deadZone; if (ax0 > cmd[CMD_LEFTSTEER].max) { ax0 = cmd[CMD_LEFTSTEER].max; } else if (ax0 < cmd[CMD_LEFTSTEER].min) { ax0 = cmd[CMD_LEFTSTEER].min; } // normalize ax0 to -1..0 ax0 = (ax0 - cmd[CMD_LEFTSTEER].max) / (cmd[CMD_LEFTSTEER].max - cmd[CMD_LEFTSTEER].min); leftSteer = -SIGN(ax0) * cmd[CMD_LEFTSTEER].pow * pow(fabs(ax0), cmd[CMD_LEFTSTEER].sens) / (1.0 + cmd[CMD_LEFTSTEER].spdSens * car->pub.speed); break; case GFCTRL_TYPE_MOUSE_AXIS: ax0 = mouseInfo->ax[cmd[CMD_LEFTSTEER].val] - cmd[CMD_LEFTSTEER].deadZone; //FIXME: correct? if (ax0 > cmd[CMD_LEFTSTEER].max) { ax0 = cmd[CMD_LEFTSTEER].max; } else if (ax0 < cmd[CMD_LEFTSTEER].min) { ax0 = cmd[CMD_LEFTSTEER].min; } ax0 = ax0 * cmd[CMD_LEFTSTEER].pow; leftSteer = pow(fabs(ax0), cmd[CMD_LEFTSTEER].sens) / (1.0 + cmd[CMD_LEFTSTEER].spdSens * car->pub.speed / 10.0); break; case GFCTRL_TYPE_KEYBOARD: case GFCTRL_TYPE_SKEYBOARD: case GFCTRL_TYPE_JOY_BUT: if (cmd[CMD_LEFTSTEER].type == GFCTRL_TYPE_KEYBOARD) { ax0 = keyInfo[cmd[CMD_LEFTSTEER].val].state; } else if (cmd[CMD_LEFTSTEER].type == GFCTRL_TYPE_SKEYBOARD) { ax0 = skeyInfo[cmd[CMD_LEFTSTEER].val].state; } else { ax0 = joyInfo->levelup[cmd[CMD_LEFTSTEER].val]; } if (ax0 == 0) { HCtx[idx]->prevLeftSteer = leftSteer = 0; } else { ax0 = 2 * ax0 - 1; leftSteer = HCtx[idx]->prevLeftSteer + ax0 * cmd[CMD_LEFTSTEER].sens * s->deltaTime / (1.0 + cmd[CMD_LEFTSTEER].spdSens * car->pub.speed / 10.0); if (leftSteer > 1.0) leftSteer = 1.0; if (leftSteer < 0.0) leftSteer = 0.0; HCtx[idx]->prevLeftSteer = leftSteer; } break; default: leftSteer = 0; break; } switch (cmd[CMD_RIGHTSTEER].type) { case GFCTRL_TYPE_JOY_AXIS: ax0 = joyInfo->ax[cmd[CMD_RIGHTSTEER].val] - cmd[CMD_RIGHTSTEER].deadZone; if (ax0 > cmd[CMD_RIGHTSTEER].max) { ax0 = cmd[CMD_RIGHTSTEER].max; } else if (ax0 < cmd[CMD_RIGHTSTEER].min) { ax0 = cmd[CMD_RIGHTSTEER].min; } // normalize ax to 0..1 ax0 = (ax0 - cmd[CMD_RIGHTSTEER].min) / (cmd[CMD_RIGHTSTEER].max - cmd[CMD_RIGHTSTEER].min); rightSteer = -SIGN(ax0) * cmd[CMD_RIGHTSTEER].pow * pow(fabs(ax0), cmd[CMD_RIGHTSTEER].sens) / (1.0 + cmd[CMD_RIGHTSTEER].spdSens * car->pub.speed); break; case GFCTRL_TYPE_MOUSE_AXIS: ax0 = mouseInfo->ax[cmd[CMD_RIGHTSTEER].val] - cmd[CMD_RIGHTSTEER].deadZone; if (ax0 > cmd[CMD_RIGHTSTEER].max) { ax0 = cmd[CMD_RIGHTSTEER].max; } else if (ax0 < cmd[CMD_RIGHTSTEER].min) { ax0 = cmd[CMD_RIGHTSTEER].min; } ax0 = ax0 * cmd[CMD_RIGHTSTEER].pow; rightSteer = - pow(fabs(ax0), cmd[CMD_RIGHTSTEER].sens) / (1.0 + cmd[CMD_RIGHTSTEER].spdSens * car->pub.speed / 10.0); break; case GFCTRL_TYPE_KEYBOARD: case GFCTRL_TYPE_SKEYBOARD: case GFCTRL_TYPE_JOY_BUT: if (cmd[CMD_RIGHTSTEER].type == GFCTRL_TYPE_KEYBOARD) { ax0 = keyInfo[cmd[CMD_RIGHTSTEER].val].state; } else if (cmd[CMD_RIGHTSTEER].type == GFCTRL_TYPE_SKEYBOARD) { ax0 = skeyInfo[cmd[CMD_RIGHTSTEER].val].state; } else { ax0 = joyInfo->levelup[cmd[CMD_RIGHTSTEER].val]; } if (ax0 == 0) { HCtx[idx]->prevRightSteer = rightSteer = 0; } else { ax0 = 2 * ax0 - 1; rightSteer = HCtx[idx]->prevRightSteer - ax0 * cmd[CMD_RIGHTSTEER].sens * s->deltaTime/ (1.0 + cmd[CMD_RIGHTSTEER].spdSens * car->pub.speed / 10.0); if (rightSteer > 0.0) rightSteer = 0.0; if (rightSteer < -1.0) rightSteer = -1.0; HCtx[idx]->prevRightSteer = rightSteer; } break; default: rightSteer = 0; break; } car->_steerCmd = leftSteer + rightSteer; switch (cmd[CMD_BRAKE].type) { case GFCTRL_TYPE_JOY_AXIS: brake = joyInfo->ax[cmd[CMD_BRAKE].val]; if (brake > cmd[CMD_BRAKE].max) { brake = cmd[CMD_BRAKE].max; } else if (brake < cmd[CMD_BRAKE].min) { brake = cmd[CMD_BRAKE].min; } car->_brakeCmd = fabs(cmd[CMD_BRAKE].pow * pow(fabs((brake - cmd[CMD_BRAKE].minVal) / (cmd[CMD_BRAKE].max - cmd[CMD_BRAKE].min)), cmd[CMD_BRAKE].sens)); break; case GFCTRL_TYPE_MOUSE_AXIS: ax0 = mouseInfo->ax[cmd[CMD_BRAKE].val] - cmd[CMD_BRAKE].deadZone; if (ax0 > cmd[CMD_BRAKE].max) { ax0 = cmd[CMD_BRAKE].max; } else if (ax0 < cmd[CMD_BRAKE].min) { ax0 = cmd[CMD_BRAKE].min; } ax0 = ax0 * cmd[CMD_BRAKE].pow; car->_brakeCmd = pow(fabs(ax0), cmd[CMD_BRAKE].sens) / (1.0 + cmd[CMD_BRAKE].spdSens * car->_speed_x / 10.0); break; case GFCTRL_TYPE_JOY_BUT: car->_brakeCmd = joyInfo->levelup[cmd[CMD_BRAKE].val]; break; case GFCTRL_TYPE_MOUSE_BUT: car->_brakeCmd = mouseInfo->button[cmd[CMD_BRAKE].val]; break; case GFCTRL_TYPE_KEYBOARD: car->_brakeCmd = keyInfo[cmd[CMD_BRAKE].val].state; break; case GFCTRL_TYPE_SKEYBOARD: car->_brakeCmd = skeyInfo[cmd[CMD_BRAKE].val].state; break; default: car->_brakeCmd = 0; break; } switch (cmd[CMD_CLUTCH].type) { case GFCTRL_TYPE_JOY_AXIS: clutch = joyInfo->ax[cmd[CMD_CLUTCH].val]; if (clutch > cmd[CMD_CLUTCH].max) { clutch = cmd[CMD_CLUTCH].max; } else if (clutch < cmd[CMD_CLUTCH].min) { clutch = cmd[CMD_CLUTCH].min; } car->_clutchCmd = fabs(cmd[CMD_CLUTCH].pow * pow(fabs((clutch - cmd[CMD_CLUTCH].minVal) / (cmd[CMD_CLUTCH].max - cmd[CMD_CLUTCH].min)), cmd[CMD_CLUTCH].sens)); break; case GFCTRL_TYPE_MOUSE_AXIS: ax0 = mouseInfo->ax[cmd[CMD_CLUTCH].val] - cmd[CMD_CLUTCH].deadZone; if (ax0 > cmd[CMD_CLUTCH].max) { ax0 = cmd[CMD_CLUTCH].max; } else if (ax0 < cmd[CMD_CLUTCH].min) { ax0 = cmd[CMD_CLUTCH].min; } ax0 = ax0 * cmd[CMD_CLUTCH].pow; car->_clutchCmd = pow(fabs(ax0), cmd[CMD_CLUTCH].sens) / (1.0 + cmd[CMD_CLUTCH].spdSens * car->_speed_x / 10.0); break; case GFCTRL_TYPE_JOY_BUT: car->_clutchCmd = joyInfo->levelup[cmd[CMD_CLUTCH].val]; break; case GFCTRL_TYPE_MOUSE_BUT: car->_clutchCmd = mouseInfo->button[cmd[CMD_CLUTCH].val]; break; case GFCTRL_TYPE_KEYBOARD: car->_clutchCmd = keyInfo[cmd[CMD_CLUTCH].val].state; break; case GFCTRL_TYPE_SKEYBOARD: car->_clutchCmd = skeyInfo[cmd[CMD_CLUTCH].val].state; break; default: car->_clutchCmd = 0; break; } // if player's used the clutch manually then we dispense with autoClutch if (car->_clutchCmd != 0.0f) HCtx[idx]->autoClutch = 0; switch (cmd[CMD_THROTTLE].type) { case GFCTRL_TYPE_JOY_AXIS: throttle = joyInfo->ax[cmd[CMD_THROTTLE].val]; if (throttle > cmd[CMD_THROTTLE].max) { throttle = cmd[CMD_THROTTLE].max; } else if (throttle < cmd[CMD_THROTTLE].min) { throttle = cmd[CMD_THROTTLE].min; } car->_accelCmd = fabs(cmd[CMD_THROTTLE].pow * pow(fabs((throttle - cmd[CMD_THROTTLE].minVal) / (cmd[CMD_THROTTLE].max - cmd[CMD_THROTTLE].min)), cmd[CMD_THROTTLE].sens)); break; case GFCTRL_TYPE_MOUSE_AXIS: ax0 = mouseInfo->ax[cmd[CMD_THROTTLE].val] - cmd[CMD_THROTTLE].deadZone; if (ax0 > cmd[CMD_THROTTLE].max) { ax0 = cmd[CMD_THROTTLE].max; } else if (ax0 < cmd[CMD_THROTTLE].min) { ax0 = cmd[CMD_THROTTLE].min; } ax0 = ax0 * cmd[CMD_THROTTLE].pow; car->_accelCmd = pow(fabs(ax0), cmd[CMD_THROTTLE].sens) / (1.0 + cmd[CMD_THROTTLE].spdSens * car->_speed_x / 10.0); if (isnan (car->_accelCmd)) { car->_accelCmd = 0; } /* printf(" axO:%f accelCmd:%f\n", ax0, car->_accelCmd); */ break; case GFCTRL_TYPE_JOY_BUT: car->_accelCmd = joyInfo->levelup[cmd[CMD_THROTTLE].val]; break; case GFCTRL_TYPE_MOUSE_BUT: car->_accelCmd = mouseInfo->button[cmd[CMD_THROTTLE].val]; break; case GFCTRL_TYPE_KEYBOARD: car->_accelCmd = keyInfo[cmd[CMD_THROTTLE].val].state; break; case GFCTRL_TYPE_SKEYBOARD: car->_accelCmd = skeyInfo[cmd[CMD_THROTTLE].val].state; break; default: car->_accelCmd = 0; break; } if (s->currentTime > 1.0) { // thanks Christos for the following: gradual accel/brake changes for on/off controls. const tdble inc_rate = 0.2f; if (cmd[CMD_BRAKE].type == GFCTRL_TYPE_JOY_BUT || cmd[CMD_BRAKE].type == GFCTRL_TYPE_MOUSE_BUT || cmd[CMD_BRAKE].type == GFCTRL_TYPE_KEYBOARD || cmd[CMD_BRAKE].type == GFCTRL_TYPE_SKEYBOARD) { tdble d_brake = car->_brakeCmd - HCtx[idx]->pbrake; if (fabs(d_brake) > inc_rate && car->_brakeCmd > HCtx[idx]->pbrake) { car->_brakeCmd = MIN(car->_brakeCmd, HCtx[idx]->pbrake + inc_rate*d_brake/fabs(d_brake)); } HCtx[idx]->pbrake = car->_brakeCmd; } if (cmd[CMD_THROTTLE].type == GFCTRL_TYPE_JOY_BUT || cmd[CMD_THROTTLE].type == GFCTRL_TYPE_MOUSE_BUT || cmd[CMD_THROTTLE].type == GFCTRL_TYPE_KEYBOARD || cmd[CMD_THROTTLE].type == GFCTRL_TYPE_SKEYBOARD) { tdble d_accel = car->_accelCmd - HCtx[idx]->paccel; if (fabs(d_accel) > inc_rate && car->_accelCmd > HCtx[idx]->paccel) { car->_accelCmd = MIN(car->_accelCmd, HCtx[idx]->paccel + inc_rate*d_accel/fabs(d_accel)); } HCtx[idx]->paccel = car->_accelCmd; } } if (HCtx[idx]->AutoReverseEngaged) { /* swap brake and throttle */ brake = car->_brakeCmd; car->_brakeCmd = car->_accelCmd; car->_accelCmd = brake; } if (HCtx[idx]->ParamAbs) { if (fabs(car->_speed_x) > 10.0) { int i; tdble skidAng = atan2(car->_speed_Y, car->_speed_X) - car->_yaw; NORM_PI_PI(skidAng); if (car->_speed_x > 5 && fabs(skidAng) > 0.2) car->_brakeCmd = MIN(car->_brakeCmd, 0.10 + 0.70 * cos(skidAng)); if (fabs(car->_steerCmd) > 0.1) { tdble decel = ((fabs(car->_steerCmd)-0.1) * (1.0 + fabs(car->_steerCmd)) * 0.6); car->_brakeCmd = MIN(car->_brakeCmd, MAX(0.35, 1.0 - decel)); } const tdble abs_slip = 2.5; const tdble abs_range = 5.0; slip = 0; for (i = 0; i < 4; i++) { slip += car->_wheelSpinVel(i) * car->_wheelRadius(i); } slip = car->_speed_x - slip/4.0f; if (slip > abs_slip) car->_brakeCmd = car->_brakeCmd - MIN(car->_brakeCmd*0.8, (slip - abs_slip) / abs_range); } } if (HCtx[idx]->ParamAsr) { tdble trackangle = RtTrackSideTgAngleL(&(car->_trkPos)); tdble angle = trackangle - car->_yaw; NORM_PI_PI(angle); tdble maxaccel = 0.0; if (car->_trkPos.seg->type == TR_STR) maxaccel = MIN(car->_accelCmd, 0.2); else if (car->_trkPos.seg->type == TR_LFT && angle < 0.0) maxaccel = MIN(car->_accelCmd, MIN(0.6, -angle)); else if (car->_trkPos.seg->type == TR_RGT && angle > 0.0) maxaccel = MIN(car->_accelCmd, MIN(0.6, angle)); tdble origaccel = car->_accelCmd; tdble skidAng = atan2(car->_speed_Y, car->_speed_X) - car->_yaw; NORM_PI_PI(skidAng); if (car->_speed_x > 5 && fabs(skidAng) > 0.2) { car->_accelCmd = MIN(car->_accelCmd, 0.15 + 0.70 * cos(skidAng)); car->_accelCmd = MAX(car->_accelCmd, maxaccel); } if (fabs(car->_steerCmd) > 0.1) { tdble decel = ((fabs(car->_steerCmd)-0.1) * (1.0 + fabs(car->_steerCmd)) * 0.8); car->_accelCmd = MIN(car->_accelCmd, MAX(0.35, 1.0 - decel)); } tdble drivespeed = 0.0; switch (HCtx[idx]->drivetrain) { case D4WD: drivespeed = ((car->_wheelSpinVel(FRNT_RGT) + car->_wheelSpinVel(FRNT_LFT)) * car->_wheelRadius(FRNT_LFT) + (car->_wheelSpinVel(REAR_RGT) + car->_wheelSpinVel(REAR_LFT)) * car->_wheelRadius(REAR_LFT)) / 4.0; break; case DFWD: drivespeed = (car->_wheelSpinVel(FRNT_RGT) + car->_wheelSpinVel(FRNT_LFT)) * car->_wheelRadius(FRNT_LFT) / 2.0; break; default: drivespeed = (car->_wheelSpinVel(REAR_RGT) + car->_wheelSpinVel(REAR_LFT)) * car->_wheelRadius(REAR_LFT) / 2.0; break; } tdble slip = drivespeed - fabs(car->_speed_x); if (slip > 2.0) car->_accelCmd = MIN(car->_accelCmd, origaccel - MIN(origaccel-0.1, ((slip - 2.0)/10.0))); } if (speedLimiter) { tdble Dv; if (Vtarget != 0) { Dv = Vtarget - car->_speed_x; if (Dv > 0.0) { car->_accelCmd = MIN(car->_accelCmd, fabs(Dv/6.0)); } else { car->_brakeCmd = MAX(car->_brakeCmd, fabs(Dv/5.0)); car->_accelCmd = 0; } } } #ifndef WIN32 #ifdef TELEMETRY if ((car->_laps > 1) && (car->_laps < 5)) { if (HCtx[idx]->lap == 1) { RtTelemStartMonitoring("Player"); } RtTelemUpdate(car->_curLapTime); } if (car->_laps == 5) { if (HCtx[idx]->lap == 4) { RtTelemShutdown(); } } #endif #endif HCtx[idx]->lap = car->_laps; }
/* return state mode */ static int reRaceRealStart(void) { int i, j; int sw, sh, vw, vh; tRobotItf *robot; tReCarInfo *carInfo; const int BUFSIZE = 1024; char buf[BUFSIZE]; int foundHuman; void *params = ReInfo->params; void *results = ReInfo->results; tSituation *s = ReInfo->s; RmLoadingScreenSetText("Loading Simulation Engine..."); const char* dllname = GfParmGetStr(ReInfo->_reParam, "Modules", "simu", ""); snprintf(buf, BUFSIZE, "%smodules/simu/%s.%s", GetLibDir (), dllname, DLLEXT); if (GfModLoad(0, buf, &ReRaceModList)) return RM_QUIT; ReRaceModList->modInfo->fctInit(ReRaceModList->modInfo->index, &ReInfo->_reSimItf); if (ReInitCars()) { return RM_QUIT; } /* Blind mode or not */ if (ReInfo->_displayMode != RM_DISP_MODE_CONSOLE) { ReInfo->_displayMode = RM_DISP_MODE_NORMAL; ReInfo->_reGameScreen = ReScreenInit(); foundHuman = 0; for (i = 0; i < s->_ncars; i++) { if (s->cars[i]->_driverType == RM_DRV_HUMAN) { foundHuman = 1; break; } } if (!foundHuman) { if (!strcmp(GfParmGetStr(params, ReInfo->_reRaceName, RM_ATTR_DISPMODE, RM_VAL_VISIBLE), RM_VAL_INVISIBLE)) { ReInfo->_displayMode = RM_DISP_MODE_NONE; ReInfo->_reGameScreen = ReResScreenInit(); } } } if (!(ReInfo->s->_raceType == RM_TYPE_QUALIF) || ((int)GfParmGetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_DRIVER, NULL, 1) == 1)) { RmLoadingScreenStart(ReInfo->_reName, "data/img/splash-qrloading.png"); } for (i = 0; i < s->_ncars; i++) { snprintf(buf, BUFSIZE, "Initializing Driver %s...", s->cars[i]->_name); RmLoadingScreenSetText(buf); robot = s->cars[i]->robot; robot->rbNewRace(robot->index, s->cars[i], s); } carInfo = ReInfo->_reCarInfo; ReInfo->_reSimItf.update(s, RCM_MAX_DT_SIMU, -1); for (i = 0; i < s->_ncars; i++) { carInfo[i].prevTrkPos = s->cars[i]->_trkPos; } RmLoadingScreenSetText("Running Prestart..."); for (i = 0; i < s->_ncars; i++) { memset(&(s->cars[i]->ctrl), 0, sizeof(tCarCtrl)); s->cars[i]->ctrl.brakeCmd = 1.0; } for (j = 0; j < ((int)(1.0 / RCM_MAX_DT_SIMU)); j++) { ReInfo->_reSimItf.update(s, RCM_MAX_DT_SIMU, -1); } if (ReInfo->_displayMode == RM_DISP_MODE_NONE) { if (ReInfo->s->_raceType == RM_TYPE_QUALIF) { ReUpdateQualifCurRes(s->cars[0]); } else { snprintf(buf, BUFSIZE, "%s on %s", s->cars[0]->_name, ReInfo->track->name); ReResScreenSetTitle(buf); } } RmLoadingScreenSetText("Ready."); ReInfo->_reTimeMult = 1.0; ReInfo->_reLastTime = -1.0; ReInfo->s->currentTime = -2.0; ReInfo->s->deltaTime = RCM_MAX_DT_SIMU; ReInfo->s->_raceState = RM_RACE_STARTING; if ((ReInfo->_displayMode != RM_DISP_MODE_CONSOLE) && ReInfo->_reGraphicItf.initview != 0) { GfScrGetSize(&sw, &sh, &vw, &vh); ReInfo->_reGraphicItf.initview((sw-vw)/2, (sh-vh)/2, vw, vh, GR_VIEW_STD, ReInfo->_reGameScreen); if (ReInfo->_displayMode == RM_DISP_MODE_NORMAL) { /* RmLoadingScreenSetText("Loading Cars 3D Objects..."); */ stopMenuMusic(); ReInfo->_reGraphicItf.initcars(s); } GfuiScreenActivate(ReInfo->_reGameScreen); } // If the race is adaptive, initialize performance measurement. Uses strategy pattern, pass in the desired performance measurement object. if (taManager->IsActive()) { if (taManager->GetRaceType() == torcsAdaptive::TARaceType::Adaptive) taManager->InitPerfMeasurement(new RaceLineEvaluation(&ReInfo->carList[0], Pathfinder::K1999, ReInfo->track, ReInfo->s)); } return RM_SYNC | RM_NEXT_STEP; }