resolutions.pl
#!/usr/bin/perl -s
# resolutions.pl - Copyright (c) 2005,2008 by Mikkel Holm Olsen
use XML::Parser;
sub usage {
print($err."\n\n") if $err=shift;
print <<"EOF";
resolutions.pl v2.05 Copyright (c) 2005,2008 by Mikkel Holm Olsen
Generate a list of the most used video-modes for MAME/AdvanceMAME
USAGE
resolutions.pl [args] list.xml
WHERE
list.xml - input-file (XML) generated from MAME/AdvanceMAME
with the --listxml option.
ARGUMENTS
-r Don\'t swap hor/ver resolution for vertical games
-p=pct Stop after listing pct % (1-100) of the games
-n=num Stop after listing num video modes (resolutions)
-c Don\'t count clones (only parents)
-f Don\'t diffrentiate on refresh frequency
-o=? Only list horizontal (h) or vertical (v) games
EOF
exit;
}
# Handle arguments
$norotate=1 if ${r};
$fraction=$p/100 if ($p)&&($p>0)&&($p<=100);
$maxmodes=$n if $n;
$noclones=1 if $c;
$refresh=1 if !$r;
$filter='';
$filter='horizontal' if ($o eq 'v');
$filter='vertical' if ($o eq 'h');
usage() if $h || ${-help};
usage("Missing filename (list.xml)") if $#ARGV<0;
usage("Only one filename can be given") if $#ARGV>0;
$thisruns=$no_runner=0;
sub start_tag {
my %attrs;
$expat=shift(@_);
$elem=shift(@_);
return if ($elem=~/(rom|chip|dipswitch|dipvalue)/); # x2 speed-up
while (($key,$val)=splice(@_,0,2)) {
$attrs{$key}=$val;
}
if ($elem eq 'game'){
$runnable+=$thisruns;
$norunnable+=$no_runner;
$thisgame=$attrs{'name'};
if ($attrs{'runnable'} eq 'yes') {
$thisruns=($noclones&&$attrs{'cloneof'})?0:1;
$no_runner=0;
} else {
$thisruns=0;
$no_runner=1;
}
} elsif (!$thisruns) {
return;
} elsif (($elem eq 'video')||($elem eq 'display')) {
$orient="unknown";
if ($attrs{'orientation'}) { # AdvanceMAME style
$orient=$attrs{'orientation'};
} else { # Regular MAME style
$orient=(((int($attrs{'rotate'})/90)%2)?"vertical":"horizontal");
}
if ($filter eq $orient) {
$thisruns=0;
return;
}
if ($attrs{'type'}.$attrs{'screen'} eq 'raster') {
if ($norotate || ($orient eq 'horizontal')) {
($width,$height)=($attrs{'width'},$attrs{'height'});
} else {
($height,$width)=($attrs{'width'},$attrs{'height'});
}
$key=$width."x".$height;
} else { # must be vector then
$key="vector";
}
$key.="@".sprintf("%.2f",int($attrs{'refresh'}*100)/100) if $refresh;
$res_count{$key}++;
$example{$key}=$thisgame;
}
}
my $file = shift;
die "Can't find file \"$file\"" unless -f $file;
my $parser = new XML::Parser(ErrorContext => 2);
$parser->setHandlers(Start => \&start_tag);
$parser->parsefile($file);
$runnable++ if ($thisruns);
$norunnable++ if ($no_runner);
sub by_count { $res_count{$b} <=> $res_count{$a}; }
foreach $r (sort by_count keys %res_count) {
printf("%4d %-15s %s\n",$res_count{$r},$r,$example{$r});
$numgames+=$res_count{$r};
$nummodes++;
last if $fraction && ($numgames/$runnable)>=$fraction;
last if (($maxmodes)&&($nummodes>=$maxmodes));
}
print "\n$nummodes modes for ".$numgames."/".$runnable." ROMs (".
(int($numgames/$runnable*1000)/10)."%). ".$norunnable." additional non-runnable.\n";