# program for extracting times from Need for Speed: Porsche Unleashed file # this script should go in the SaveData folder which contains the 'nfs5.trk' file. # Author: Mark Jeays (mark [at] jeays [dot] net) # This is a public domain script. # Warning, if you try to run this script while the game is attempting to access the file the game may crash. use strict; # names of drivers that you want to show records for. my @drivernames = qw(Drivername1 Drivername2); # your name for output file my $displayname = 'Your Name'; # file position info my $recordlength = 76; my $nameoffset = 0; my $caroffset = 20; my $timeoffset = 72; my $numrecords = 8; # number of times recorded per track my $namelength = 20; my $carlength = 20; # files (assumes you are running the script in the SaveData folder) my $inputfile = 'nfs5.trk'; my $outputfile = 'times.htm'; # list of offsets for where the times are found for each track my %trackoffsets = ( "Côte d'Azur" => 432, "Schwarzwald" => 1624, "Pyrénées" => 2816, "Alps" => 4008, "Autobahn" => 5200, "Auvergne" => 6392, "Normandie" => 7584, "Zone Industrielle" => 8776, "Monte Carlo 1" => 9968, "Monte Carlo 2" => 11160, "Monte Carlo 3" => 12352, "Monte Carlo 4" => 13544, "Monte Carlo 5" => 14736, "Corsica" => 17120, ); my ($nameidx, $caridx, $timeidx, $name, $car, $time, $rawtime, $seconds, $total, $bestflag, $output); sub format_time { my ($seconds) = @_; my $min = int($seconds / 60); my $sec = sprintf("%02d",$seconds % 60); my $hun = sprintf("%02d",100*($seconds - (60*$min) - $sec)); return "$min:$sec.$hun"; } # slurp data $/ = undef; open(RECORDS,'<', $inputfile); binmode(RECORDS); my $savedata = ; close(RECORDS); # create output HTML file open(OUTPUT,'>',$outputfile); print OUTPUT "\n"; print OUTPUT "\n${displayname}'s Need for Speed: Porsche Unleashed Records\n"; print OUTPUT "

${displayname}'s Need for Speed: Porsche Unleashed Records

\n"; for my $track (sort keys %trackoffsets) { $bestflag = 0; $output .= "

$track

\n"; $output .= "
    \n"; for (0 .. $numrecords - 1) { $nameidx = $trackoffsets{$track} + $nameoffset + ($recordlength * $_); $caridx = $trackoffsets{$track} + $caroffset + ($recordlength * $_); $timeidx = $trackoffsets{$track} + $timeoffset + ($recordlength * $_); # find data $name = unpack("Z*",substr($savedata,$nameidx,$namelength)); $car = unpack("Z*",substr($savedata, $caridx, $carlength)); $rawtime = substr($savedata,$timeidx,2); # time is stored as a 2-byte integer, which is divided by 64 to get seconds. # this is a bit odd since the time is given to the hundredth of a second. $seconds = unpack("s", $rawtime) / 64; if (grep($name eq $_, @drivernames)) { $output .= "\t
  1. " . format_time($seconds) . " ($car)
  2. \n"; $total += $seconds unless($bestflag++); } } $output .= "
\n"; } $output = "

Total of all best times: " . format_time($total) ."

" . $output; print OUTPUT $output; print OUTPUT "

Last updated: ". scalar(localtime()) . "

\n"; print OUTPUT "\n"; close(OUTPUT);