Register FAQ Search Today's Posts Mark Forums Read
Go Back   JazzJackrabbit Community Forums » Open Forums » General Jazz Jackrabbit Talk

JJ2 File Format Specifications

Reply
 
Thread Tools
Jerrythabest

JCF Member

Joined: Apr 2005

Posts: 2,602

Jerrythabest is a forum legendJerrythabest is a forum legendJerrythabest is a forum legend

Jun 3, 2009, 03:51 PM
Jerrythabest is offline
Reply With Quote
Has someone started on an AJAX implementation of JJ2 yet?


Really, reading all this makes me think we're almost ready for that. They should hurry with those 100 THz 50-core processors that are probably needed for playing 'JSJJ2' (JavaScriptJJ2) though.
__________________
djazz

JCF Member

Joined: Feb 2009

Posts: 257

djazz is OFF DA CHARTdjazz is OFF DA CHARTdjazz is OFF DA CHART

Jun 3, 2009, 10:54 PM
djazz is offline
Reply With Quote
Yea, I have thought about that too, but it's very hard I think.

I can now make php exe programs with a GUI, maybe we could make a completely php-based JJ2?
__________________
WebJCS 2 (new and in progress)
WebJCS 1 (old but complete)
SGIP Simple Games in Progress list
Level Packer v2 - With a GUI!
PHP Tileset Compiler
Grytolle

JCF Member

Joined: Sep 2004

Posts: 4,126

Grytolle is a forum legendGrytolle is a forum legendGrytolle is a forum legend

Jun 4, 2009, 02:13 AM
Grytolle is offline
Reply With Quote
Sounds optimized! Do it man
__________________
<center></center>
Jerrythabest

JCF Member

Joined: Apr 2005

Posts: 2,602

Jerrythabest is a forum legendJerrythabest is a forum legendJerrythabest is a forum legend

Jun 4, 2009, 04:36 PM
Jerrythabest is offline
Reply With Quote
Hmm... I think the best you could do with PHP with stuff like this is by using it as some sort of core layer to build a Javascript on top of it that will handle all the I/O. PHP is good at keeping track of stuff, but I'm not so optimistic about its abilities to react immediately to user input.
__________________
Stijn

Administrator

Joined: Mar 2001

Posts: 6,965

Stijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to behold

Jun 4, 2009, 06:05 PM
Stijn is offline
Reply With Quote
protip: this will lead nowhere

Seriously, porting JJ2 to javascript+php, what have you been smoking?
FQuist

JCF Member

Joined: Sep 2001

Posts: 3,251

FQuist is an asset to this forumFQuist is an asset to this forum

Jun 5, 2009, 04:24 AM
FQuist is offline
Reply With Quote
yeah
you don't need php/javascript for that.... html and the canvas element is enough..................
__________________
“The truth is that everything that can be accomplished by showing a person when he's wrong, ten times as much can be accomplished by showing him where he is right.” - Robert T. Allen

Interesting Jazz-related links:
Thread: Gameplay Theories - Thread: Make Up Your Own Gametype

Spotify.fm

Black Ninja

JCF Member

Joined: Mar 2001

Posts: 2,312

Black Ninja is an asset to this forumBlack Ninja is an asset to this forum

Jun 5, 2009, 01:25 PM
Black Ninja is offline
Reply With Quote
HTML is a luxury, a JJ2 port using straight Assembly is the way to go. Machine code would be even better!
djazz

JCF Member

Joined: Feb 2009

Posts: 257

djazz is OFF DA CHARTdjazz is OFF DA CHARTdjazz is OFF DA CHART

Jun 5, 2009, 02:06 PM
djazz is offline
Reply With Quote
It wouldn't be hard to do a JCS based on HTML, CSS, JavaScript and PHP. Just look at my level editor, it has tiles and rules (events)!
Thanks to Stijn for making it easier to read J2l and J2t!

A web-based JJ2 is nearly impossible, I think, with HTML, PHP and JS+Ajax. Because it need to handle TCP and UDP connections.
__________________
WebJCS 2 (new and in progress)
WebJCS 1 (old but complete)
SGIP Simple Games in Progress list
Level Packer v2 - With a GUI!
PHP Tileset Compiler
Stijn

Administrator

Joined: Mar 2001

Posts: 6,965

Stijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to behold

Jun 5, 2009, 02:29 PM
Stijn is offline
Reply With Quote
Quote:
Originally Posted by DJazz View Post
It wouldn't be hard to do a JCS based on HTML, CSS, JavaScript and PHP. Just look at my level editor, it has tiles and rules (events)!
You might find this interesting - it was made in the era of firefox 2 and optimized for that browser, so it doesn't look perfect in later versions, but I guess you get the idea.

FQuist made a working version of a collaborative web-based JCS a year or two ago (you could create a level together, and see the changes others made real-time), which that page of mine is based on. Note that back then the J2L and J2T formats were not documented yet.
djazz

JCF Member

Joined: Feb 2009

Posts: 257

