View Single Post
Ice M A N

JCF Member

Joined: Jan 2001

Posts: 580

Ice M A N is doing well so far

Apr 2, 2006, 02:16 PM
Ice M A N is offline
Reply With Quote
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($fp262); //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)
*/
?>