/** Constructs the race manager. */ RaceManager::RaceManager() { // Several code depends on this, e.g. kart_properties assert(DIFFICULTY_FIRST == 0); m_num_karts = UserConfigParams::m_num_karts; m_difficulty = DIFFICULTY_HARD; m_major_mode = MAJOR_MODE_SINGLE; m_minor_mode = MINOR_MODE_NORMAL_RACE; m_ai_superpower = SUPERPOWER_NONE; m_track_number = 0; m_coin_target = 0; m_started_from_overworld = false; m_have_kart_last_position_on_overworld = false; setMaxGoal(0); setTimeTarget(0.0f); setReverseTrack(false); setRecordRace(false); setRaceGhostKarts(false); setWatchingReplay(false); setTrack("jungle"); m_default_ai_list.clear(); setNumPlayers(0); } // RaceManager
/** Start a timer. Specify if you'd like the timer to repeat and, if so, the interval at which you'd like it to repeat. If you have set up a handler with setHandler() then your handler function will get called at the specified interval. If the timer is already running, this will reset it. @param millis The number of milliseconds @param repeat Whether or not to repeat - true by default. */ int Timer::start( int millis, bool repeat ) { timeCurrent = 0; timeInitial = millis * TIMER_CYCLES_PER_MS; this->repeat = repeat; next = NULL; // this could be a lot smarter - for example, modifying the current period? if ( !manager.servicing ) Task::enterCritical(); if ( !manager.running ) { // Timer_SetActive( true ); setTimeTarget( this->timeInitial ); enable(); } // Calculate how long remaining int target = getTimeTarget(); int timeCurrent = getTime(); int remaining = target - timeCurrent; // Get the entry ready to roll this->timeCurrent = this->timeInitial; // Add entry Timer* first = manager.first; manager.first = this; this->next = first; // Are we actually servicing an interupt right now? if ( !manager.servicing ) { // No - so does the time requested by this new timer make the time need to come earlier? if ( this->timeCurrent < ( remaining - TIMER_MARGIN ) ) { // Damn it! Reschedule the next callback setTimeTarget( target - ( remaining - this->timeCurrent )); } else { // pretend that the existing time has been with us for the whole slice so that when the // IRQ happens it credits the correct (reduced) time. this->timeCurrent += timeCurrent; } } else { // Yep... we're servicing something right now // Make sure the previous pointer is OK. This comes up if we were servicing the first item // and it subsequently wants to delete itself, it would need to alter the next pointer of the // the new head... err... kind of a pain, this if ( manager.previous == NULL ) manager.previous = this; // Need to make sure that if this new time is the lowest yet, that the IRQ routine // knows that. Since we added this entry onto the beginning of the list, the IRQ // won't look at it again if ( manager.nextTime == -1 || manager.nextTime > this->timeCurrent ) manager.nextTime = this->timeCurrent; } if ( !manager.servicing ) Task::exitCritical(); return CONTROLLER_OK; }