package javaforce.utils;
/**
* Desc : Lists chunks in a 3DS file
*
* Usage : java -cp /usr/share/java/javaforce.jar javaforce.utils.list3ds
* filein.3ds
*
*/
import java.io.*;
public class list3ds {
static FileInputStream fi;
static String str;
static void readstr() throws Exception {
str = "";
char ch;
while (fi.available() > 0) {
ch = (char) fi.read();
if (ch == 0) {
return;
}
str += ch;
}
str = "";
}
private static final int _3DS_FLG_TENSION = 0x01;
private static final int _3DS_FLG_CONTINUITY = 0x02;
private static final int _3DS_FLG_BIAS = 0x04;
private static final int _3DS_FLG_EASE_TO = 0x08;
private static final int _3DS_FLG_EASE_FROM = 0x10;
static void readx(boolean four) throws Exception {
int u16;
int u32;
float f;
float f4[] = new float[4];
int cnt;
u16 = readuint16(fi);
System.out.format(" flgs = %d\n", u16);
u32 = readuint32(fi);
System.out.format(" res1 = %d\n", u32);
u32 = readuint32(fi);
System.out.format(" res2 = %d\n", u32);
cnt = readuint32(fi);
System.out.format(" keys = %d\n", cnt);
while (cnt-- > 0) {
System.out.format(" tcb {\n");
u32 = readuint32(fi);
System.out.format(" frame = %d\n", u32);
u16 = readuint16(fi);
System.out.format(" flgs = %d\n", u16);
if ((u16 & _3DS_FLG_TENSION) != 0) {
f = readfloat(fi);
System.out.format(" tension = %f\n", f);
}
if ((u16 & _3DS_FLG_CONTINUITY) != 0) {
f = readfloat(fi);
System.out.format(" continuity = %f\n", f);
}
if ((u16 & _3DS_FLG_BIAS) != 0) {
f = readfloat(fi);
System.out.format(" bias = %f\n", f);
}
if ((u16 & _3DS_FLG_EASE_TO) != 0) {
f = readfloat(fi);
System.out.format(" ease to = %f\n", f);
}
if ((u16 & _3DS_FLG_EASE_FROM) != 0) {
f = readfloat(fi);
System.out.format(" ease from = %f\n", f);
}
System.out.format(" };\n");
if (four) {
f4[0] = readfloat(fi);
f4[1] = readfloat(fi);
f4[2] = readfloat(fi);
f4[3] = readfloat(fi);
System.out.format(" angle : %f : axis : %f : %f : %f\n", f4[0], f4[1], f4[2], f4[4]);
} else {
f4[0] = readfloat(fi);
f4[1] = readfloat(fi);
f4[2] = readfloat(fi);
System.out.format(" coords : %f : %f : %f\n", f4[0], f4[1], f4[2]);
}
}
}
public static void main(String args[]) {
int id, u16;
int len, u32;
int pos = 0, skip;
int cnt;
float f[] = new float[4];
int i16[] = new int[4];
if (args.length != 1) {
System.out.println("Usage : list3ds filein.3ds");
System.exit(0);
}
try {
fi = new FileInputStream(args[0]);
int fs = fi.available();
System.out.format("list3ds : %s : filesize=%08x\n", args[0], fs);
while (fi.available() > 0) {
id = readuint16(fi);
len = readuint32(fi);
skip = 0;
switch (id) {
case 0x0000:
System.out.format("%08x:%08x:%04x : EOF Chunk\n", pos, len, id);
pos += 6;
return;
case 0x4d4d:
System.out.format("%08x:%08x:%04x : Main Chunk\n", pos, len, id);
pos += 6;
break;
case 0x3d3d:
System.out.format("%08x:%08x:%04x : Mesh Chunk\n", pos, len, id);
pos += 6;
break;
case 0xafff:
System.out.format("%08x:%08x:%04x : Material Chunk\n", pos, len, id);
pos += 6;
break;
case 0xa000:
System.out.format("%08x:%08x:%04x : Material : Name Chunk\n", pos, len, id);
readstr();
System.out.format(" Name = %s\n", str);
pos += len;
break;
case 0xa200:
System.out.format("%08x:%08x:%04x : Texture Chunk\n", pos, len, id);
pos += 6;
break;
case 0xa300:
readstr();
System.out.format("%08x:%08x:%04x : Texture Filename Chunk\n FileName = %s\n", pos, len, id, str);
pos += 6 + str.length() + 1;
break;
case 0xb000:
System.out.format("%08x:%08x:%04x : KeyFrame Chunk\n", pos, len, id);
pos += 6;
break;
case 0xb00a:
System.out.format("%08x:%08x:%04x : KeyFrame Header Chunk\n", pos, len, id);
u16 = readuint16(fi);
System.out.format(" revision = %d\n", u16);
readstr();
System.out.format(" name = %s\n", str);
u32 = readuint32(fi);
System.out.format(" frames = %d\n", u32);
pos += 6 + 2 + str.length() + 1 + 4;
break;
case 0xb008:
System.out.format("%08x:%08x:%04x : KeyFrame Segment Chunk\n", pos, len, id);
u32 = readuint32(fi);
System.out.format(" start = %d\n", u32);
u32 = readuint32(fi);
System.out.format(" stop = %d\n", u32);
pos += 6 + 4 + 4;
break;
case 0xb009:
System.out.format("%08x:%08x:%04x : KeyFrame Current Time Chunk\n", pos, len, id);
u32 = readuint32(fi);
System.out.format(" curtime = %d\n", u32);
pos += 6 + 4;
break;
case 0xb002:
System.out.format("%08x:%08x:%04x : KeyFrame Object Node Tag Chunk\n", pos, len, id);
pos += 6;
break;
case 0xb010:
System.out.format("%08x:%08x:%04x : KeyFrame Object Node Tag : Node Header Chunk\n", pos, len, id);
readstr();
System.out.format(" name = %s\n", str);
u16 = readuint16(fi);
System.out.format(" flgs1 = %d\n", u16);
u16 = readuint16(fi);
System.out.format(" flgs2 = %d\n", u16);
u16 = readuint16(fi);
System.out.format(" parent id = %d\n", u16);
pos += len;
skip = len - (6 + str.length() + 1 + 2 + 2 + 2);
break;
case 0xb013:
System.out.format("%08x:%08x:%04x : KeyFrame Object Node Tag : Pivot Chunk\n", pos, len, id);
f[0] = readfloat(fi);
f[1] = readfloat(fi);
f[2] = readfloat(fi);
System.out.format(" Pivot = %f : %f : %f\n", f[0], f[1], f[2]);
pos += 6 + 4 * 3;
break;
case 0xb020:
System.out.format("%08x:%08x:%04x : KeyFrame Object Node Tag : Pos Track Chunk\n", pos, len, id);
readx(false);
pos += len;
break;
case 0xb021:
System.out.format("%08x:%08x:%04x : KeyFrame Object Node Tag : Rotate Track Chunk\n", pos, len, id);
readx(true);
pos += len;
break;
case 0xb022:
System.out.format("%08x:%08x:%04x : KeyFrame Object Node Tag : Scale Track Chunk\n", pos, len, id);
readx(false);
pos += len;
break;
case 0xb030:
System.out.format("%08x:%08x:%04x : KeyFrame Object Node Tag : Node ID Chunk\n", pos, len, id);
u16 = readuint16(fi);
System.out.format(" node id = %d\n", u16);
pos += len;
skip = len - (6 + 2);
break;
case 0x4000:
readstr();
System.out.format("%08x:%08x:%04x : Object Chunk\n Name = %s\n", pos, len, id, str);
pos += 6 + str.length() + 1;
break;
case 0x4100:
System.out.format("%08x:%08x:%04x : Triangular Chunk\n", pos, len, id);
pos += 6;
break;
case 0x4110:
u16 = readuint16(fi);
System.out.format("%08x:%08x:%04x : Vertex Chunk\n Count = %d\n", pos, len, id, u16);
pos += len;
cnt = 0;
while (u16-- > 0) {
f[0] = readfloat(fi);
f[1] = readfloat(fi);
f[2] = readfloat(fi);
System.out.format(" %3d : %f : %f : %f\n", cnt++, f[0], f[1], f[2]);
}
break;
case 0x4120:
u16 = readuint16(fi);
System.out.format("%08x:%08x:%04x : Points Chunk\n Count = %d\n", pos, len, id, u16);
pos += 6 + 2 + (u16 * 2 * 4);
cnt = 0;
while (u16-- > 0) {
i16[0] = readuint16(fi);
i16[1] = readuint16(fi);
i16[2] = readuint16(fi);
i16[3] = readuint16(fi);
System.out.format(" %3d : %d : %d : %d : flgs = x%x\n", cnt++, i16[0], i16[1], i16[2], i16[3]);
}
break;
case 0x4130:
System.out.format("%08x:%08x:%04x : Object Material Name Chunk\n", pos, len, id);
readstr();
System.out.format(" Name = %s\n", str);
pos += len;
skip = len - (6 + str.length() + 1);
break;
case 0x4140:
u16 = readuint16(fi);
System.out.format("%08x:%08x:%04x : Texture Vertex Chunk\n Count = %d\n", pos, len, id, u16);
pos += len;
cnt = 0;
while (u16-- > 0) {
f[0] = readfloat(fi);
f[1] = readfloat(fi);
System.out.format(" %3d : %f : %f\n", cnt++, f[0], f[1]);
}
break;
default:
System.out.format("%08x:%08x:%04x : Unknown Chunk\n", pos, len, id);
pos += len;
skip = len - (6);
}
if (skip > 0) {
fi.skip(skip);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static int readuint16(InputStream in) {
byte data[] = new byte[2];
try {
if (in.read(data) != 2) {
return -1;
}
} catch (Exception e) {
e.printStackTrace();
return -1;
}
int ret;
ret = (int) data[0] & 0xff;
ret += ((int) data[1] & 0xff) << 8;
return ret;
}
public static int readuint32(InputStream in) {
byte data[] = new byte[4];
try {
if (in.read(data) != 4) {
return -1;
}
} catch (Exception e) {
e.printStackTrace();
return -1;
}
int ret;
ret = (int) data[0] & 0xff;
ret += ((int) data[1] & 0xff) << 8;
ret += ((int) data[2] & 0xff) << 16;
ret += ((int) data[3] & 0xff) << 24;
return ret;
}
public static float readfloat(InputStream in) {
int bits = readuint32(in);
return Float.intBitsToFloat(bits);
}
}