djazz is OFF DA CHARTdjazz is OFF DA CHARTdjazz is OFF DA CHART

Jun 6, 2009, 02:48 AM
djazz is offline
Reply With Quote
Awesome Stijn! does it use any PHP or is it static HTML?
__________________
WebJCS 2 (new and in progress)
WebJCS 1 (old but complete)
SGIP Simple Games in Progress list
Level Packer v2 - With a GUI!
PHP Tileset Compiler
Stijn

Administrator

Joined: Mar 2001

Posts: 6,965

Stijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to behold

Jun 6, 2009, 02:58 AM
Stijn is offline
Reply With Quote
It uses some PHP for breaking up a tileset image in 32x32 tile images, but apart from that it's all Javascript/CSS/HTML. The PHP part could probably be improved a lot (to handle .j2t files directly for example).
Jerrythabest

JCF Member

Joined: Apr 2005

Posts: 2,602

Jerrythabest is a forum legendJerrythabest is a forum legendJerrythabest is a forum legend

Jun 7, 2009, 04:38 AM
Jerrythabest is offline
Reply With Quote
I remember that script... it's so awesome

Although I wasn't serious about the AJAX JJ2, it would be pretty awesome
__________________
CownLeme

Banned

Joined: Nov 2009

Posts: 3

CownLeme is doing well so far

Nov 21, 2009, 06:38 PM
CownLeme is offline
Reply With Quote
JJ2 File Format Specifications

Just wondering if anyone could help me with a problem I am having. I need to have a lot o webpages that pull a line of text from a txt file so that when the file is changed, all the HTML files will have the new info when they start.

Any ideas? Please let me know.
SpazAlex0777

JCF Member

Joined: Dec 2009

Posts: 5

SpazAlex0777 is doing well so far

Dec 21, 2009, 09:56 AM
SpazAlex0777 is offline
Reply With Quote
Good guide!
Sfaizst

JCF Member

Joined: Mar 2008

Posts: 99

Sfaizst is an asset to this forum

Dec 23, 2009, 07:42 PM
Sfaizst is offline
Reply With Quote
Hello
Good Job Guys,
I tryed to create basics on this thread a component for Delphi and i have the most finished but I have a problem with compress2, I have more parameters as you in the function header and i dont know 3 of them, i hope someone can help me.

How the compress2 Function is looking at delphi:
ZlibEx.ZCompress2(inBuffer,inSize,outBuffer,outSiz e,compressionlevel, windowBits,memLevel,strategy)

the first 4 i know (...) and i think the compression level is "max" (9)
WindowBits and memLevel are Integer Values (4byte, in c++ "int")
The strategy have 5 possible values:
- zsDefault(0)
- zsFiltered(1)
- zsHuffman(2)
- zsRLE(3)
- zsFixed(4)

I hope someone can help me with this, when i get this working i post my component for Delphi here.

Sfaizst

Last edited by Sfaizst; Dec 23, 2009 at 08:00 PM.
Violet CLM

JCF Éminence Grise

Joined: Mar 2001

Posts: 11,047

Violet CLM has disabled reputation

Dec 31, 2009, 01:56 PM
Violet CLM is offline
Reply With Quote
Does anyone know if Data3 in .j2t files is read by JCS, or only JJ2?
__________________
djazz

JCF Member

Joined: Feb 2009

Posts: 257

djazz is OFF DA CHARTdjazz is OFF DA CHARTdjazz is OFF DA CHART

Jan 2, 2010, 10:23 AM
djazz is offline
Reply With Quote
J2L - Event Map, Events in general and the Generator Event

Quote:
Originally Posted by Neobeo View Post
The J2L format
...
Data2 - The Event Map
Each event is a long (4 bytes long), so this buffer should be (Layer4Width * Layer4Height * 4) bytes long.
I've done testings and research about this and this is what I have found so far:

Each event looks like this (4 bytes):
Code:
struct Event {
	char EventID;
	char Unknown[3];
}
Where unknown are the event parameters. If there are no parameters, all three are 0.

I've done some deeper research about the Generator event (216), and found out this:
If the Event is 12 (Belt AccR) and the Delay is 3, the structure of the Event Data is:
Code:
216 192 48 0
192 / 16 = 12
48 / 16 = 3

But this ONLY applies when Event or Delay is below 15.
Example with values above 15:
Event: 58 (TNT)
Delay: 29

And we get the following result:
Code:
216 160 211 1
As you can see, the Event and Delay are more hard coded than before.
I've made a PHP script that calculates the Delay:
PHP Code:
<?php
$event
=chr(216).chr(160).chr(211).chr(1);
$delay intval(ceil(((ord(substr($event,2,1)))/16)+(ord(substr($event,3,1))*15)));
?>
Where $event is the four byte part from the Event Map, and this code sets $delay to 29, which is the correct delay.
This code isn't tested with all the combinations of event and delays, as there are a lot of combinations:
256*32 = 8192
All I know it works with the most event and delays, and there may be some exceptions.


