X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=SCX%2FTrack.pm;h=90724290bc5252bd2bb7b897486d7ec23d3ef72c;hb=1ae1ef53e1bc6383b599782616b656a25094a7e6;hp=fcf6b80d94747fbe3cf4e1af8edf0d285f78de9a;hpb=47a074f4d544cc734a6c053025747ec08149370b;p=slotcarman.git diff --git a/SCX/Track.pm b/SCX/Track.pm index fcf6b80..9072429 100644 --- a/SCX/Track.pm +++ b/SCX/Track.pm @@ -5,9 +5,9 @@ package SCX::Track; use strict; use Carp; -use Time::HiRes qw(gettimeofday); use Glib qw(TRUE FALSE); use SCX::Car; +use SCX::Sound; our $SEMAPHORE_STEP = 1000; @@ -19,6 +19,9 @@ sub new { race_running => 0, lap_counting_up => 1, round => 0, + now => 0, + qualification_setup => -100, + no_semaphore => $args->{no_semaphore}, }; bless $self, $class; @@ -35,22 +38,35 @@ sub new { $self->{gui}->time(undef); $self->{gui}->best_lap(undef, undef); + $self->{sound} = new SCX::Sound; + return $self; } sub car { return shift->{cars}->[shift]; } sub race_start { - my ($self) = @_; + my ($self, $time) = @_; return if $self->{race_running} || $self->{start_in_progress} || $self->{qualification_running}; - $self->{round} = 0; - $self->{race_running} = 0; - $self->{start_in_progress} = 1; - $self->{semaphore} = 0; - $self->{gui}->show_semaphore(0); - Glib::Timeout->add($SEMAPHORE_STEP, \&semaphore_step, $self); + + if ($time - $self->{qualification_setup} < 1) { + $self->{qualification_running} = 1; + } elsif ($self->{no_semaphore}) { + $self->{round} = 0; + $self->{race_running} = 1; + $self->{race_running_since} = $self->{now}; + $self->{start_in_progress} = undef; + } else { + $self->{round} = 0; + $self->{race_running} = 0; + $self->{start_in_progress} = 1; + $self->{semaphore} = 0; + $self->{gui}->show_semaphore(0); + Glib::Timeout->add($SEMAPHORE_STEP, \&semaphore_step, $self); + } + $self->print_rounds; } sub semaphore_step { @@ -67,16 +83,18 @@ sub semaphore_step { Glib::Timeout->add($timeout, \&semaphore_step, $self); } elsif ($self->{semaphore} == 6) { $self->{race_running} = 1; - $self->{race_running_since} = gettimeofday; + $self->{race_running_since} = $self->{now}; $self->{start_in_progress} = undef; $self->{gui}->show_semaphore(0); Glib::Timeout->add($SEMAPHORE_STEP, \&semaphore_step, $self); } else { $self->{gui}->show_semaphore(undef); $self->{semaphore} = undef; + $self->{sound}->start(); } return FALSE; } + sub race_end { my ($self) = @_; @@ -84,38 +102,30 @@ sub race_end { } sub race_setup { - my ($self, $rounds) = @_; + my ($self, $rounds, $time) = @_; - $self->{round} = 0; - if ($rounds) { - $self->{race_rounds} = $rounds; + if ($time - $self->{qualification_setup} < 1) { + $self->{round} = 0; } else { - $self->{race_rounds} = 0; + if ($rounds) { + $self->{race_rounds} = $rounds; + } else { + $self->{race_rounds} = 0; + } } + $self->{round} = 0; $self->print_rounds; $self->{best_lap} = undef; $self->{gui}->show_semaphore(undef); $self->{race_running} = 0; - $self->{start_in_progress} = 0; - - $self->{gui}->time(undef); - $self->{gui}->best_lap(undef); -} - -sub reset { - my ($self) = @_; - - $self->{race_running} = 0; + $self->{qualification_running} = 0; $self->{start_in_progress} = 0; $self->{race_finishing} = 0; - $self->{best_lap} = undef; - $self->{round} = 0; - $self->print_rounds; - $self->{gui}->best_lap(undef); $self->{gui}->time(undef); + $self->{gui}->best_lap(undef); for my $car (0..5) { $self->car($car)->reset; @@ -126,8 +136,10 @@ sub print_rounds { my ($self) = @_; my $msg; - if ($self->{qualification_running}) { - $msg = 'Qualification'; + if ($self->{qualification_running} + || $self->{now} - $self->{qualification_setup} < 1) { + $msg = 'Qualification: ' . $self->{race_rounds} + . ($self->{race_rounds} == 1 ? ' round' : ' rounds'); } elsif ($self->{race_rounds}) { $msg = $self->{round} . '/' . $self->{race_rounds}; } else { @@ -137,8 +149,8 @@ sub print_rounds { $self->{gui}->rounds($msg); } -sub check_best_lap { - my ($self, $time, $who) = @_; +sub notify_best_lap { + my ($self, $id, $time, $who) = @_; return if !defined $time || $time == 0; @@ -149,29 +161,44 @@ sub check_best_lap { || $time < $self->{best_lap}) { $self->{best_lap} = $time; $self->{gui}->best_lap($time, $who); + + for my $car (0..5) { + $self->car($car)->set_global_best($car == $id); + $self->car($car)->print_best_lap; + } + + if (!$self->{race_running} || $self->{round} > 1) { + # skip the first round in the race + $self->{sound}->best_lap($id); + } return 1; } return 0; } -sub qualification_start { - my ($self) = @_; +sub qualification_setup { + my ($self, $rounds, $cars, $time) = @_; return if $self->{qualification_running}; + for my $car (0..5) { $self->car($car)->set_lap(undef); $self->car($car)->set_laptime(undef); } - $self->{qualification_running} = 1; - $self->{gui}->rounds('Qualification'); + $self->{qualification_setup} = $time; + $self->{race_rounds} = $rounds; + $self->{qualification_cars} = $cars; $self->{gui}->time(undef); $self->{gui}->best_lap(undef); + $self->print_rounds; } sub packet_received { my ($self, $time) = @_; + $self->{now} = $time; + if ($self->{race_running}) { $self->{gui}->time($time - $self->{race_running_since}); } @@ -208,6 +235,9 @@ sub recalc_order { if ($self->{round} && $self->{race_rounds} && $self->{round} > $self->{race_rounds}) { + if (!$self->{race_finishing}) { + $self->{sound}->winner($new_order[0]); + } $self->{race_finishing} = 1; } @@ -220,6 +250,36 @@ sub recalc_order { return ($lap_max_changed, $lap_max, $times[$new_order[0]]); } +sub recalc_qual_order { + my ($self) = @_; + + return if !$self->{qualification_running}; + + my @times; + for my $id (0..5) { + $times[$id] = $self->car($id)->{best_lap}; + if (!defined $times[$id] || $times[$id] <= 0) { + $times[$id] = 999_999; + } + } + + my @new_order = sort { + $times[$a] <=> $times[$b] + || + $a <=> $b; + } (0..5); + + my $best_time = $times[$new_order[0]]; + + for my $id (0..5) { + my $car = $new_order[$id]; + if ($self->car($car)->{order} != $id) { + $self->car($car)->set_order($id); + } + } + return ($times[$new_order[0]]); +} + sub finish_line { my ($self, $time, $regular, @cars) = @_; @@ -235,6 +295,14 @@ sub finish_line { return if !$was_processed; + if ($self->{qualification_running}) { + my ($best) = $self->recalc_qual_order; + for my $car (0..5) { + $self->car($car)->recalc_qual_distance($best); + } + return; + } + my ($lap_max_changed, $lap_max, $time_min) = $self->recalc_order($time);