#!/usr/bin/php -q
<?php
//
// hainsert 1.2
// by Derrick Sobodash 2003
// Released to the Public Domain on June 5, 2007
//
// This script builds new sc0 files for Heroine Anthem: The Elect of
// Wassernixie using text files generated by hadump and the original
// game sc0 files.
//
// fc /b reports all files (excluding the 21 with no actual text in
// them) built from dumped text files are binary perfect matches of
// the original sc0 files prior to dumping. This should garuantee
// full compatability in the game. Though something could always go
// wrong.
//
// If for osme reason you're wasting your time translating this game
// even though I'ma lready working on it, let me know if you encounter
// any generated files which crash the game. I will fix the script
// ASAP to account for these files.
//
// The script does a LOT of shit to make this work and I only commented
// to explain game structs and what each block of code is doing. I
// didn't see a need for more than that.
//
// Syntax:
//   hainsert [text_path] [sc0_path] [output_path]
// output_path will be created if it does not exist
//
echo ("\nhainsert v1.2\n");
set_time_limit(6000000);

if ($argc < 4) { DisplayOptions(); die; }
else { $txt_path = $argv[1]; $sc0_path = $argv[2]; $out_path = $argv[3]; }

// Simple routine to read in a directory listing and split it to an array
$txtdir=""; $sc0dir=""; $outdir="";
if ($handle = opendir($txt_path)) {
	while (false !== ($file = readdir($handle))) { 
		$txtdir .= $txt_path . "/$file\n";
		$sc0dir .= $sc0_path . "/" . substr($file, 0, strlen($file)-3) . "sc0\n";
		$outdir .= $out_path . "/" . substr($file, 0, strlen($file)-3) . "sc0\n";
	}
	closedir($handle);
}
$txt_list = split("\n", $txtdir); $sc0_list = split("\n", $sc0dir); $out_list = split("\n", $outdir);
@mkdir($out_path); unset($txtdir, $sc0dir, $outdir, $txt_path, $sc0_path, $out_path);

for ($z=2; $z < (count($txt_list)-1); $z++) {
	print "Processing $txt_list[$z]...\n";
	print "  Checking for sc0...";
	if (file_exists($sc0_list[$z])){
		print "found!\n  Loading original sc0...\n";
		$fd = fopen($sc0_list[$z], "rb");
		$file = fread($fd, filesize($sc0_list[$z]));
		fclose($fd);
		$extension = "sc0"; $sc0 = 'true';
	}
	else { print "failed!\n  Checking for sc1..."; $sc0 = 'false'; }
	if ((file_exists(substr($sc0_list[$z], 0, strlen($sc0_list[$z])-3) . "sc1"))&&$sc0==='false'){
		print "found!\n  Loading original sc1...\n";
		$fd = fopen((substr($sc0_list[$z], 0, strlen($sc0_list[$z])-3) . "sc1"), "rb");
		$file = fread($fd, filesize((substr($sc0_list[$z], 0, strlen($sc0_list[$z])-3) . "sc1")));
		fclose($fd);
		$extension = "sc1";
	}
	
	$header_test = substr($file, 4103, 3);
	$header_test_2 = substr($file, 4102, 4);
	if (($header_test != (chr(0xcd) . chr(0xcd) . chr(0xcd)))&&($header_test_2 != (chr(0x3) . chr(0x0) . chr(0x0) . chr(0x0)))){ $header = ""; $offset = 0; }
	else{ $header = substr($file, 0, 4100); $offset = 4100; }
	
	// <!-- Header structure -->
	// $1004 = String Count 16-bit little endian
	// Struct {
	//    32-bit string             = tag
	//    32-bit little endian long = offset
	//    32-bit little endian long = length
	//    16-byte string            = string name
	// }
	// 0x0000 = Spacer
	// <!-- Begin script -->
	$x = hexdec(bin2hex(strrev(substr($file, $offset, 2)))); $offset += 2;
	$x2 = substr($file, $offset-2, 2);
	print "  Processing sc0 data...\n";
	for ($i=0; $i<$x; $i++) {
		$tag[$i] = substr($file, $offset, 4);  $offset += 4;
		$off[$i] = substr($file, $offset, 4);  $offset += 4;
		$len[$i] = substr($file, $offset, 4);  $offset += 4;
		$str[$i] = substr($file, $offset, 16); $offset += 16;
	}
	
	$footer = substr($file, ($offset + 2 + hexdec(bin2hex(strrev($off[$i-1]))) + hexdec(bin2hex(strrev($len[$i-1])))));
	
	// Get strings from the text file as an array
	print "  Getting strings from txt...\n";
	$fd = fopen($txt_list[$z], "rb");
	$file = fread($fd, filesize($txt_list[$z]));
	fclose($fd);
	$txt = split("<>\r\n\r\n", $file);
	
	// Build new $off and $len tags using the nex English strings
	print "  Building new string data...\n";
	$strings = "";
	for ($i=0; $i<$x; $i++) {
		$new_txt[$i] = ltrim($txt[$i]) . chr(0);
		$new_off[$i] = pack("V*", strlen($strings));
		$new_len[$i] = pack("V*", strlen($new_txt[$i]));
		$strings .= $new_txt[$i];
	}
	
	// Construct a new pointer set
	print "  Cosntructing new pointer set...\n";
	$pointer_table = $x2;
	for ($i=0; $i<$x; $i++) {
		$pointer_table .= $tag[$i] . $new_off[$i] . $new_len[$i] . $str[$i];
	}
	$pointer_table .= chr(0) . chr(0);
	
	// Write out the new file
	print "  Writing new sc0 file...\n";
	$fo = fopen((substr($out_list[$z], 0, strlen($out_list[$z])-3) . $extension), "w");
	fputs($fo, $header . $pointer_table . $strings . $footer);
	fclose($fo);
}	

echo ("All done!...\n\n");

function DisplayOptions() {
	echo ("Compiled new sc0 files for Heroine Anthem using the original files and text\nfiles generated by hadump. New files will be built if a text file exists.\n  usage: hainsert [text_path] [sc0_path] [output_path]\n\n");
}
?>