// Handle input events void TrackChooserView::handleEvent(sf::Event event) { bool pressed = (event.type == sf::Event::KeyPressed); bool released = (event.type == sf::Event::KeyReleased); // Select the next track if (pressed && event.key.code == sf::Keyboard::Right) { setTrack(trackNumber + 1); // Move the arrow layoutChildviews(); arrowRight.move(6,0); } else if (released && event.key.code == sf::Keyboard::Right) { // Reset the arrow layoutChildviews(); } // Select the previous track if (pressed && event.key.code == sf::Keyboard::Left) { setTrack(trackNumber - 1); // Move the arrow layoutChildviews(); arrowLeft.move(-6, 0); } else if (released && event.key.code == sf::Keyboard::Left) { // Reset the arrow layoutChildviews(); } }
bool MidiParser_SH::loadMusic(byte *musData, uint32 musDataSize) { Common::StackLock lock(_mutex); debugC(kDebugLevelMusic, "Music: loadMusic()"); unloadMusic(); _musData = musData; _musDataSize = musDataSize; byte *headerPtr = _musData + 12; // skip over the already checked SPACE header byte *pos = headerPtr; uint16 headerSize = READ_LE_UINT16(headerPtr); assert(headerSize == 0x7F); // Security check // Skip over header pos += headerSize; _lastEvent = 0; _trackEnd = _musData + _musDataSize; _numTracks = 1; _tracks[0] = pos; _ppqn = 1; setTempo(16667); setTrack(0); return true; }
void faceThread::run() { static int eyeFlag = 0; static float scale = 0.5; while(true) { if(runFlag) { switch (MODE) { case SLEEP_MODE: setSleep(); break; case SMILE_MODE: setSmile(); break; case ANGER_MODE: setAnger(); break; case TRACK_MODE: setTrack(); scale = 1; break; default: break; } if( eyeFlag == 0 ) { scale -= CHANGE_SPEED; if(scale <= LOWBOUND) { eyeFlag = 1; } } else { scale += CHANGE_SPEED; if(scale >= UPBOUND) { eyeFlag = 0; if(UPBOUND > 0.8) { scale = 0.8; } else { scale = UPBOUND; } } } facesketch->reset(); facesketch->setEyeScale(scale); facesketch->sketchWholeFace(); setRunFlag(false); emit resultReady(); } } }
TagDialog::TagDialog( const TrackInfo& track, QWidget *parent ) : QDialog( parent, Qt::Dialog ) { ui.setupUi( this ); ui.tagEdit->setFocus(); ui.tagEdit->installEventFilter( this ); LastFmUserSettings& user = The::currentUser(); ui.tagTypeBox->setCurrentIndex( user.lastTagType( 1 ) ); ui.personalTagsList->setSortOrder( (Tags::SortOrder) user.personalTagsListSortOrder() ); ui.publicTagsList->setSortOrder( (Tags::SortOrder) user.publicTagsListSortOrder() ); QRegExp rx( "[a-zA-Z0-9\\-:,' ]{1,255}" ); ui.tagEdit->setValidator( new QRegExpValidator( rx, this ) ); setTrack( track ); ui.buttonBox->button( QDialogButtonBox::Ok )->setText( tr("Tag") ); ui.buttonBox->button( QDialogButtonBox::Ok )->setEnabled( false ); connect( ui.tagTypeBox, SIGNAL( currentIndexChanged( int ) ), SLOT( onTagTypeChanged( int ) ) ); connect( ui.personalTagsList, SIGNAL( itemActivated( QTreeWidgetItem*, int ) ), SLOT( onTagActivated( QTreeWidgetItem* ) ) ); connect( ui.publicTagsList, SIGNAL( itemActivated( QTreeWidgetItem*, int ) ), SLOT( onTagActivated( QTreeWidgetItem* ) ) ); connect( this, SIGNAL( accepted() ), SLOT( onAccepted() ) ); connect( ui.buttonBox, SIGNAL( accepted() ), SLOT( accept() ) ); connect( ui.buttonBox, SIGNAL( rejected() ), SLOT( reject() ) ); //needs to stay textEdited() not textChanged() or the completion breaks the filtering connect( ui.tagEdit, SIGNAL( textEdited( QString ) ), SLOT( onTagEditChanged() ) ); ////// requestFactory<UserTagsRequest>()->start(); }
TrackChooserView::TrackChooserView(const Rect& frame) : View(frame) { // Get a list of all tracks Rac0r::TrackFileManager fileManager; tracks = fileManager.getTrackList(); // Load textures arrowDownTexture.loadFromFile(resourcePath() + "arrowDown.png"); arrowUpTexture.loadFromFile(resourcePath() + "arrowUp.png"); // Initialize arrows and the track image arrowRight.setTexture(arrowUpTexture); arrowRight.rotate(90); addChild(arrowRight); arrowLeft.setTexture(arrowDownTexture); arrowLeft.rotate(90); addChild(arrowLeft); addChild(track); // Select the first track if (tracks.size() > 0) { setTrack(0); } // Calculate the initial layout. However, it will be recalculated whenever View's setSize() is called. layoutChildviews(); }
/** \brief Function to start the race with only ghost kart(s) and watch. * \param trackIdent Internal name of the track to race on * \param num_laps Number of laps to race, or -1 if number of laps is * not relevant in current mode */ void RaceManager::startWatchingReplay(const std::string &track_ident, const int num_laps) { assert(m_watching_replay && m_has_ghost_karts && !m_is_recording_race); StateManager::get()->enterGameState(); setTrack(track_ident); setNumLaps(num_laps); setMajorMode(RaceManager::MAJOR_MODE_SINGLE); setCoinTarget(0); m_num_karts = ReplayPlay::get()->getNumGhostKart(); m_kart_status.clear(); Log::verbose("RaceManager", "%u ghost kart(s) for watching replay only\n", (unsigned int)m_num_karts); int init_gp_rank = 0; for(int i = 0; i < m_num_karts; i++) { m_kart_status.push_back(KartStatus(ReplayPlay::get()->getGhostKartName(i), i, -1, -1, init_gp_rank, KT_GHOST, PLAYER_DIFFICULTY_NORMAL)); init_gp_rank ++; } m_track_number = 0; startNextRace(); } // startSingleRace
bool SLine::readProperties(const QDomElement& e) { if (Element::readProperties(e)) return true; const QString& tag(e.tagName()); const QString& val(e.text()); int i = val.toInt(); if (tag == "tick2") // obsolete __setTick2(score()->fileDivision(i)); else if (tag == "tick") // obsolete __setTick1(score()->fileDivision(i)); else if (tag == "Segment") { LineSegment* ls = createLineSegment(); ls->read(e); add(ls); } else if (tag == "track") setTrack(i); else if (tag == "length") setLen(val.toDouble()); else if (tag == "diagonal") setDiagonal(i); else if (tag == "anchor") setAnchor(Anchor(i)); else return false; return true; }
void Entity::setFrameSpline(const PhysicsFrameSpline& spline) { shared_ptr<SplineTrack> c = dynamic_pointer_cast<SplineTrack>(m_track); if (isNull(c)) { c = shared_ptr<SplineTrack>(new SplineTrack()); setTrack(shared_ptr<Track>(c)); } c->setSpline(spline); }
RTCRtpSender::RTCRtpSender(RefPtr<MediaStreamTrack>&& track, const String& trackKind, Vector<String>&& mediaStreamIds, RTCRtpSenderClient& client) : RTCRtpSenderReceiverBase() , m_trackKind(trackKind) , m_mediaStreamIds(WTFMove(mediaStreamIds)) , m_client(&client) { setTrack(WTFMove(track)); }
void MagicMNMPage::setToCurrentTrack() { uint8_t currentTrack = MNM.getCurrentTrack(); if (currentTrack == 255) { GUI.flash_strings_fill("MNM TIMEOUT", ""); } else { show(); setTrack(currentTrack); } }
void InfoWidget::Implementation::showTrackInformation(const Jerboa::TrackData& track) { if(track.isValid()) { setTrack(track); } else { clear(); } }
bool MidiParser_S1D::loadMusic(byte *data, uint32 size) { unloadMusic(); if (!size) return false; // The original actually just ignores the first two bytes. byte *pos = data; if (*pos == 0xFC) { // SysEx found right at the start // this seems to happen since Elvira 2, we ignore it // 3rd byte after the SysEx seems to be saved into a global // We expect at least 4 bytes in total if (size < 4) return false; byte skipOffset = pos[2]; // get second byte after the SysEx // pos[1] seems to have been ignored // pos[3] is saved into a global inside the original interpreters // Waxworks + Simon 1 demo typical header is: // 0xFC 0x29 0x07 0x01 [0x00/0x01] // Elvira 2 typical header is: // 0xFC 0x04 0x06 0x06 if (skipOffset >= 6) { // should be at least 6, so that we skip over the 2 size bytes and the // smallest SysEx possible skipOffset -= 2; // 2 size bytes were already read by previous code outside of this method if (size <= skipOffset) // Skip to the end of file? -> something is not correct return false; // Do skip over the bytes pos += skipOffset; } else { warning("MidiParser_S1D: unexpected skip offset in music file"); } } // And now we're at the actual data. Only one track. _numTracks = 1; _data = pos; _tracks[0] = pos; // Note that we assume the original data passed in // will persist beyond this call, i.e. we do NOT // copy the data to our own buffer. Take warning.... resetTracking(); setTempo(666667); setTrack(0); return true; }
void InputState::update(Element* e) { if (e == 0) return; if (e && e->type() == Element::Type::CHORD) e = static_cast<Chord*>(e)->upNote(); setDrumNote(-1); if (e->type() == Element::Type::NOTE) { Note* note = static_cast<Note*>(e); Chord* chord = note->chord(); setDuration(chord->durationType()); setRest(false); setTrack(note->track()); setNoteType(note->noteType()); setBeamMode(chord->beamMode()); } else if (e->type() == Element::Type::REST) { Rest* rest = static_cast<Rest*>(e); if (rest->durationType().type() == TDuration::DurationType::V_MEASURE) setDuration(TDuration::DurationType::V_QUARTER); else setDuration(rest->durationType()); setRest(true); setTrack(rest->track()); setBeamMode(rest->beamMode()); setNoteType(NoteType::NORMAL); } if (e->type() == Element::Type::NOTE || e->type() == Element::Type::REST) { const Instrument* instr = e->part()->instrument(); if (instr->useDrumset()) { if (e->type() == Element::Type::NOTE) setDrumNote(static_cast<Note*>(e)->pitch()); else setDrumNote(-1); } } }
void Slur::read(const QDomElement& de) { setTrack(0); // set staff setId(de.attribute("id").toInt()); for (QDomElement e = de.firstChildElement(); !e.isNull(); e = e.nextSiblingElement()) { const QString& tag(e.tagName()); const QString& val(e.text()); // if (tag == "tick2") // _tick2 = score()->fileDivision(i); if (tag == "track2") _track2 = val.toInt(); // else if (tag == "startTick") // obsolete // ; // setTick(i); // else if (tag == "endTick") // obsolete // setTick2(val.toInt()); else if (tag == "startTrack") // obsolete setTrack(val.toInt()); else if (tag == "endTrack") // obsolete setTrack2(val.toInt()); else if (!SlurTie::readProperties(e)) domError(e); } }
ERROR_CODES M35_Floppy::read (uint16_t sector, uint16_t addr, unsigned& cycles) { // From 0 to max if (sector >= SECTORS_PER_TRACK*tracks || isSectorBad (sector)) return ERROR_CODES::BAD_SECTOR; cycles = setTrack(sector / SECTORS_PER_TRACK); cycles += READ_CYCLES_PER_SECTOR; cursor = addr; count = 0; reading = true; last_sector = sector; return ERROR_CODES::NONE; }
bool CCScrollBar::initWithTrackAndThumb(CCScale9Sprite* track, CCScale9Sprite* thumb) { if(!CCLayer::init()) { return false; } // anchor ignoreAnchorPointForPosition(false); // save track and thumb setTrack(track); setThumb(thumb); // update scheduleUpdate(); return true; }
/** \brief Higher-level method to start a GP without having to care about * the exact startup sequence. * \param trackIdent Internal name of the track to race on * \param num_laps Number of laps to race, or -1 if number of laps is * not relevant in current mode */ void RaceManager::startSingleRace(const std::string &track_ident, const int num_laps, bool from_overworld) { StateManager::get()->enterGameState(); setTrack(track_ident.c_str()); if (num_laps != -1) setNumLaps( num_laps ); setMajorMode(RaceManager::MAJOR_MODE_SINGLE); setCoinTarget( 0 ); // Might still be set from a previous challenge if (!NetworkWorld::getInstance<NetworkWorld>()->isRunning()) // if not in a network world race_manager->setupPlayerKartInfo(); // do this setup player kart startNew(from_overworld); }
/** 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; setReverseTrack(false); setTrack("jungle"); m_default_ai_list.clear(); setNumLocalPlayers(0); } // RaceManager
TrackWidget::TrackWidget( Track& track, QWidget *parent ) :QPushButton(parent), ui( new Ui::TrackWidget ), m_nowPlaying( false ), m_triedFetchAlbumArt( false ) { ui->setupUi( this ); m_spinner = new QLabel( this ); m_spinner->setAlignment( Qt::AlignHCenter | Qt::AlignVCenter ); m_spinner->hide(); m_movie = new QMovie( ":/icon_eq.gif", "GIF", this ); m_movie->setCacheMode( QMovie::CacheAll ); ui->equaliser->setMovie( m_movie ); ui->buttonLayout->setAlignment( ui->love, Qt::AlignTop ); ui->buttonLayout->setAlignment( ui->tag, Qt::AlignTop ); ui->buttonLayout->setAlignment( ui->share, Qt::AlignTop ); ui->buttonLayout->setAlignment( ui->buy, Qt::AlignTop ); ui->trackTitleLayout->setAlignment( ui->asterisk, Qt::AlignTop ); ui->albumArt->setAttribute( Qt::WA_LayoutUsesWidgetRect ); ui->love->setAttribute( Qt::WA_LayoutUsesWidgetRect ); ui->tag->setAttribute( Qt::WA_LayoutUsesWidgetRect ); ui->share->setAttribute( Qt::WA_LayoutUsesWidgetRect ); ui->buy->setAttribute( Qt::WA_LayoutUsesWidgetRect ); setAttribute( Qt::WA_MacNoClickThrough ); ui->albumArt->setAttribute( Qt::WA_MacNoClickThrough ); ui->love->setAttribute( Qt::WA_MacNoClickThrough ); ui->tag->setAttribute( Qt::WA_MacNoClickThrough ); ui->share->setAttribute( Qt::WA_MacNoClickThrough ); ui->buy->setAttribute( Qt::WA_MacNoClickThrough ); connect( ui->love, SIGNAL(clicked(bool)), SLOT(onLoveClicked(bool))); connect( ui->tag, SIGNAL(clicked()), SLOT(onTagClicked())); connect( ui->share, SIGNAL(clicked()), SLOT(onShareClicked())); connect( ui->buy, SIGNAL(clicked()), SLOT(onBuyClicked())); connect( this, SIGNAL(clicked()), SLOT(onClicked()) ); setTrack( track ); }
ERROR_CODES M35_Floppy::write (uint16_t sector, uint16_t addr, unsigned& cycles) { // From 0 to max if (sector >= SECTORS_PER_TRACK*tracks || isSectorBad (sector)) return ERROR_CODES::BAD_SECTOR; if (wp_flag) return ERROR_CODES::PROTECTED; cycles = setTrack(sector / SECTORS_PER_TRACK); cycles += WRITE_CYCLES_PER_SECTOR; cursor = addr; count = 0; reading = false; last_sector = sector; return ERROR_CODES::NONE; }
void GraffitiTab::save () { const auto& modified = FilesModel_->GetModified (); if (modified.isEmpty ()) return; if (QMessageBox::question (this, "LMP Graffiti", tr ("Do you really want to accept changes to %n file(s)?", 0, modified.size ()), QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return; ITagResolver *resolver = LMPProxy_->GetTagResolver (); auto toTLStr = [] (const QString& str) { return TagLib::String (str.toUtf8 ().constData (), TagLib::String::UTF8); }; for (const auto& pair : modified) { const auto& newInfo = pair.first; QMutexLocker locker (&resolver->GetMutex ()); auto file = resolver->GetFileRef (newInfo.LocalPath_); auto tag = file.tag (); tag->setArtist (toTLStr (newInfo.Artist_)); tag->setAlbum (toTLStr (newInfo.Album_)); tag->setTitle (toTLStr (newInfo.Title_)); tag->setYear (newInfo.Year_); tag->setGenre (toTLStr (newInfo.Genres_.join (" / "))); tag->setTrack (newInfo.TrackNumber_); if (!file.save ()) qWarning () << Q_FUNC_INFO << "unable to save file" << newInfo.LocalPath_; } handleRereadFiles (); }
/** \brief Higher-level method to start a GP without having to care about * the exact startup sequence. * \param trackIdent Internal name of the track to race on * \param num_laps Number of laps to race, or -1 if number of laps is * not relevant in current mode */ void RaceManager::startSingleRace(const std::string &track_ident, const int num_laps, bool from_overworld) { assert(!m_watching_replay); StateManager::get()->enterGameState(); setTrack(track_ident); if (num_laps != -1) setNumLaps( num_laps ); setMajorMode(RaceManager::MAJOR_MODE_SINGLE); setCoinTarget( 0 ); // Might still be set from a previous challenge // if not in a network world, setup player karts if (!RaceEventManager::getInstance<RaceEventManager>()->isRunning()) race_manager->setupPlayerKartInfo(); // do this setup player kart startNew(from_overworld); } // startSingleRace
bool MidiParser_SCI::loadMusic(SoundResource::Track *track, MusicEntry *psnd, int channelFilterMask, SciVersion soundVersion) { unloadMusic(); _track = track; _pSnd = psnd; _soundVersion = soundVersion; for (int i = 0; i < 16; i++) { _channelUsed[i] = false; _channelMuted[i] = false; _channelVolume[i] = 127; if (_soundVersion <= SCI_VERSION_0_LATE) _channelRemap[i] = i; else _channelRemap[i] = -1; } // FIXME: SSCI does not always start playing a track at the first byte. // By default it skips 10 (or 13?) bytes containing prio/voices, patch, // volume, pan commands in fixed locations, and possibly a signal // in channel 15. We should initialize state tracking to those values // so that they automatically get set up properly when the channels get // mapped. See also the related FIXME in MidiParser_SCI::processEvent. if (channelFilterMask) { // SCI0 only has 1 data stream, but we need to filter out channels depending on music hardware selection midiFilterChannels(channelFilterMask); } else { midiMixChannels(); } _numTracks = 1; _tracks[0] = _mixedData; if (_pSnd) setTrack(0); _loopTick = 0; return true; }
bool MidiParser_RO::loadMusic (byte *data, uint32 size) { unloadMusic(); byte *pos = data; if (memcmp (pos, "RO", 2)) { error("'RO' header expected but found '%c%c' instead", pos[0], pos[1]); return false; } _num_tracks = 1; _ppqn = 120; _tracks[0] = pos + 2; _markerCount = _lastMarkerCount = 0; // Note that we assume the original data passed in // will persist beyond this call, i.e. we do NOT // copy the data to our own buffer. Take warning.... resetTracking(); setTempo (500000); setTrack (0); return true; }
void PL_OggFile::setValue(dataColumn x,QVariant& value,bool replace) { if(!linked) link(); oggtagger->setValue(x,value,replace); bool a; switch(x) { case TITLE: setTitle(value.toString()); break; case ARTIST: setArtist(value.toString()); break; case ALBUM: setAlbumtitle(value.toString()); break; case GENRE: setGenre(value.toInt(&a)); break; case COMMENT: setComment(value.toString()); break; case YEAR: setYear(value.toInt(&a)); break; case TRACK: setTrack(value.toInt(&a)); break; case TIME: case BITRATE: case PICTURE: break; } }
bool MidiParser_S1D::loadMusic(byte *data, uint32 size) { unloadMusic(); byte *pos = data; if (*(pos++) != 0xFC) debug(1, "Expected 0xFC header but found 0x%02X instead", (int) *pos); // The next 3 bytes MIGHT be tempo, but we skip them and use the default. // setTempo (*(pos++) | (*(pos++) << 8) | (*(pos++) << 16)); pos += 3; // And now we're at the actual data. Only one track. _num_tracks = 1; _data = pos; _tracks[0] = pos; // Note that we assume the original data passed in // will persist beyond this call, i.e. we do NOT // copy the data to our own buffer. Take warning.... resetTracking(); setTempo(666667); setTrack(0); return true; }
SLine::SLine(Score* s) : Spanner(s) { _diagonal = false; setTrack(0); }
bool MidiParser_SMF::loadMusic(byte *data, uint32 size) { uint32 len; byte midi_type; uint32 total_size; bool isGMF; unloadMusic(); byte *pos = data; isGMF = false; if (!memcmp(pos, "RIFF", 4)) { // Skip the outer RIFF header. pos += 8; } if (!memcmp(pos, "MThd", 4)) { // SMF with MTHd information. pos += 4; len = read4high(pos); if (len != 6) { warning("MThd length 6 expected but found %d", (int)len); return false; } // Verify that this MIDI either is a Type 2 // or has only 1 track. We do not support // multitrack Type 1 files. _num_tracks = pos[2] << 8 | pos[3]; midi_type = pos[1]; if (midi_type > 2 /*|| (midi_type < 2 && _num_tracks > 1)*/) { warning("No support for a Type %d MIDI with %d tracks", (int)midi_type, (int)_num_tracks); return false; } _ppqn = pos[4] << 8 | pos[5]; pos += len; } else if (!memcmp(pos, "GMF\x1", 4)) { // Older GMD/MUS file with no header info. // Assume 1 track, 192 PPQN, and no MTrk headers. isGMF = true; midi_type = 0; _num_tracks = 1; _ppqn = 192; pos += 7; // 'GMD\x1' + 3 bytes of useless (translate: unknown) information } else { warning("Expected MThd or GMD header but found '%c%c%c%c' instead", pos[0], pos[1], pos[2], pos[3]); return false; } // Now we identify and store the location for each track. if (_num_tracks > ARRAYSIZE(_tracks)) { warning("Can only handle %d tracks but was handed %d", (int)ARRAYSIZE(_tracks), (int)_num_tracks); return false; } total_size = 0; int tracks_read = 0; while (tracks_read < _num_tracks) { if (memcmp(pos, "MTrk", 4) && !isGMF) { warning("Position: %p ('%c')", pos, *pos); warning("Hit invalid block '%c%c%c%c' while scanning for track locations", pos[0], pos[1], pos[2], pos[3]); return false; } // If needed, skip the MTrk and length bytes _tracks[tracks_read] = pos + (isGMF ? 0 : 8); if (!isGMF) { pos += 4; len = read4high(pos); total_size += len; pos += len; } else { // An SMF End of Track meta event must be placed // at the end of the stream. data[size++] = 0xFF; data[size++] = 0x2F; data[size++] = 0x00; data[size++] = 0x00; } ++tracks_read; } // If this is a Type 1 MIDI, we need to now compress // our tracks down into a single Type 0 track. free(_buffer); _buffer = 0; if (midi_type == 1) { // FIXME: Doubled the buffer size to prevent crashes with the // Inherit the Earth MIDIs. Jamieson630 said something about a // better fix, but this will have to do in the meantime. _buffer = (byte *)malloc(size * 2); compressToType0(); _num_tracks = 1; _tracks[0] = _buffer; } // Note that we assume the original data passed in // will persist beyond this call, i.e. we do NOT // copy the data to our own buffer. Take warning.... resetTracking(); setTempo(500000); setTrack(0); return true; }
Ref<RTCRtpSender> RTCRtpSender::create(PeerConnectionBackend& connection, Ref<MediaStreamTrack>&& track, Vector<String>&& mediaStreamIds, std::unique_ptr<RTCRtpSenderBackend>&& backend) { auto sender = adoptRef(*new RTCRtpSender(connection, String(track->kind()), WTFMove(mediaStreamIds), WTFMove(backend))); sender->setTrack(WTFMove(track)); return sender; }
void parseCommand(char *command, int *trainSpeeds, int *train) { char *argv[MAX_ARGS]; int argc = formatArgs(command, argv); if(strcmp(argv[0], "tr") == 0) { if(numArgs(argc, argv) != 2) { printColored(RED, BLACK, "Error: command tr expects 2 arguments\r"); }else{ int trainNumber = strToInt(getArgument(argc, argv, 0)); int trainSpeed = strToInt(getArgument(argc, argv, 1)); if(trainNumber == -1 || trainNumber < 1 || trainNumber > 80) { printColored(RED, BLACK, "Error: train number must be a number between 1 and 80\r"); }else if(trainSpeed == -1 || trainSpeed < 0 || trainSpeed > 14) { printColored(RED, BLACK, "Error: train speed must be a number between 0 and 14\r"); }else { Putc2(1, (char)trainSpeed, (char)trainNumber); trainSpeeds[trainNumber] = trainSpeed; } } }else if(strcmp(argv[0], "rv") == 0) { if(numArgs(argc, argv) != 1) { printColored(RED, BLACK, "Error: command rv expects an argument\r"); }else{ int trainNumber = strToInt(getArgument(argc, argv, 0)); if(trainNumber == -1 || trainNumber < 1 || trainNumber > 80) { printColored(RED, BLACK, "Error: train number must be a number between 1 and 80\r"); }else{ Putc2(1, (char)0, (char)trainNumber); int reverseTask = Create(1, reverser); int reply; struct trainInfo info; info.speed = trainSpeeds[trainNumber]; info.number = trainNumber; Send(reverseTask, (char *)&info, sizeof(struct trainInfo), (char *)&reply, sizeof(int)); } } }else if(strcmp(argv[0], "sw") == 0) { if(numArgs(argc, argv) != 2) { printColored(RED, BLACK, "Error: command sw expects two arguments\r"); }else{ int switchNumber = strToInt(getArgument(argc, argv, 0)); if(strcmp(getArgument(argc, argv, 1), "S") == 0) { setSwitchState(switchNumber, 'S'); }else if(strcmp(getArgument(argc, argv, 1), "C") == 0) { setSwitchState(switchNumber, 'C'); }else{ printColored(RED, BLACK, "Error: switch direction must be 'S' or 'C'\r"); } } }else if(strcmp(argv[0], "q") == 0) { outputEscape("[2J"); moveCursor(1,1); Shutdown(); }else if(strcmp(argv[0], "setTrack") == 0) { if(numArgs(argc, argv) != 1) { printColored(RED, BLACK, "Error: command setTrack expects an argument\r"); }else{ if(strcmp(getArgument(argc, argv, 0), "A") == 0) { setTrack(TRACKA); }else if(strcmp(getArgument(argc, argv, 0), "B") == 0) { setTrack(TRACKB); }else{ printColored(RED, BLACK, "Error: track must be A or B\r"); } } }else if(strcmp(argv[0], "move") == 0) { if(numArgs(argc, argv) != 3) { printColored(RED, BLACK, "Error: command move expects two arguments\r"); }else{ struct TrainMessage msg; int trainNum = strToInt(getArgument(argc, argv, 0)); msg.type = TRAINGOTO; strcpy(msg.dest, getArgument(argc, argv, 1)); msg.doReverse = getFlag(argc, argv, "r"); msg.speed = strToInt(getArgument(argc, argv, 2)); if(train[trainNum] == -1) { printColored(RED, BLACK, "Error: train %d has not been initialized\r", trainNum); }else{ int reply; Send(train[trainNum], (char *)&msg, sizeof(struct TrainMessage), (char *)&reply, sizeof(int)); } } }else if(strcmp(argv[0], "randomizeSwitches") == 0) { int i; seed(Time()); for(i=1; i<19; i++) { int dir = random() % 2; if(dir == 0) { setSwitchState(i, 'S'); }else{ setSwitchState(i, 'C'); } } for(i=153; i<157; i++) { int dir = random() % 2; if(dir == 0) { setSwitchState(i, 'S'); }else{ setSwitchState(i, 'C'); } } }else if(strcmp(argv[0], "init") == 0) { if(numArgs(argc, argv) != 1) { printColored(RED, BLACK, "Error: command init expects an argument\r"); }else{ struct TrainMessage msg; int trainNum = strToInt(getArgument(argc, argv, 0)); int reply; if(train[trainNum] == -1) { train[trainNum] = Create(2, trainTask); Send(train[trainNum], (char *)&trainNum, sizeof(int), (char *)&reply, sizeof(int)); } msg.type = TRAININIT; Send(train[trainNum], (char *)&msg, sizeof(struct TrainMessage), (char *)&reply, sizeof(int)); } }else if(strcmp(argv[0], "d") == 0) { track_node track[TRACK_MAX]; initTrack(track); int trainNum = 45; int trainSpeed = strToInt(getArgument(argc, argv, 0)); Putc2(1, (char)trainSpeed, (char)trainNum); int sensor, lastSensor = waitOnAnySensor(), lastTime = Time(), time; int v = 0; while(true) { sensor = waitOnAnySensor(); time = Time(); if(sensor == 71) break; int timeDelta = (time - lastTime); int distance = BFS(lastSensor, sensor, track, NULL, false); int newVelocity = (500*distance)/timeDelta; v *= 95; v += newVelocity; v /= 100; lastTime = time; lastSensor = sensor; printAt(9, 1, "Velocity: %dmm/s\r", v); } Putc2(1, (char)0, (char)trainNum); }else if(strcmp(argv[0], "a") == 0) { track_node track[TRACK_MAX]; initTrack(track); int trainNum = 45; int trainSpeed = strToInt(getArgument(argc, argv, 2)); int source = 0, dest = 0; int velocity[15]; initVelocities(trainNum, velocity); while(source < TRACK_MAX && strcmp(track[source].name, getArgument(argc, argv, 0)) != 0) source++; while(dest < TRACK_MAX && strcmp(track[dest].name, getArgument(argc, argv, 1)) != 0) dest++; int distance = BFS(source, dest, track, NULL, false); Putc2(1, (char)trainSpeed, (char)trainNum); int t0 = Time(); printf("Time 0: %d\r", t0); waitOnSensor(dest); int t2 = Time(); Putc2(1, (char)0, (char)trainNum); printf("Time 2: %d\r", t2); int t1 = -(200*distance)/velocity[trainSpeed]; t1 -= t0; t1 += 2*t2; printf("Time 1: %d\r", t1); printf("Accelerating to speed %d takes %d ticks\r", trainSpeed, t1-t0); }else if(strcmp(argv[0], "clear") == 0) { moveCursor(13, 1); outputEscape("[J"); }else if(strcmp(argv[0], "configureVelocities") == 0) { struct TrainMessage msg; msg.type = TRAINCONFIGVELOCITY; if(argc != 2) { printColored(RED, BLACK, "Command configureVelocities expects an argument\r"); }else{ int trainNum = strToInt(getArgument(argc, argv, 0)); int reply; if(train[trainNum] == -1) { train[trainNum] = Create(2, trainTask); Send(train[trainNum], (char *)&trainNum, sizeof(int), (char *)&reply, sizeof(int)); } Send(train[trainNum], (char *)&msg, sizeof(struct TrainMessage), (char *)&reply, sizeof(int)); } }else{ printColored(RED, BLACK, "Unrecognized command: \"%s\"\r", command); } }