G1rFxiTools/FXItoG1R/converter.php

370 lines
10 KiB
PHP
Raw Normal View History

2019-12-26 17:22:34 +01:00
<?php
ini_set("display_errors",0);
if(isset($_FILES['file']['name']))
{
require_once('../common/functions.php');
//format
if(isset($_POST['format']) && ($_POST['format']=="g1r" || $_POST['format']=="g1m") )
{
$format = $_POST['format'];
}
else
$format = "g1r";
//Get and decode FXI
$InFile = file_get_contents($_FILES['file']['tmp_name']);
$InFileSize = strlen($InFile);
$InFile = fxiDecode($InFile);
//Search for blocks (TXT, pictures or other)
$nbrPrgm = 0;
$textSize = 0;
$prgms = "";
for($i = 0 ; $i < $InFileSize*2; $i+=2)
{
//TXT
if(substr($InFile, $i, 6) == "545854" && substr($InFile,$i+8,4)=="5047")// TXT.PG
{
$valide = true;
//title : ([^\xff]{1,8})
$title = "";
for($j = $i+20 ; $j < $i+20+16; $j+=2)
{
if($InFile[$j].$InFile[$j+1] == "ff")
break;
else
$title.= $InFile[$j].$InFile[$j+1];
}
$title = str_pad($title, 16, '0', STR_PAD_RIGHT);
// echo "Title hex : ".$title."\nTitle ascii : \"".pack('H*',$title)."\"\n\n";
$titleLen = strlen($title)/2;
// \xff{16,23} : (16+8-$titleLen) FF
$Offset = $j;
for($j=$j ; $j < $i+68; $j++)
{
if($InFile[$j]!='f')
{
$valide = false;
break;
}
}
// (NL|BN)
if($valide && (substr($InFile,$i+68,4)!='4e4c' && substr($InFile,$i+68,4)!='424e'))
$valide = false;
// \xff{12} : (16+8-$titleLen) FF
if($valide)
{
for($j=$i+72 ; $j < $i+96; $j++)
{
if($InFile[$j]!='f')
{
$valide = false;
break;
}
}
}
//get prgm content
if($valide)
{
$text ="00000000000000000000";
for($j = $i+96 ; $j < $InFileSize*2; $j+=2)
{
if($InFile[$j].$InFile[$j+1]=='ff')
{
break;
}
else
{
$text.=$InFile[$j].$InFile[$j+1];
}
}
//calcul taille texte
$tailleText = strlen($text)/2;
$tailleText= $tailleText + (4-$tailleText%4);
$textSize += $tailleText+44;
$tailleTextHex = str_pad(dechex($tailleText), 8, '0', STR_PAD_LEFT);
//arrondi la taille a 4
$text = str_pad($text, $tailleText*2, '0', STR_PAD_RIGHT);
}
//validation prgm
if($valide)
{
$prgms .= "50524f4752414d0000000000000000000000000173797374656d0000".$title."01".$tailleTextHex."000000".$text;
$nbrPrgm++;
}
}
//Picture block
if(substr($InFile, $i, 6) == "494d47" && substr($InFile,$i+8,4)=="5043")
{
$valide = true;
//title : ([^\xff]{1,8})
$title = "";
for($j = $i+20 ; $j < $i+20+16; $j+=2)
{
if($InFile[$j].$InFile[$j+1] == "ff")
break;
else
$title.= $InFile[$j].$InFile[$j+1];
}
$title = str_pad($title, 16, '0', STR_PAD_RIGHT);
$titleLen = strlen($title)/2;
$picId = $title[14].$title[15];
// \xff{16,23} : (16+8-$titleLen) FF
$Offset = $j;
for($j=$j ; $j < $i+52; $j++)
{
if($InFile[$j]!='f')
{
$valide = false;
break;
}
}
// (DRUWF)
if($valide && (substr($InFile,$i+52,10)!='4452555746'))
$valide = false;
// \xff{13}
if($valide)
{
for($j=$i+70 ; $j < $i+96; $j++)
{
if($InFile[$j]!='f')
{
$valide = false;
break;
}
}
}
//get prgm content
if($valide)
{
$pics ="";
for($j = $i+96 ; $j < $i+8224+96; $j++)
{
$pics.=$InFile[$j];
}
$picsArray = getFxiPic($pics);
//fusion des couleurs (rouge/bleu/vert/blanc => noir/blanc)
//rouge
foreach($picsArray[0] as $key => $value)
{
$g1mPicsArray[0][$key]=$value;
}
//bleu
foreach($picsArray[1] as $key => $value)
{
$g1mPicsArray[0][$key]|=$value;
}
//vert
foreach($picsArray[2] as $key => $value)
{
$g1mPicsArray[0][$key]|=$value;
}
//blanc
foreach($picsArray[3] as $key => $value)
{
$g1mPicsArray[1][$key]=$value;
}
//test
// echo $picsArray[3][0];exit;
//generating g1m block
$text ="5049435455524520".$picId."00000000000000000000016d61696e0000000050494354".$picId."0000000700000800000000";
$color = 0;
$j =0;
while($color < 2)
{
$text .= str_pad(dechex($g1mPicsArray[$color][$j]), 2, '0', STR_PAD_LEFT);
$j++;
if($j > 1023)
{
$color++;
$j = 0;
}
}
//calcul taille texte
$tailleText = strlen($text)/2;
$tailleText= $tailleText + (4-$tailleText%4);
$textSize += $tailleText;
//arrondi la taille a 4
$text = str_pad($text, $tailleText*2, '0', STR_PAD_RIGHT);
$prgms.=$text;
//validation
$nbrPrgm++;
}
}
//MSC1  : TXT graph 100
elseif(substr($InFile, $i, 14) == "4d435331000000" && $InFile[$i+18].$InFile[$i+19]=="01")
{
$valide = true;
//title : ([^\xff]{1,8})
$title = "";
for($j = $i+20 ; $j < $i+20+16; $j+=2)
{
if($InFile[$j].$InFile[$j+1] == "ff")
break;
else
$title.= $InFile[$j].$InFile[$j+1];
}
$title = str_pad($title, 16, '0', STR_PAD_RIGHT);
// echo "Title hex : ".$title."\nTitle ascii : \"".pack('H*',$title)."\"\n\n";exit;
$titleLen = strlen($title)/2;
// \xff{16,23} : (16+8-$titleLen) FF
$Offset = $j;
for($j=$j ; $j < $i+76; $j++)
{
if($InFile[$j]!='f')
{
$valide = false;
break;
}
}
//get prgm content
if($valide)
{
$text ="00000000000000000000";
for($j = $i+96 ; $j < $InFileSize*2; $j+=2)
{
if($InFile[$j].$InFile[$j+1]=='ff')
{
break;
}
else
{
$text.=$InFile[$j].$InFile[$j+1];
}
}
//calcul taille texte
$tailleText = strlen($text)/2;
$tailleText= $tailleText + (4-$tailleText%4);
$textSize += $tailleText+44;
$tailleTextHex = str_pad(dechex($tailleText), 8, '0', STR_PAD_LEFT);
//arrondi la taille a 4
$text = str_pad($text, $tailleText*2, '0', STR_PAD_RIGHT);
}
//validation prgm
if($valide)
{
$prgms .= "50524f4752414d0000000000000000000000000173797374656d0000".$title."01".$tailleTextHex."000000".$text;
$nbrPrgm++;
}
}
//MSC1  : MAT graph 100
elseif(substr($InFile, $i, 14) == "4d435331000000" && $InFile[$i+18].$InFile[$i+19]=="06")
{
$valide = true;
//title : ([^\xff]{1,8})
$title = "";
for($j = $i+20 ; $j < $i+20+16; $j+=2)
{
if($InFile[$j].$InFile[$j+1] == "ff")
break;
else
$title.= $InFile[$j].$InFile[$j+1];
}
$title = str_pad($title, 16, '0', STR_PAD_RIGHT);
$letter = $title[8].$title[9];
// echo "Title hex : ".$title."\nTitle ascii : \"".pack('H*',$title)."\" ; letter : ".$letter."\n\n";exit;
$titleLen = strlen($title)/2;
// \xff{16,23} : (16+8-$titleLen) FF
$Offset = $j;
for($j=$j ; $j < $i+76; $j++)
{
if($InFile[$j]!='f')
{
$valide = false;
break;
}
}
//get content size
$contentSize = substr($InFile, $i+10, 8);
$contentSize = hexdec($contentSize);
//get matrix height
$matrixHeight = $InFile[$i+92].$InFile[$i+93];
//get matrix width
$matrixWidth = $InFile[$i+96].$InFile[$i+97];
//get prgm content
if($valide)
{
//contenu
$matrixContent= substr($InFile, $i+108, ($contentSize-16)*2);
//ajouter 3*00 apres 9eme puis au 9+3 +9
$matrixContentSize = strlen($matrixContent);
for($j=18 ; $j < $matrixContentSize; $j+=18)
{
if(isset($matrixContent[$j]))
{
$matrixContent = substr($matrixContent,0,$j)."000000".substr($matrixContent,$j,$matrixContentSize-$j);
$matrixContentSize+=6;
$j+=6;
}
else
break;
}
//calcul taille texte
$tailleText = strlen($matrixContent)/2;
$tailleText= $tailleText + (4-$tailleText%4) + 16;
$textSize += $tailleText + 44;
$tailleTextHex = str_pad(dechex($tailleText), 8, '0', STR_PAD_LEFT);
//arrondi la taille a 4
$matrixContent = str_pad($matrixContent, ($tailleText-16)*2, '0', STR_PAD_RIGHT);
//contenu finale
$prgms .=
"4d415420".$letter."0000000000000000000000".
"000000016d61696e000000004d41545f".
$letter."00000006". $tailleTextHex ."00000000000000".
"0000000000". $matrixHeight ."00". $matrixWidth ."00000000". $matrixContent;
}
//validation prgm
if($valide)
{
$nbrPrgm++;
}
}
}
// echo $InFile;exit;
//G1M generating
//filesize calculation
// $filesize = 32 + $textSize + 44*$nbrPrgm;
$filesize = 32 + $textSize;
if($filesize > 0xFFFFFFFF)
{
error("File too big.", "Fichier trop gros.");
}
//OFFSET 0xE : last filesize byte + 65(0x41) and NOT (inverted)
$offset0xE = $filesize + 0x41;
$offset0xE = 0xFFFFFFFF - $offset0xE;
$offset0xE = dechex($offset0xE);
$offset0xE = str_pad($offset0xE, 2, '0', STR_PAD_LEFT);
$offset0xE = substr($offset0xE, -2); // take the last byte
//OFFSET 0x10 : filesize NOT (inverted)
$offset0x10 = 0xFFFFFFFF - $filesize;
$offset0x10 = dechex($offset0x10);// to hex
$offset0x10 = str_pad($offset0x10, 8, '0', STR_PAD_LEFT);
//OFFSET 0x14 : last filesize byte + 184(0xB8) and NOT (inverted)
$offset0x14 = $filesize + 0xB8;
$offset0x14 = 0xFFFFFFFF - $offset0x14;
$offset0x14 = dechex($offset0x14);
$offset0x14 = str_pad($offset0x14, 2, '0', STR_PAD_LEFT);
$offset0x14 = substr($offset0x14, -2);
//OFFSET 0x14 : last filesize byte + 184(0xB8) and NOT (inverted)
$offset0x1E = $nbrPrgm;
$offset0x1E = 0xFFFF - $offset0x1E;
$offset0x1E = dechex($offset0x1E);
$offset0x1E = str_pad($offset0x1E, 4, '0', STR_PAD_LEFT);
//making
$fileContent = pack('H*',
"aaacbdaf90889a8dceffefffefff".$offset0xE."fe".
$offset0x10.$offset0x14."000000000000000000".$offset0x1E.
$prgms
);
//sending
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment;filename="'.substr($_FILES['file']['name'],0,-4).'.'.$format.'"');
header('Cache-Control: max-age=0');
$fh = fopen('php://output', 'wb');
fwrite($fh, $fileContent);
fclose($fh);
}
else
{
header("Location: ../");
}
?>