static void IdleMouseInit(void) { /* Get the center mouse position */ memset(&mouseInfo, 0, sizeof(mouseInfo)); GfctrlMouseGetCurrent(&mouseInfo); GfctrlMouseInitCenter(); glutIdleFunc(Idle2); }
static void IdleMouseInit(void) { /* Get the center mouse position */ memset(&MouseInfo, 0, sizeof(MouseInfo)); GfctrlMouseGetCurrentState(&MouseInfo); GfctrlMouseInitCenter(); GfuiApp().eventLoop().setRecomputeCB(Idle2); }
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; }