# (c) 2005-2007 Electronic Arts Inc.
# 1.22 BG DOS based Directory Usage.
# 2.00 FB Rewritten in Perl 
# 2.10 FB Align to 2048
# 2.20 FB Return size in MB 
# 1.00 FB Initial version from cdu 2.2 into paddvd 2004.12.17

# This utility written for improving loadtimes, by Frank Barchard.  2004.6.28
# Its useful to get a directory listing of your DVD for a few reasons
# -Look for folders that contain few files, or are small in size, ane make them into big files.
# -Classify folders as Movies, Ingame, Boot, FE, BE and layout in that order (BE on outside) 

# Original version written in DOS by Brad Gour.
# Required minor updates for large files, and added File & Directory counts

#
# ABSTRACT
#
# paddvd - pad a dvd to specified size
#
# SUMMARY
#
# PadDVD <padfile> <discsectors> <rootfolder>
#     padfile        pad file to create
#     <discsectors>  size to fill disc out to
#     <rootfolder>   root of source data folder to compute size from
#
# DESCRIPTION
#
# paddvd recurses thru the specified directory tree, computing the total size
# considering ECC (32k) alignment, and then generates a pad file to fill the disc
# to the specified number of sectors.
#
# RETURNS
#
# total size in MB
#
# SEE ALSO
#
# makepad, du
#
# EXAMPLE
#
# The following script was used to build a padded ps2 disc on FIFA Street
#
# :::::::::::::::::::::::::::::::::::
# :: Make the iso
# :::::::::::::::::::::::::::::::::::
# Echo === Building iso ===
# cd /d %TP_DRIVE%:\fifast\build\ps2
# 
# del slus_211.47.elf
# del data\dvdbuild.map
# del fifast-ps2.ccz
# del /f mvporide.ini
# del /f data\femovies\*_pal.mpc
# 
# :: 2284232+10088=2294320 (dvdgen). Divisible by 16.  2283600 is free space with 18 directories.
# echo making padding disc to 2283600 sectors
# timex paddvd boot.pad 2283600 .
# 
# mkdir \fifast\build\ps2-iso
# 
# 
# :: luxpak once to get the ps2dir.h. 
# timex luxpak /end=2284216 /license=\fifast\tools\bin\layout\license-ntsc.txt @\fifast\tools\bin\layout\fifast.rsp e:\share\bball\fifast-ps2.ccz /map1=e:\share\bball\fifast-ps2.map /map2=e:\share\bball\fifast-ps2-map2.map
# 
# dvdmap e:\share\bball\fifast-ps2.map e:\share\bball\ps2dir.bin -noroot -invert
# huff -tj e:\share\bball\ps2dir.bin =e:\share\bball\ps2dir.qbin
# p4 edit \fifast\source\common\main\ps2dir.h
# imagetohex e:\share\bball\ps2dir.qbin \fifast\source\common\main\ps2dir.h
# 
# cd /d %TP_DRIVE%:\fifast\source
# timex make ntscfinal
# cd /d %TP_DRIVE%:\fifast\build\ps2
# 
# del slus_211.47.elf
# del data\dvdbuild.map
# 
# :: now build .ccz for dvdgen and .iso to burning
# timex luxpak /end=2284216 /license=\fifast\tools\bin\layout\license-ntsc.txt @\fifast\tools\bin\layout\fifast.rsp e:\share\bball\fifast-ps2.ccz /map1=e:\share\bball\fifast-ps2.map /map2=e:\share\bball\fifast-ps2-map2.map
# timex luxpak /end=2284216 /license=\fifast\tools\bin\layout\license-ntsc.txt @\fifast\tools\bin\layout\fifast.rsp e:\share\bball\fifast-ps2.iso
# 
# END ABSTRACT
#

use strict;
use warnings;

#--- usage information
sub PrintUsageAndExit()
{
	print STDERR "PadDVD v1.00 (Fromme) 2004.12.17 by Frank Barchard, EAC\n";
	print STDERR "USAGE: PadDVD <padfile> <discsectors> <rootfolder>\n";
	exit 1;
}

my $totaldircount = 1;
my $totalfilecount = 0;

#------------------------------------------------------------------------------
# List all directories in a tree.
#------------------------------------------------------------------------------

sub GetDirSize
{
	my ($directory) = @_;
	my $totalfilesize = 0;

	my $dircount = 0;
	my $filecount = 0;
	my $filesize = 0;
	my $subfilesize = 0;

	if (-f "$directory") {
		$subfilesize = -s "$directory";
		$filecount = 1;
		$dircount = 0;
		$totaldircount = 0;
		printf ('%12.0f%8.1f%7d%6d', $subfilesize, ($subfilesize)/1048576, $filecount, $dircount);
		printf (" $directory\n");
	}
	else {
		opendir(D, $directory) || die;
		foreach(readdir D) {
			if (-f "$directory/$_") {
				$filecount += 1;
				my $thisfilesize = -s "$directory/$_";
				my $alignedsize = ($thisfilesize+32767)&~32767;
				$filesize += $alignedsize;
			}
			elsif (-d "$directory/$_" and "$_" ne "." and "$_" ne "..") {
				$dircount += 1;
				my $dirsize = GetDirSize("$directory/$_");
				$subfilesize += $dirsize;
			}
		}
		closedir(D);

		$totaldircount += $dircount;
		$totalfilecount += $filecount;
		$subfilesize += $filesize;
		$totalfilesize += $subfilesize;

		printf ('%12.0f%8.1f%7d%6d', $filesize, ($filesize)/1048576, $filecount, $dircount);
		$directory =~ s/\.\///;
		printf (" $directory\n");
	}

	return $totalfilesize;
}

if (@ARGV < 1) {
	PrintUsageAndExit();
}

my $padfile = "boot.pad";
if (@ARGV >= 1) {
	$padfile = shift @ARGV;
	if ($padfile eq "?") {
		PrintUsageAndExit();
	}
}

my $disksize = 2283600;
if (@ARGV >= 1) {
	$disksize = shift @ARGV;
}

my $rootfolder = ".";
if (@ARGV >= 1) {
	$rootfolder = shift @ARGV;
}

system("makepad $padfile 0");

my $totalsize = GetDirSize($rootfolder);
my $padsize = $disksize*2048 - $totalsize;

printf ("Size %.0f bytes, %.0f sectors, Pad %.0f bytes, %.0f sectors, %d files, %d dirs\n", $totalsize, ($totalsize)/2048, $padsize,  $padsize/2048, $totalfilecount, $totaldircount);

system("makepad $padfile -$padsize");

exit (($totalsize+1048575)/1048576);

