Once again, awesome work...
I can't wait to get back to working with this stuff.. (I didn't know J2L except for the header and first part of Data1, or a fair bit of J2A data2)
I'll try to find some more useful code/documentation I made to share later..
one thing I guess I'll have to double check is where you have:
(in J2T) char Unknown[256]; //I suspect this has something to do with transparency; haven't looked at it yet
I have a longer thing written down (entirely possible I had expanded it based on the bits), but I think it flagged tiles that either had some transparency and/or some pure white I think (probably a bug or white used to indicate transparent or somesuch..)..
a PHP J2T decoder and a couple comments I gave someone..:
it's slow and poorly made (requires GD, only does image [no mask], doesn't really do anything cleanly), but it's more of a proof of concept that you can do stuff in non-C/C++/VB/whatever...
PHP Code:
<?php
define("VERSION_TSF", 513);
define("VERSION_123", 512);
set_time_limit(60);//!! MegaMegatropolis broke 30...
$filename = "MegaMegatropolis.j2t";//last tileset I was testing with :)
$fp = fopen($filename,"rb");
$header = fread($fp, 262); //262 = sizeof(J2THEADER);
//unpack will make an array with index [1] giving be the int I'm looking for
list(,$version) = unpack('v',substr($header,220,2));//short int for version
//I've only tested this with one TSF tileset, but I think it's right
if ($version == VERSION_TSF) {
$MAXTILES = 4096;
} else {
$MAXTILES = 1024;
}
//compressed/uncompressed sizes of following sections:
list(,$s1clen) = unpack('V',substr($header,230,4));
list(,$s1len) = unpack('V',substr($header,234,4));
list(,$s2clen) = unpack('V',substr($header,238,4));
list(,$s2len) = unpack('V',substr($header,242,4));
unset($header);
//read & uncompress said sections
$s1compressed = fread($fp, $s1clen);
$s1 = gzuncompress($s1compressed,$s1len);
unset($s1compressed);
$s2compressed = fread($fp,$s2clen);
$s2 = gzuncompress($s2compressed,$s2len);
unset($s2compressed);
fclose($fp);
list(,$numtiles) = unpack('V',substr($s1,1024,4));
//Perhaps limit numtiles to 100? (remember to keep multiple of 10)
//this way: a lot quicker (depending on how big it really is)
//and people can't rip tilesets
//uncomment next line to do so:
//$numtiles = min($numtiles,100);
$height = $numtiles*1024/320;
$img = imagecreate(320,$height);
//palette
for ($i = 0; $i < 256; $i++) {
$r = ord($s1[$i*4+0]);
$g = ord($s1[$i*4+1]);
$b = ord($s1[$i*4+2]);
imagecolorallocate($img, $r,$g,$b);
}
//maps tiles from the "J2T order" to "JCS order"
$offsets = unpack('V*',substr($s1,1024+4+2*$MAXTILES,4*$MAXTILES));
unset($s1);
//top left corner of where to place current tile
$xoff = 0;
$yoff = 0;
for ($i = 0; $i < $numtiles; $i++) { //each tile
for ($j = 0; $j < 32; $j++) { // each row of pixels in tile
for ($k = 0; $k < 32; $k++) { // each pixel in row
$curpix = ord($s2[$offsets[$i+1]+32*$j+$k]);
imagesetpixel($img,$xoff+$k,$yoff+$j,$curpix);
}
}
//move where "current tile" goes
$xoff+=32;
if ($xoff == 320) {
$xoff=0;
$yoff+=32;
}
}
unset($s2,$offsets);
imagepng($img,"./write/$filename.png");
imagedestroy($img);
echo "DONE";
/*
You may also be interested in this stuff that I found out...
typedef struct _J2THEADER {
char copyright[180];
DWORD id; // 0x454c4954/TILE
DWORD magic; //0xafbeadde/DEADBEAF
char name[32];
short int version;
DWORD filesize;
DWORD checksum; //probably adler32 checksum
DWORD s1clen;
DWORD s1len;
DWORD s2clen;
DWORD s2len;
DWORD s3clen;
DWORD s3len;
DWORD s4clen;
DWORD s4len;
} J2THEADER;
typedef struct _J2TSECTION1 {
BYTE palette[256][4];
DWORD numtiles;
BYTE fastblit[1024];//in TSF, all these array will be 4096
BYTE reserved1[1024];
DWORD jcsorder[1024];
DWORD reserved2[1024];
DWORD unknown[1024];
DWORD reserved3[1024];
DWORD mask[1024];
DWORD flippedmask[1024];
} J2TSECTION1;
sections 2=gfx
section3.. still haven't looked at much.. based on a 10 second glance
from a while ago, I thought it was blit masks... (i.e. transparency masks..)
section 4 = masks (with flipped masks as well)
*/
?>