If we/someone will make a new JCS or make a JCS patch, or something else related to events, please help me/us.
If this information was useful, or you got any questions/suggestions/further knowledge, please let me know.
Comments are appreciated!
__________________
WebJCS 2 (new and in progress)
WebJCS 1 (old but complete)
SGIP Simple Games in Progress list
Level Packer v2 - With a GUI!
PHP Tileset Compiler

Last edited by djazz; Jan 2, 2010 at 01:13 PM.
Violet CLM

JCF Éminence Grise

Joined: Mar 2001

Posts: 11,047

Violet CLM has disabled reputation

Jan 2, 2010, 11:39 AM
Violet CLM is offline
Reply With Quote
DJazz: No worries, events are understood.
Neobeo addresses your research.
Same info, in a JCSref article. (Scroll down to "Parameters vs. Bitfields.")
__________________
djazz

JCF Member

Joined: Feb 2009

Posts: 257

djazz is OFF DA CHARTdjazz is OFF DA CHARTdjazz is OFF DA CHART

Jan 2, 2010, 05:50 PM
djazz is offline
Reply With Quote
A better J2L Event reader/parser

Aah, I haven't seen those pages before, thanks!
That solution is much more simpler than mine..

Anyway, it was so interesting that I made a PHP script to get all the event data and it's parameters.

It's heavily commented, so you easy understand what it does :P

PHP Code:
<?php
/*
This code is made by DJazzy of J2NSM, and a few lines are from Stijn's J2L reader PHP-class.
Thanks to Neobeo, who made the research, and to Jerry for his questions.

Changelog:
-changed the behavior for Generators
-some small changes in the parameter loop
-rearranged the code

Todo:
-add error handling
*/

// If you are not using PHP5, then use this function
if(!function_exists('str_split')) {
    function 
str_split($string,$string_length=1) {
        if(
strlen($string)>$string_length || !$string_length) {
            do {
                
$c strlen($string);
                
$parts[] = substr($string,0,$string_length);
                
$string substr($string,$string_length);
            } while(
$string !== false);
        } else {
            
$parts = array($string);
        }
        return 
$parts;
    }
}

