#!/usr/bin/perl -w use strict; use utf8; use Getopt::Std; use Gtk2 '-init'; use Glib qw(TRUE FALSE); use Time::HiRes qw(time usleep); use SCX::GUI; use SCX::Track; use SCX::Reader; use SCX::LogReader; use SCX::RaceParser; my %opt; if (!getopts('b:e:ft:l:', \%opt)) { usage(); } if (($opt{t} && $opt{l}) || (!$opt{l} && ($opt{b} || $opt{e} || $opt{f}))) { usage(); } my $gui = SCX::GUI->new({ img_height => 70 }); my $track = SCX::Track->new({ gui => $gui, no_semaphore => $opt{f} }); my $logfile = 'log'; my $parser = SCX::RaceParser->new({ track => $track, logfile => $opt{l} ? undef : $logfile, }); my ($log_reader, $tty_reader); if ($opt{l}) { # Log file replay mode $log_reader = SCX::LogReader->new({ filename => $opt{l}, begin_time => $opt{b}, end_time => $opt{e}, }); } else { my $tty = $opt{t} || '/dev/ttyUSB0'; $tty_reader = eval { SCX::Reader->new({ filename => $tty, parser => $parser, }); }; if ($@) { if ($opt{t}) { exit 1; } print STDERR "Demo mode only: $@"; } } $track->car(0)->set_model('F1 Ferrari'); $track->car(1)->set_model('F1 McLaren'); #$track->car(2)->set_model('F1 Williams'); $track->car(2)->set_model('Citroen Xsara'); $track->car(3)->set_model('Chevrolet Corvette gelb'); $track->car(4)->set_model('Ferrari 360 Red Bull'); $track->car(5)->set_model('Ferrari 360 Cric Crac'); $track->car(0)->set_driver('Ferrari'); $track->car(1)->set_driver('McLaren'); $track->car(2)->set_driver('Xsara'); if ($tty_reader) { Glib::IO->add_watch(fileno($tty_reader->fh), 'in', \&scx_read, $tty_reader); $track->{sound}->unmute(); } elsif ($log_reader) { Glib::Idle->add(\&log_read_start, [ $log_reader, $parser, $opt{f} ]); } else { # Just display some random values $gui->rounds('5/13'); $gui->time('53.4'); $gui->best_lap('12.3'); my $now = time; $track->{race_running_since} = $now; $track->{race_running} = 1; $track->finish_line($now + 0.5, 1, 2); $track->finish_line($now + 0.7, 1, 1); $track->finish_line($now + 4.9, 1, 1); $track->finish_line($now + 5.3, 1, 2); $track->finish_line($now + 7.2, 1, 1); $track->finish_line($now + 8.1, 0, 2); # $track->car(0)->set_lap(13); # $track->car(1)->set_lap(11); # $track->car(2)->set_lap(10); # $track->car(3)->set_lap(undef); # $track->car(4)->set_lap(undef); # $track->car(5)->set_lap(undef); $track->car(0)->set_laptime(9.12322); $track->car(1)->set_laptime(15.313); $track->car(2)->set_laptime(5.989); $track->car(0)->set_fuel(6); $track->car(1)->set_fuel(2); $track->car(2)->set_fuel(8); $track->car(0)->set_throttle(0); $track->car(1)->set_throttle(8, 1); $track->car(2)->set_throttle(12); } $gui->show; Gtk2->main(); exit 0; sub quit { Gtk2->main_quit; return FALSE; } sub scx_read { my ($event, $fh, $reader) = @_; $reader->read(); return TRUE; } sub usage { die "Usage: $0 [-t tty_line]\n" . "or: $0 -l logfile [-b starttime] [-e endtime] [-f]\n" . "-f ... replay as fast as possible\n"; } sub log_read_start { my ($data) = @_; my ($logreader, $parser, $fast) = @$data; our ($starttime, $log_starttime); my ($l_time, @data) = $logreader->get_data(); return FALSE if !$l_time; my $now = time; $starttime ||= $now; $log_starttime ||= $l_time; my $time_diff = ($l_time - $log_starttime) - ($now - $starttime); if (!$fast && $time_diff > 0) { # print "sleeping for $time_diff s\n"; usleep(1_000_000 * $time_diff); } $parser->add_data($l_time, @data); return TRUE; }