function 
getJcsIni($path) {
    
    
// Open the JCS.ini file for reading
    
$handle fopen($path"r");
    
    
// Init the main JCSini variable (local)
    
$JCSini=array();
    
    
// Init the read variable, when true: put data in the JCSini variable
    
$read=false;
    
    
// If the file could be opened for reading, continue
    
if ($handle) {
        
        
// Index for each EventID
        
$i=0;
        
        
// Start the while loop, loops until End Of File is found
        
while (!feof($handle)) {
            
            
// Store data buffer, read max 4096 bytes, a row in the file
            
$buffer fgets($handle4096);
            
            
// If it find the row with "Events" in it, set read to true, index to 1 and continue to next loop/row
            
if(strpos($buffer,'Events') && strlen($buffer)==10 && $read==false) {$i=1;$read=true;continue;}
            
            
// If read is true, start store the event info in the JCSini variable
            
if($read==true) {$JCSini[$i] = explode("|",preg_replace('/(\d+)\=/i','',$buffer));}
            
            
// Only store 255 variables
            
if($i==255) break;
            
            
// Increment index with 1
            
$i++;
            
        } 
// End WHILE-loop
        
        // Close the file
        
fclose($handle);
        
        
// Return JCSini
        
return $JCSini;
        
    } 
// End IF-statement
    
    // If it couldn't open file for reading, return FALSE
    
return false;
    
// End of function
        
function parseEventMap($eventdata,$JCSini) {
    
    
// Split up the EventMap using str_split (PHP5)
    
$eventdata str_split($eventdata,4);
    
    
// The main variable containing all events
    
$Event=array();
    
    
// Init the EventIndex variable
    
$i=0;
    
    
// Main loop. Loop through each event
    
foreach($eventdata as $val) {
        
        
// If there are no event, or an event with ID 0, skip this and continue on next
        
if(ord(substr($val,0,1))==0)  {$i++;continue;}
        
        
// Get the field of bits
        
list(,$bitfield) = unpack('V'substr($val04));
        
        
// Make it 32-bit, add zeros until it is 32-bit length
        
$fullBitfield str_pad(decbin($bitfield),32,"0",STR_PAD_LEFT);
        
        
// Store the Event ID
        
$Event[$i]['id']=bindec(substr($fullBitfield,-8,8));
        
        
// Store the name, trim away NULLs and white spaces
        
$Event[$i]['name']=trim($JCSini[$Event[$i]['id']][0]);
        
        
// Store the short name, that is displayed on the event in JCS. Rows are separated by a "\n" (linebreak)
        
$Event[$i]['shortname']=trim($JCSini[$Event[$i]['id']][3]).((trim($JCSini[$Event[$i]['id']][4])=="")?"":"\n".trim($JCSini[$Event[$i]['id']][4])."");
        
        
// Store difficulty. 0 = Normal, 1 = Easy, 2 = Hard, 3 = MP only
        
$Event[$i]['difficulty']=bindec(substr($fullBitfield,-10,2));
        
        
// Store the illuminate checkbox's value
        
$Event[$i]['illuminate']=(substr($fullBitfield,-11,1)==1)? true false;
        
        
// Stores true if the event is an generator (event 216), else false
        
$Event[$i]['generator']=($Event[$i]['id']==216)? true false;
        
        
// Init a temporary variable, that will contain the bitfields names and lengths
        
$param=array();
        
        
// Init a temporary variable, to store all data of the final parameters
        
$params=array();
        
        
// Init the final result variableof the parameters, fill with NULL if some parameter don't exists
        
$Event[$i]['params']=array(NULL,NULL,NULL,NULL);
        
        
// Parameter index holder
        
$p=0;
        
        
// Init variable that holds the last position for reading bitfields
        
$lastpos=-12;
        
        
// Loop through each parameter
        
for($j=5;$j <= 8$j++) {
            
            
// If there was no parameter at this id, break the loop
            
if(!($JCSini[$Event[$i]['id']][$j])) {$param[$j]=null;break;}
            
            
// Split up name and the bitfield length number
            
$param[$p]=explode(":",$JCSini[$Event[$i]['id']][$j]);
            
            
// Store the current parameter's name
            
$params[$p]['name']=$param[$p][0];
            
            
// Store the value of the current parameter
            
$params[$p]['value']=bindec(substr($fullBitfield,$lastpos-intval(str_replace("-","",$param[$p][1])),intval(str_replace("-","",$param[$p][1]))));
            
            
// This IF-statement handles negative bitfield lengths
            
if($param[$p][1] < && $params[$p]['value'] >= bindec("".pow(10,intval(str_replace("-","",$param[$p][1]))-1)))
                
// If current parameter is negative, store it's value again
                
$params[$p]['value']=-(bindec(pow(10,intval(str_replace("-","",$param[$p][1]))))-$params[$p]['value']);
            
            
// Change the last position for reading, going on next parameter
            
$lastpos-=intval(str_replace("-","",$param[$p][1]));
            
            
// Store the temporary data to the Event variable
            
$Event[$i]['params'][$p]=$params[$p];
            
            
// Increment the index with 1
            
$p++;
            
        } 
// End FOR-loop
        
        // Do this if the event is a Generator
        
if($Event[$i]['generator']) {
            
            
// Re-store the new EventID
            
$Event[$i]['id']=$params[0]['value'];
            
            
// Re-store the new name
            
$Event[$i]['name']=trim($JCSini[$Event[$i]['id']][0]);
            
            
// Re-store the new shortname
            
$Event[$i]['shortname']=trim($JCSini[$Event[$i]['id']][3]).((trim($JCSini[$Event[$i]['id']][4])=="")?"":"\n".trim($JCSini[$Event[$i]['id']][4])."");
            
        } 
// End Generator IF-statement
        
        // Increment the EventIndex variable with 1
        
$i++;
        
    } 
// End FOREACH-loop
    
    // Return the Event variable
    
return $Event;
    
// End function



// Path to your JCS.ini
$JCSiniPath  "JCS.ini";

// Read, parse and store it in JCSini
$JCSini getJcsIni($JCSiniPath);

// Enter the path where your J2L file is located
$infile "level.j2l";

// Open file for reading
$f=fopen($infile,"r");

// Store the J2L file header
$header fread($f262);

// Init the variable where it store compressed sized
$offsets = array();

// Store the sizes in the offsets variable
list(,$offsets['info_c']) = unpack('V'substr($header2304));
list(,
$offsets['evnt_c']) = unpack('V'substr($header2384));

// Read the levelinfo stream (needed to move the fread file pointer)
$LevelInfo gzuncompress(fread($f$offsets['info_c']));

// Read the actual event stream
$EventData gzuncompress(fread($f$offsets['evnt_c']));

// Close the file        
fclose($f);

// Make the actual parsing of the eventmap stream
$events=parseEventMap($EventData,$JCSini);

// Output the EventMap
print_r($events);
?>
If you would find any errors or bugs, please report them! Enjoy!

The first working code was made in three hours!
__________________
WebJCS 2 (new and in progress)
WebJCS 1 (old but complete)
SGIP Simple Games in Progress list
Level Packer v2 - With a GUI!
PHP Tileset Compiler

Last edited by djazz; Jan 3, 2010 at 06:17 AM. Reason: Changed levelpath
Violet CLM

JCF Éminence Grise

Joined: Mar 2001

Posts: 11,047

Violet CLM has disabled reputation

Jan 2, 2010, 06:10 PM
Violet CLM is offline
Reply With Quote
Very nice! Particularly remembering to account for the negative parameters. Depending on the context that gets used in, one probably also wants to put in some exception for the Generator event, since giving the name of the event being generated is more useful than the number.
__________________
djazz

JCF Member

Joined: Feb 2009

Posts: 257

djazz is OFF DA CHARTdjazz is OFF DA CHARTdjazz is OFF DA CHART

Jan 3, 2010, 05:20 AM
djazz is offline
Reply With Quote
Thanks

Quote:
Originally Posted by Unknown Rabbit View Post
Depending on the context that gets used in, one probably also wants to put in some exception for the Generator event, since giving the name of the event being generated is more useful than the number.
This is fixed now. The ID, name and shortname are fetched from the Event-parameter with JCS.ini, and the $Event[$index]['generator'] now contains a boolean you can check whenever it is a generator or not. The event's parameters Event and Delay are still in the params subarray.
__________________
WebJCS 2 (new and in progress)
WebJCS 1 (old but complete)
SGIP Simple Games in Progress list
Level Packer v2 - With a GUI!
PHP Tileset Compiler
Foly

JCF Member

Joined: Jan 2009

Posts: 202

Foly has disabled reputation

Jan 3, 2010, 10:50 PM
Foly is offline
Reply With Quote
Quote:
Originally Posted by Unknown Rabbit View Post
DJazz: No worries, events are understood.
Neobeo addresses your research.
Same info, in a JCSref article. (Scroll down to "Parameters vs. Bitfields.")
I read the article about the event theory. Someone probably found it out already but this means you can make up to 1 million triggers. My question is will there be more lag if I use trigger 500.000 and trigger 1 compared to trigger 5 and trigger 1? And will there be more lag if im able to use 1 million triggers with jcs instead of 31? And is there any jcs.ini around that good and has edits like this (+MCE+SCE)?

Also in that article: I tried to give the apple |Speed:-8 in jcs but it appeared in the name of the event, how do you change it in jcs so it will appear in a box where you can edit it?
__________________
[13:07:13] *** Foly is on a KILLING SPREE!
[13:07:14] *** you killed yourself
[13:07:14] *** Foly was looking good but died instead...
Violet CLM

JCF Éminence Grise

Joined: Mar 2001

Posts: 11,047

Violet CLM has disabled reputation

Jan 3, 2010, 11:08 PM
Violet CLM is offline
Reply With Quote
You will not be able to use more than 32 (0-31) triggers because that's all that the game code allows for, the trigger events only read the first six bytes and not the others for figuring out the TriggerID.

As for Apple, JCS names use two fields, so that you can have multi-line event names, not just one, so you need a blank field between Apple and the parameters. Compare to, say, Echo.
Code:
141=Apple                           |+|Food      |Apple  |       |Speed:-8
__________________
Foly

JCF Member

Joined: Jan 2009

Posts: 202

Foly has disabled reputation

Jan 4, 2010, 03:25 AM
Foly is offline
Reply With Quote
Quote:
Originally Posted by Unknown Rabbit View Post
You will not be able to use more than 32 (0-31) triggers because that's all that the game code allows for, the trigger events only read the first six bytes and not the others for figuring out the TriggerID.

As for Apple, JCS names use two fields, so that you can have multi-line event names, not just one, so you need a blank field between Apple and the parameters. Compare to, say, Echo.
Code:
141=Apple                           |+|Food      |Apple  |       |Speed:-8
Ah, too bad. I guess you need the source code to make some real changes. Anyway, thanks for the information (and all stuff on jcsref).
__________________
[13:07:13] *** Foly is on a KILLING SPREE!
[13:07:14] *** you killed yourself
[13:07:14] *** Foly was looking good but died instead...
Stijn

Administrator

Joined: Mar 2001

Posts: 6,965

Stijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to behold

Jan 9, 2010, 02:38 PM
Stijn is offline
Reply With Quote
http://mods.jazz2online.com/j2b.txt

(Very) incomplete J2B documentation, not complete by far but at least more readable than Dr. Eggman's article. Thanks to Torkell for additions and corrections. If you have any more information on the format, feel free to share.
Stijn

Administrator

Joined: Mar 2001

Posts: 6,965

Stijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to behold

Jan 30, 2010, 12:58 PM
Stijn is offline
Reply With Quote
Python tileset renderer: http://www.jazz2online.com/junk/sour...ile=tileset.py

Can be optimized (it doesn't cache tiles, for example), but I thought, why not put it up here.
Krezack

JCF member

Joined: Nov 2001

Posts: 5,156

Krezack has disabled reputation

Jan 31, 2010, 03:01 AM
Krezack is offline
Reply With Quote
Quote:
Originally Posted by Stijn View Post
Python tileset renderer: http://www.jazz2online.com/junk/sour...ile=tileset.py

Can be optimized (it doesn't cache tiles, for example), but I thought, why not put it up here.
Cheers.
__________________
"Are we not threatened with a flood of information? And is this not the monstrousness of it: that it crushes beauty by means of beauty, and annihilates truth by means of truth? For the sound of a million Shakespeares would produce the very same furious din and hubbub as the sound of a herd of prairie buffalo or sea billows."
—Stanisław Lem, Imaginary Magnitude (1973)
Stijn

Administrator

Joined: Mar 2001

Posts: 6,965

Stijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to behold

Jan 31, 2010, 07:52 AM
Stijn is offline
Reply With Quote
I believe the J2L specification is wrong:

Code:
JcsLayerWidth[0 to 7] 	 Byte (1 byte each) 	 Width of layer as seen in JCS. (decreased by Tile Width setting)
LayerWidth[0 to 7] 	Byte (1 byte each) 	Width of layer as used by JJ2 and other DataStreams.
This can't be right, as 1 byte can't hold a value higher than 256 and layer width can be far over 256 (1023, according to JCS). I'm having similar troubles with some other layer data fields. Does anyone have the correct format for the this and other layer data in the J2L file?
blurredd

JCF Member

Joined: Nov 2001

Posts: 1,896

blurredd is an asset to this forumblurredd is an asset to this forum

Jan 31, 2010, 11:40 AM
blurredd is offline
Reply With Quote
I thought you would've know the correct specification considering that you made the php Level class. Anyway, here is the struct that I have been using recently. Some of it is based on your Level class.
__________________
D3
Extra. No CTO v0.75
Animating Tiles Properties.
ATB Contest. Scripting Language.
Gameplay Theories.
1UP. Pitfall. Desolation.
SC2.

Stijn

Administrator

Joined: Mar 2001

Posts: 6,965

Stijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to behold

Jan 31, 2010, 11:49 AM
Stijn is offline
Reply With Quote
Yes, but I only got that to work after skipping random numbers of bytes (the LayerUnknown parts, for example - their size also doesn't match NeoBeo's article), and I hoped someone else had a more robust solution.

Thanks for the code! I see you also haven't figured it out all, but at least a C struct comes in handy for what I was trying to do.
cooba

JCF Veteran

Joined: Jan 2004

Posts: 7,814

cooba is a glorious beacon of lightcooba is a glorious beacon of lightcooba is a glorious beacon of lightcooba is a glorious beacon of lightcooba is a glorious beacon of lightcooba is a glorious beacon of light

Jan 31, 2010, 12:12 PM
cooba is offline
Reply With Quote
Quote:
Originally Posted by BlurredD
Code:
#ifdef TSF_RELEASE
#define MAX_ANIMATING_TILES 256
#else
#define MAX_ANIMATING_TILES 128
#endif
Are you sure about this? I could have sworn that I once had about 130-140 animations, and it was a 1.23 level. Unfortunately I lost it so I can't check and be sure.
blurredd

JCF Member

Joined: Nov 2001

Posts: 1,896

blurredd is an asset to this forumblurredd is an asset to this forum

Jan 31, 2010, 10:17 PM
blurredd is offline
Reply With Quote
I'm sure. You can't even add more than 128 animating tiles in 1.23 JCS.
__________________
D3
Extra. No CTO v0.75
Animating Tiles Properties.
ATB Contest. Scripting Language.
Gameplay Theories.
1UP. Pitfall. Desolation.
SC2.

Stijn

Administrator

Joined: Mar 2001

Posts: 6,965

Stijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to behold

Feb 1, 2010, 04:18 PM
Stijn is offline
Reply With Quote
I dunno if this has been posted before (I couldn't find anything about it), so here goes: a list of what set/animation goes with JCS events. Formatted as a Python dictionary (remove the newlines if you want to use it in Python though), but should be easy to convert.

Code:
#format: Event ID (as in jcs.ini): (setID, animationID)
events = {
    29: (55, 14), #Jazz Level Start
    30: (86, 14), #Spaz Level Start
    31: (86, 14), #Multiplayer Level Start
    33: (1, 30), #Freezer Ammo+3
    34: (1, 26), #Bouncer Ammo+3
    35: (1, 35), #Seeker Ammo+3
    36: (1, 50), #3Way Ammo+3
    37: (1, 58), #Toaster Ammo+3
    38: (1, 60), #TNT Ammo+3
    39: (1, 62), #Gun8 Ammo+3
    40: (1, 69), #Gun9 Ammo+3
    41: (100, 5), #Still Turtleshell
    42: (103, 2), #Swinging Vine
    43: (1, 2), #Bomb
    44: (68, 85), #Silver Coin
    45: (68, 38), #Gold Coin
    46: (68, 6), #Gun crate
    47: (68, 6), #Carrot crate
    48: (68, 6), #1Up crate
    49: (68, 4), #Gem barrel
    50: (68, 4), #Carrot barrel
    51: (68, 4), #1up barrel
    52: (68, 6), #Bomb Crate
    53: (68, 56), #Freezer Ammo+15
    54: (68, 55), #Bouncer Ammo+15
    55: (68, 57), #Seeker Ammo+15
    56: (68, 58), #3Way Ammo+15
    57: (68, 59), #Toaster Ammo+15F
    58: (68, 91), #TNT (armed explosive, no pickup)
    59: (68, 37), #Airboard
    60: (93, 6), #Frozen Green Spring
    61: (68, 30), #Gun Fast Fire
    62: (68, 6), #Spring Crate
    63: (68, 23), #Red Gem +1
    64: (68, 23), #Green Gem +1
    65: (68, 23), #Blue Gem +1
    66: (68, 23), #Purple Gem +1
    67: (68, 35), #Super Red Gem
    68: (9, 4), #Birdy
    69: (68, 4), #Gun Barrel
    70: (68, 6), #Gem Crate
    71: (68, 71), #Jazz<->Spaz
    72: (68, 22), #Carrot Energy +1
    73: (68, 83), #Full Energy
    74: (68, 32), #Fire Shield
    75: (68, 11), #Water Shield
    76: (68, 52), #Lightning Shield
    79: (68, 34), #Fast Feet
    80: (68, 1), #Extra Live
    81: (68, 29), #End of Level signpost
    83: (68, 15), #Save point signpost
    84: (12, 1), #Bonus Level signpost
    85: (93, 8), #Red Spring
    86: (93, 6), #Green Spring
    87: (93, 1), #Blue Spring
    88: (68, 73), #Invincibility
    89: (68, 88), #Extra Time
    90: (68, 43), #Freeze Enemies
    91: (93, 9), #Hor Red Spring
    92: (93, 7), #Hor Green Spring
    93: (93, 2), #Hor Blue Spring
    94: (68, 69), #Morph Into Bird
    95: (68, 53), #Scenery Trigger Crate
    96: (68, 41), #Fly carrot
    97: (49, 1), #RectGem Red
    98: (49, 1), #RectGem Green
    99: (49, 1), #RectGem Blue
    100: (99, 1), #Tuf Turt
    101: (98, 6), #Tuf Boss
    102: (59, 3), #Lab Rat
    103: (33, 1), #Dragon
    104: (60, 5), #Lizard
    105: (16, 1), #Bee
    106: (73, 3), #Rapier
    107: (85, 1), #Sparks
    108: (2, 2), #Bat
    109: (96, 7), #Sucker
    110: (21, 1), #Caterpillar
    111: (19, 3), #Cheshire1
    112: (20, 3), #Cheshire2
    113: (52, 5), #Hatter
    114: (8, 5), #Bilsy Boss
    115: (80, 3), #Skeleton
    116: (30, 1), #Doggy Dogg
    117: (100, 8), #Norm Turtle
    118: (53, 1), #Helmut
    120: (25, 1), #Demon
    123: (32, 1), #Dragon Fly
    124: (64, 7), #Monkey
    125: (41, 2), #Fat Chick
    126: (42, 1), #Fencer
    127: (43, 1), #Fish
    128: (65, 4), #Moth
    129: (94, 1), #Steam
    130: (76, 1), #Rotating Rock
    131: (68, 61), #Blaster PowerUp
    132: (68, 62), #Bouncy PowerUp
    133: (68, 63), #Ice gun PowerUp
    134: (67, 64), #Seek PowerUp
    135: (68, 65), #RF PowerUp
    136: (68, 66), #Toaster PowerUP
    137: (69, 5), #PIN: Left Paddle
    138: (69, 6), #PIN: Right Paddle
    139: (69, 1), #PIN: 500 Bump
    140: (69, 3), #PIN: Carrot Bump
    141: (68, 2), #Apple
    142: (68, 3), #Banana
    143: (68, 17), #Cherry
    144: (68, 72), #Orange
    145: (68, 75), #Pear
    146: (68, 80), #Pretzel
    147: (68, 82), #Strawberry
    151: (72, 1), #Queen Boss
    152: (96, 5), #Floating Sucker
    153: (14, 1), #Bridge
    154: (68, 49), #Lemon
    155: (68, 51), #Lime
    156: (68, 90), #Thing
    157: (68, 93), #Watermelon
    158: (68, 74), #Peach
    159: (68, 39), #Grapes
    160: (68, 50), #Lettuce
    161: (68, 27), #Eggplant
    162: (68, 24), #Cucumb
    163: (68, 21), #Soft Drink
    164: (68, 76), #Soda Pop
    165: (68, 54), #Milk
    166: (68, 77), #Pie
    167: (68, 13), #Cake
    168: (68, 26), #Donut
    169: (68, 25), #Cupcake
    170: (68, 19), #Chips
    171: (68, 14), #Candy
    172: (58, 20), #Chocbar
    173: (68, 44), #Icecream
    174: (68, 12), #Burger
    175: (68, 78), #Pizza
    176: (68, 33), #Fries
    177: (68, 18), #Chicken Leg
    178: (68, 81), #Sandwich
    179: (68, 89), #Taco
    180: (68, 92), #Weenie
    181: (68, 40), #Ham
    182: (68, 16), #Cheese
    183: (60, 3), #Float Lizard
    184: (64, 6), #Stand Monkey
    190: (74, 2), #Raven
    191: (97, 1), #Tube Turtle
    192: (68, 36 #Gem Ring
    193: (81, 1), #Small Tree
    195: (102, 4), #Uterus
    196: (102, 8), #Crab
    197: (109, 1), #Witch
    198: (77, 2), #Rocket Turtle
    199: (15, 1), #Bubba
    200: (28, 9), #Devil devan boss
    201: (27, 2), #Devan (robot boss)
    202: (75, 4), #Robot (robot boss)
    203: (18, 1), #Carrotus pole
    204: (71, 1), #Psych pole
    205: (29, 1), #Diamondus pole
    209: (48, 1), #Fruit Platform
    210: (11, 1), #Boll Platform
    211: (51, 1), #Grass Platform
    212: (70, 1), #Pink Platform
    213: (84, 1), #Sonic Platform
    214: (92, 1), #Spike Platform
    215: (90, 1), #Spike Boll
    217: (38, 1), #Eva
    220: (68, 67), #Gun8 Powerup
    221: (68, 68), #Gun9 Powerup
    223: (91, 1), #3D Spike Boll
    226: (60, 1), #Copter
    228: (68, 88), #Stopwatch
    229: (58, 1), #Jungle Pole
    231: (6, 1), #Big Rock
    232: (5, 1), #Big Box
    235: (83, 3), #Bolly Boss
    236: (17, 1), #Butterfly
    237: (4, 1), #BeeBoy
    241: (101, 7), #Tweedle Boss
    244: (44, 2) #CTF Base + Flag
}
For some events the parameter influences what they look like (warps, platforms) or the event is composed out of several animations (CTF bases, Bolly boss). This is not reflected in the list. I tried to choose the sprite closest to the "idle" animation for each event, but in some cases the in-game version might use a slightly different animation.

Events which have no sprite are obviously excluded.
Stijn

Administrator

Joined: Mar 2001

Posts: 6,965

Stijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to behold

Feb 14, 2010, 04:59 PM
Stijn is offline
Reply With Quote
Quote:
Originally Posted by Stijn View Post
Python tileset renderer: http://www.jazz2online.com/junk/sour...ile=tileset.py

Can be optimized (it doesn't cache tiles, for example), but I thought, why not put it up here.
Python episode (J2E) image renderer: http://www.jazz2online.com/junk/sour...ile=episode.py
Stijn

Administrator

Joined: Mar 2001

Posts: 6,965

Stijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to behold

Feb 15, 2010, 01:00 PM
Stijn is offline
Reply With Quote
And the PHP port: http://www.jazz2online.com/junk/sour...ss.Episode.php
Stijn

Administrator

Joined: Mar 2001

Posts: 6,965

Stijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to beholdStijn is a splendid one to behold

Feb 22, 2010, 01:17 PM
Stijn is offline
Reply With Quote
Aaand a J2A renderer (for all those myriads of custom animation files out there):

http://www.jazz2online.com/junk/source.php?file=j2a.py

also needs http://www.jazz2online.com/junk/source.php?file=misc.py

The sprite drawing algorithm is a bit quirky, but seems to work and is reasonably fast.
djazz

JCF Member

Joined: Feb 2009

Posts: 257

djazz is OFF DA CHARTdjazz is OFF DA CHARTdjazz is OFF DA CHART

Mar 1, 2010, 10:38 AM
djazz is offline
Reply With Quote
Quote:
Originally Posted by Unknown Rabbit View Post
Does anyone know if Data3 in .j2t files is read by JCS, or only JJ2?
I think JJ2 only, because when I use my Tileset Compiler, all looks fine in JCS, but weird black colors (#000) on transparent areas of tiles in JJ2. I think this has to do with the Data3 (Transparency Mask)
__________________
WebJCS 2 (new and in progress)
WebJCS 1 (old but complete)
SGIP Simple Games in Progress list
Level Packer v2 - With a GUI!
PHP Tileset Compiler
Violet CLM

JCF Éminence Grise

Joined: Mar 2001

Posts: 11,047

Violet CLM has disabled reputation

Mar 1, 2010, 04:53 PM
Violet CLM is offline
Reply With Quote
Sweet! Thanks.
__________________
Jojo

JCF Member

Joined: Dec 2006

Posts: 38

Jojo is doing well so far

Mar 8, 2010, 11:35 AM
Jojo is offline
Reply With Quote
Hello Stijn and others,
you may want to have a look at modplug's source code (load_j2b.cpp) for a deeper insight into the J2B format. Everything is working correctly (apart from restart position, I have absolutely no clue where this could be hidden in the file, apparently it's hardcoded?) and I hope that there are at least a few helpful code comments in there. This is certainly more helpful than Dr. Eggman's findings (no offence).
Jojo

JCF Member

Joined: Dec 2006

Posts: 38

Jojo is doing well so far

Mar 8, 2010, 11:35 AM
Jojo is offline
Reply With Quote
Oh and if you have any specific questions about the J2B format (EDIT: Although I see that you pretty much covered most of it already), just let me know. I feel like I could answer most of the stuff. =)

Last edited by Jojo; Mar 8, 2010 at 11:51 AM. Reason: edit
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is On

Forum Jump

All times are GMT -8. The time now is 02:58 PM.