aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcomex <comexk@gmail.com>2009-03-01 15:57:14 -0500
committercomex <comexk@gmail.com>2009-03-01 15:57:14 -0500
commit0c44369b84b29a8b11121c718660d9a8ad4085ec (patch)
tree9a0a92f7a79cf0b8f609f193c1fa4ec9ce32807b
parent86cc61b37614443d1af703030fc12f771fddc179 (diff)
parent9b7a102e4b8747c3c8d7f68848785425a45c27b4 (diff)
Merge branch 'master' of git://github.com/SquidMan/benzin
Diffstat (limited to '')
-rw-r--r--BenzinWindblowsInstructions.txt30
-rw-r--r--brlan.c124
-rw-r--r--brlyt.h2
-rw-r--r--ethyl.py23
-rw-r--r--general.h8
-rw-r--r--parse-brlyt.py312
-rw-r--r--sample.xmlan36
7 files changed, 316 insertions, 219 deletions
diff --git a/BenzinWindblowsInstructions.txt b/BenzinWindblowsInstructions.txt
new file mode 100644
index 0000000..70116a3
--- /dev/null
+++ b/BenzinWindblowsInstructions.txt
@@ -0,0 +1,30 @@
+GUIDE TO COMPILING BENZIN FOR WINDOWS
+==================================================
+
+In order to compile Benzin you require:
+1) Cygwin with the GCC package
+2) MiniXML 2.5
+3) Benzin source code
+4) Half a brain.
+
+First off, let's make sure we have all the above.
+ 1) Go download Cygwin from http://www.cygwin.com/ (Direct Download Link: http://www.cygwin.com/setup.exe )
+ 2) Now run setup.exe and when it gets to the Select Packages screen, click the [+] next to Devel. Scroll down to gcc, and click on the word `Skip'. It should change to some version number. Click next. Do the same for make.
+ 3) Cygwin will most likely take a while to install.
+ 4) Ok, Cygwin is now installed, let's go get MiniXML 2.5
+ 5) Go to http://www.minixml.org/software.php and choose mxml-2.5.tar.gz. Once you have that, extract it to C:\cygwin\ (it should create the mxml-2.5 directory)
+ 6) Now, go open Cygwin (it should have a shortcut on the desktop). If you are running Vista, you must open it as an administrator.
+ 7) Type `cd /mxml-2.5/'
+ 8) Now type `./configure'. This should do several checks, and get everything ready.
+ 9) Type `make'. A bunch of stuff should appear on screen. Just ignore it.
+10) Now type `make install'. More stuff should pop up on screen. Ignore that too.
+11) Now before we can do any more, we have to go get Benzin. Get it however you wish (through the git, download a zip from the github page, etc.). Put it all in the benzin folder inside C:\cygwin\. (Should end up as C:\cygwin\benzin\)
+12) Copy all the .o files from the mxml-2.5 directory into the benzin directory.
+13) Now open up Makefile in WordPad (NOT NotePad, NotePad cannot handle UNIX style newlines)
+14) Add the following line before the `LIBS = ' line: `MXMLOBJS = mxml-*.o'.
+15) Now add the following to the END of the `LIBS = ' line (make sure to put a space): `$(MXMLOBJS)'
+16) Now go back to the Cygwin window. Type in `cd /benzin/'.
+17) Type `make'
+18) A file called benzin.exe should have been created. That is Benzin all ready for use. You must either use it in the Cygwin window, or you must copy the cygwin1.dll file from C:\cygwin to wherever you put benzin.exe, and then run it in a command prompt.
+19) ????
+20) PROFIT!!!!
diff --git a/brlan.c b/brlan.c
index 228744d..1878f7f 100644
--- a/brlan.c
+++ b/brlan.c
@@ -13,6 +13,7 @@
#include <ctype.h>
#include <mxml.h>
+#include "general.h"
#include "memfile.h"
#include "types.h"
#include "brlan.h"
@@ -31,6 +32,7 @@ fourcc tag_FourCCs[] = { "RLPA", "RLTS", "RLVI", "RLVC", "RLMC", "RLTP" };
char tag_types_list[15][24];
static size_t BRLAN_fileoffset = 0;
+FILE* xmlanout;
static void BRLAN_ReadDataFromMemoryX(void* destination, void* input, size_t size)
{
@@ -70,10 +72,15 @@ static void DisplayTagData(tag_data data, int z)
u32 p1 = be32(data.part1);
u32 p2 = be32(data.part2);
u32 p3 = be32(data.part3);
+#ifndef OLD_BRLAN_OUTSTYLE
+ printf("\t\t\t<triplet>\n\t\t\t\t<frame>%.6f</frame>\n\t\t\t\t<value>%.6f</value>\n\t\t\t\t<blend>%.6f</blend>\n\t\t\t</triplet>\n", *(f32*)(&p1), *(f32*)(&p2), *(f32*)(&p3));
+#endif // OLD_BRLAN_OUTSTYLE
+#ifdef OLD_BRLAN_OUTSTYLE
printf(" Triplet %d:\n", z);
printf(" Frame number: %f\n", *(f32*)(&p1));
printf(" Value: %f\n", *(f32*)(&p2));
printf(" Interpolation Value: %f\n", *(f32*)(&p3));
+#endif // OLD_BRLAN_OUTSTYLE
}
static int FourCCsMatch(fourcc cc1, fourcc cc2)
@@ -99,7 +106,9 @@ static void DisplayTagInformation(int idx, tag_header* heads, tag_entry** entrie
tag_entry* entries = entriesx[idx];
tag_entryinfo* entryinfos = entryinfosx[idx];
tag_data** datas = datasxx[idx];
+ int i, z;
+#ifdef OLD_BRLAN_OUTSTYLE
printf(" Number of entries: %u\n", head.entry_count);
// Why should we show padding? It's 0 every single time.
@@ -107,16 +116,21 @@ static void DisplayTagInformation(int idx, tag_header* heads, tag_entry** entrie
printf(" Unk2: %02x\n", head.pad2);
printf(" Unk3: %02x\n", head.pad3); */
- int i, z;
printf(" Entries:\n");
+#endif // OLD_BRLAN_OUTSTYLE
for(i = 0; i < head.entry_count; i++) {
+#ifndef OLD_BRLAN_OUTSTYLE
+ if(be16(entryinfos[i].type) < 16)
+ printf("\t\t<entry type=\"%s\">\n", tag_types_list[be16(entryinfos[i].type)]);
+ else
+ printf("\t\t<entry type=\"%u\">\n", be16(entryinfos[i].type));
+#endif // OLD_BRLAN_OUTSTYLE
+#ifdef OLD_BRLAN_OUTSTYLE
printf(" Entry %u:\n", i);
-// if(FourCCsMatch(head.magic, tag_FourCCs[0]) == 1) {
- if(be16(entryinfos[i].type) < 16)
- printf(" Type: %s (%04x)\n", tag_types_list[be16(entryinfos[i].type)], be16(entryinfos[i].type));
- else
- printf(" Type: Unknown (%04x)\n", be16(entryinfos[i].type));
-// }
+ if(be16(entryinfos[i].type) < 16)
+ printf(" Type: %s (%04x)\n", tag_types_list[be16(entryinfos[i].type)], be16(entryinfos[i].type));
+ else
+ printf(" Type: Unknown (%04x)\n", be16(entryinfos[i].type));
// User doesn't need to know the offset
// printf(" Offset: %lu\n", be32(entries[i].offset));
@@ -126,8 +140,12 @@ static void DisplayTagInformation(int idx, tag_header* heads, tag_entry** entrie
printf(" Unk3: %08x\n", be32(entryinfos[i].unk2)); */
printf(" Triplet Count: %u\n", be16(entryinfos[i].coord_count));
printf(" Triplets:\n");
+#endif // OLD_BRLAN_OUTSTYLE
for(z = 0; z < be16(entryinfos[i].coord_count); z++)
DisplayTagData(datas[i][z], z);
+#ifndef OLD_BRLAN_OUTSTYLE
+ printf("\t\t</entry>\n");
+#endif // OLD_BRLAN_OUTSTYLE
}
}
@@ -178,6 +196,9 @@ void parse_brlan(char* filename)
printf("Error! Couldn't open %s!\n", filename);
exit(1);
}
+#ifndef OLD_BRLAN_OUTSTYLE
+ xmlanout = fopen("testout.xmlan", "wb+");
+#endif // OLD_BRLAN_OUTSTYLE
int i;
for(i = 0; i < 16; i++)
memset(tag_types_list[i], 0, 24);
@@ -297,6 +318,11 @@ void parse_brlan(char* filename)
dbgprintf("looping.\n");
}
+#ifndef OLD_BRLAN_OUTSTYLE
+ printf("<?xml version=\"1.0\"?>\n" \
+ "<xmlan framesize=\"%lu\">\n", be16(pai1_header.framesize));
+#endif // OLD_BRLAN_OUTSTYLE
+#ifdef OLD_BRLAN_OUTSTYLE
printf("Parsed BRLAN! Information:\n");
printf("Main header:\n");
printf(" Magic: %c%c%c%c\n", header.magic[0], header.magic[1], header.magic[2], header.magic[3]);
@@ -321,22 +347,39 @@ void parse_brlan(char* filename)
// printf(" Offset to Entries: 0x%08lx\n", be32(pai1_header.entry_offset));
printf("\nBRLAN entries:");
+#endif // OLD_BRLAN_OUTSTYLE
intag_cnt = 0;
for(i = 0; i < tagcount; i++) {
+#ifndef OLD_BRLAN_OUTSTYLE
+ printf("\t<tag ");
+ if(strlen(tag_entries[i].name) > 0)
+ printf("name=\"%s\" ", tag_entries[i].name);
+ printf("type=\"%c%c%c%c\" format=\"%s\">\n", CCs[i][0], CCs[i][1], CCs[i][2], CCs[i][3], be32(tag_entries[i].flags) == 0x01000000 ? "Normal" : "Strange");
+#endif // OLD_BRLAN_OUTSTYLE
+
+#ifdef OLD_BRLAN_OUTSTYLE
printf("\n Entry %u:\n", i);
printf(" Name: %s\n", tag_entries[i].name);
printf(" Type: %s\n", be32(tag_entries[i].flags) == 0x01000000 ? "Normal" : "Strange");
// Not important to user, why bother.
// printf(" Animation Header Length: %lu\n", be32(tag_entries[i].anim_header_len));
printf(" FourCC: %c%c%c%c\n", CCs[i][0], CCs[i][1], CCs[i][2], CCs[i][3]);
+#endif // OLD_BRLAN_OUTSTYLE
if(FourCCInList(CCs[i]) == 1) {
- dbgprintf("found tag. cnt %d.\n", intag_cnt);
DisplayTagInformation(intag_cnt, intag_heads, intag_entries, intag_entryinfos, intag_datas);
intag_cnt++;
}else{
+#ifdef OLD_BRLAN_OUTSTYLE
printf(" Sorry, this type is currently unknown.\n");
+#endif // OLD_BRLAN_OUTSTYLE
}
+#ifndef OLD_BRLAN_OUTSTYLE
+ printf("\t</tag>\n");
+#endif // OLD_BRLAN_OUTSTYLE
}
+#ifndef OLD_BRLAN_OUTSTYLE
+ printf("</xmlan>\n");
+#endif // OLD_BRLAN_OUTSTYLE
free(brlan_file);
fclose(fp);
}
@@ -372,11 +415,8 @@ void WriteBRLANTagData(tag_data* data, u16 count, FILE* fp)
tag_data writedata;
int i;
for(i = 0; i < count; i++) {
- printf("%08x -> %08x\n", data[i].part1, be32(data[i].part1));
writedata.part1 = be32(data[i].part1);
- printf("%08x -> %08x\n", data[i].part2, be32(data[i].part2));
writedata.part2 = be32(data[i].part2);
- printf("%08x -> %08x\n\n", data[i].part3, be32(data[i].part3));
writedata.part3 = be32(data[i].part3);
fwrite(&writedata, sizeof(tag_data), 1, fp);
}
@@ -421,14 +461,15 @@ u32 create_entries_from_xml(mxml_node_t *tree, mxml_node_t *node, brlan_entry *e
else
data = (tag_data**)realloc(data, sizeof(tag_data*) * head->entry_count);
data[x] = NULL;
- tempnode = mxmlFindElement(subnode, tree, "type", NULL, NULL, MXML_DESCEND);
- if(tempnode == NULL) {
- printf("Couldn't find attribute \"type\"!\n");
- exit(1);
- }
memset(temp, 0, 256);
memset(temp2, 0, 256);
- get_value(tempnode, temp, 24);
+ if(mxmlElementGetAttr(subnode, "type") != NULL)
+ strcpy(temp, mxmlElementGetAttr(subnode, "type"));
+ else{
+ printf("No type attribute found!\nSkipping this entry!\n");
+ head->entry_count--;
+ continue;
+ }
for(i = 0; i < strlen(temp); i++)
temp2[i] = toupper(temp[i]);
for(i = 0; (i < 16) && (strcmp(temp3[i - 1], temp2) != 0); i++);
@@ -460,9 +501,9 @@ u32 create_entries_from_xml(mxml_node_t *tree, mxml_node_t *node, brlan_entry *e
}
get_value(tempnode, temp, 256);
*(f32*)(&(data[x][i].part2)) = atof(temp);
- tempnode = mxmlFindElement(subsubnode, subsubnode, "interpolation", NULL, NULL, MXML_DESCEND);
+ tempnode = mxmlFindElement(subsubnode, subsubnode, "blend", NULL, NULL, MXML_DESCEND);
if(tempnode == NULL) {
- printf("Couldn't find attribute \"interpolation\"!\n");
+ printf("Couldn't find attribute \"blend\"!\n");
exit(1);
}
get_value(tempnode, temp, 256);
@@ -504,7 +545,6 @@ u32 create_entries_from_xml(mxml_node_t *tree, mxml_node_t *node, brlan_entry *e
free(data);
fclose(fp);
remove("temp.blan");
- printf("All done.\n");
return filesz;
}
@@ -512,21 +552,18 @@ void create_tag_from_xml(mxml_node_t *tree, mxml_node_t *node, u8** tagblob, u32
{
tag_header head;
brlan_entry entr;
- mxml_node_t *tempnode = mxmlFindElement(node, tree, "name", NULL, NULL, MXML_DESCEND);
- if(tempnode == NULL) {
- printf("Couldn't find attribute \"name\"!\n");
- exit(1);
- }
- memset(entr.name, 0, 20);
char temp[256];
- get_value(tempnode, temp, 20);
- strncpy(entr.name, temp, 20);
- tempnode = mxmlFindElement(node, tree, "magic", NULL, NULL, MXML_DESCEND);
- if(tempnode == NULL) {
- printf("Couldn't find attribute \"magic\"!\n");
+ memset(entr.name, 0, 20);
+ if(mxmlElementGetAttr(node, "name") != NULL)
+ strcpy(entr.name, mxmlElementGetAttr(node, "name"));
+ else{
+ }
+ if(mxmlElementGetAttr(node, "type") != NULL)
+ strcpy(temp, mxmlElementGetAttr(node, "type"));
+ else{
+ printf("No type attribute found!\nQuitting!\n");
exit(1);
}
- get_value(tempnode, temp, 5);
head.magic[0] = temp[0];
head.magic[1] = temp[1];
head.magic[2] = temp[2];
@@ -534,16 +571,15 @@ void create_tag_from_xml(mxml_node_t *tree, mxml_node_t *node, u8** tagblob, u32
head.pad1 = 0;
head.pad2 = 0;
head.pad3 = 0;
- tempnode = mxmlFindElement(node, tree, "type", NULL, NULL, MXML_DESCEND);
- if(tempnode == NULL) {
- printf("Couldn't find attribute \"type\"!\n");
+ if(mxmlElementGetAttr(node, "format") != NULL)
+ strcpy(temp, mxmlElementGetAttr(node, "format"));
+ else{
+ printf("No format attribute found!\nQuitting!\n");
exit(1);
}
int x;
- get_value(tempnode, temp, 256);
for(x = 0; x < strlen(temp); x++)
temp[x] = toupper(temp[x]);
- printf("%s\n", temp);
if(strcmp(temp, "NORMAL") == 0)
entr.flags = 0x01000000;
else if(strcmp(temp, "STRANGE") == 0)
@@ -645,12 +681,12 @@ void write_brlan(char *infile, char* outfile)
paihead.magic[3] = '1';
paihead.size = 0;
char temp[256];
- mxml_node_t *tempnode = mxmlFindElement(tree, tree, "framesize", NULL, NULL, MXML_DESCEND);
- if(tempnode == NULL) {
- printf("Couldn't find attribute \"framesize\"!\n");
- exit(1);
- }
- get_value(tempnode, temp, 256);
+ if(mxmlElementGetAttr(tree, "framesize") != NULL)
+ strcpy(temp, mxmlElementGetAttr(tree, "framesize"));
+ else{
+ printf("No framesize attribute found!\nDefaulting to 20.");
+ strcpy(temp, "20");
+ }
paihead.framesize = atoi(temp);
paihead.flags = 1;
paihead.unk1 = 0;
@@ -684,7 +720,7 @@ void write_brlan(char *infile, char* outfile)
void make_brlan(char* infile, char* outfile)
{
- printf("Starting xmlan file @ %s parsing.\n", infile);
+ printf("Parsing XMLAN @ %s.\n", infile);
write_brlan(infile, outfile);
}
diff --git a/brlyt.h b/brlyt.h
index 6f224a2..57c9bc7 100644
--- a/brlyt.h
+++ b/brlyt.h
@@ -71,4 +71,4 @@ typedef struct
void parse_brlyt(char *filename);
void make_brlyt(char* infile, char* outfile);
-#endif //BRLYT_H_ \ No newline at end of file
+#endif //BRLYT_H_
diff --git a/ethyl.py b/ethyl.py
index 0114aee..c57bb8a 100644
--- a/ethyl.py
+++ b/ethyl.py
@@ -142,9 +142,10 @@ for (dname, definition) in formats.items():
else:
df.append((typ, name, default))
formats[dname] = df, etc, etcn
-
+
# Dumb pretty printer
def my_repr(b, start=''):
+ '''scrap this shit and implement new one eventually'''
special = lambda x: type(x) not in (int, str, unicode)
if type(b) == dict:
if len(filter(special, b.values())) == 0:
@@ -155,16 +156,16 @@ def my_repr(b, start=''):
rep += ', '
else:
f = True
- rep += '%s: %s' % (str(a), my_repr(b[a]))
+ rep += '"%s": %s' % (str(a), my_repr(b[a]))
rep += ' }'
else:
rep = '{\n'
for a in sorted(b.keys()):
c = b[a]
if type(c) in (dict, list):
- rep += '%s:\n%s\n' % (str(a), my_repr(c, ' '))
+ rep += '"%s":\n%s,\n' % (str(a), my_repr(c, ' '))
else:
- rep += '%s: %s\n' % ( str(a), my_repr(c))
+ rep += '"%s": %s,\n' % ( str(a), my_repr(c))
rep += '}'
elif type(b) in (int, long):
rep = hex(b)
@@ -178,8 +179,10 @@ def my_repr(b, start=''):
else:
rep = repr(b)
return re.sub(re.compile('^', re.M), start, rep)
+
def pr_dict(*args):
print my_repr(*args)
+
types = {
'u8': 'B',
'u16': 'H',
@@ -196,6 +199,7 @@ types = {
'bool': 'c',
'char': 'c',
}
+
def parse_var(pos, typ, chunk):
if not types.has_key(typ):
raise Exception('What\'s a %s?' % typ)
@@ -209,15 +213,18 @@ def nullterm(str_plus):
return str_plus[:z]
else:
return str_plus
+
def unnullterm(var, size):
if len(var) > size:
raise Exception('unnullterm: "%s" too long' % var)
return var.ljust(size, '\0')
+
def untv(name):
#assert '\0' not in name
lex = len(name) + 16
lex -= lex % 16
return name.ljust(lex, '\0')
+
def parse_data(chunk, definition, prefix=None, start=0):
df, etc, etcn = formats[definition]
#print df, repr(definition)
@@ -264,10 +271,12 @@ def parse_data(chunk, definition, prefix=None, start=0):
ret = ret['_']
return (ret, pos) if etcn else ret
+
def unparse_var(typ, var):
if not types.has_key(typ):
raise Exception('What\'s a %s?' % typ)
return struct.pack('>' + types[typ], var)
+
def unparse_data(vars, definition, prefix=None):
df, etc, etcn = formats[definition]
ret = ''
@@ -308,6 +317,7 @@ def unparse_data(vars, definition, prefix=None):
for v in var:
ret += unparse_var(typ, v)
return ret
+
def iff_to_chunks(z):
pos = 0
chunks = []
@@ -320,6 +330,7 @@ def iff_to_chunks(z):
pos += length
chunks.append((cc, data))
return chunks
+
def bit_extract(num, start, end=None):
if end is None:
end = start
@@ -327,12 +338,14 @@ def bit_extract(num, start, end=None):
ret = (num & mask) >> (31 - end)
return ret
+
def bit_place(num, start, end=None):
# Just for sanity
if end is None:
end = start
assert num <= 2**(end - start)
return num << (31 - end)
+
def get_array(chunk, startpos, array_size, item_size, item_type=None):
ar = []
pos = startpos
@@ -341,6 +354,7 @@ def get_array(chunk, startpos, array_size, item_size, item_type=None):
ar.append(get_opt(chunk, pos, True, item_size, item_type)[0])
pos += item_size
return ar, pos
+
def get_opt(chunk, startpos, enabled, size, item_type=None):
if not enabled:
return None, startpos
@@ -376,5 +390,6 @@ def put_opt(var, flags, bit, size, item_type=None):
else:
raise Exception('unhandled')
return ret, flags
+
def i2f(int):
return struct.unpack('>f', struct.pack('>I', int))[0] \ No newline at end of file
diff --git a/general.h b/general.h
index 953764f..8ffb297 100644
--- a/general.h
+++ b/general.h
@@ -9,14 +9,16 @@
#define BENZIN_VERSION_MAJOR 0
#define BENZIN_VERSION_MINOR 1
-#define BENZIN_VERSION_BUILD 200
+#define BENZIN_VERSION_BUILD 327
#define BENZIN_VERSION_OTHER "WIP"
#define USE_BRLAN
//#define USE_BRLYT
-#define DEBUGBRLAN
-#define DEBUGMAIN
+//#define OLD_BRLAN_OUTSTYLE
+
+//#define DEBUGBRLAN
+//#define DEBUGMAIN
//#define DEBUGBRLYT
#define fatal(x) printf(x); exit(1)
diff --git a/parse-brlyt.py b/parse-brlyt.py
index 44a0da0..4001901 100644
--- a/parse-brlyt.py
+++ b/parse-brlyt.py
@@ -1,157 +1,181 @@
import sys, struct, re
from ethyl import *
-if len(sys.argv) != 2:
- print 'Usage: python parse-brlyt.py something.brlyt'
- sys.exit(1)
+def main():
+ if len(sys.argv) != 2:
+ print 'Usage: python parse-brlyt.py something.brlyt'
+ sys.exit(1)
+ f = open(sys.argv[1], 'rb')
+ rlyt = f.read()
+ f.close()
-f = open(sys.argv[1], 'rb')
-rlyt = f.read()
-f.close()
+ assert rlyt[0:8] == 'RLYT\xfe\xff\x00\x08'
+ offs, nel = struct.unpack('>hh', rlyt[0xc:0x10])
+ ch = iff_to_chunks(rlyt[offs:])
-assert rlyt[0:8] == 'RLYT\xfe\xff\x00\x08'
-offs, nel = struct.unpack('>hh', rlyt[0xc:0x10])
-ch = iff_to_chunks(rlyt[offs:])
+ assert len(ch) == nel
-assert len(ch) == nel
-
-indent = 0
-for typ, chunk in ch:
- print ' ' * indent + typ + ' ' + hex(len(chunk))
- vars = None
- if typ in ('pic1', 'pan1', 'bnd1', 'wnd1', 'txt1'):
- vars, pos = parse_data(chunk, 'pane')
- assert chunk[:pos] == unparse_data(vars, 'pane') # for testing
- if typ == 'txt1':
- vars2, pos = parse_data(chunk[pos:], 'text', '~text')
- os = vars2['~text.name_offs'] - 8
- txt = chunk[os:os + vars2['~text.len2']]
- vars2['~text.text'] = unicode(txt, 'utf_16_be').rstrip('\x00')
- vars2['~text.material'] = materials[vars2['~text.mat_off']]
- vars.update(vars2)
- #print vars['~text.cnt2'], len(vars2['~text.text']), len(txt), repr(txt)
- elif typ == 'pic1':
- vars2, pos = parse_data(chunk, 'pic', prefix='~pic', start=pos)
- vars2['~pic.material'] = materials[vars2['~pic.mat_off']]
- vars2['~pic.texcoords'] = []
- for n in xrange(vars2['~pic.num_texcoords']):
- vars2['~pic.texcoords'].append(struct.unpack('>ffffffff', chunk[pos:pos+0x20]))
- pos += 0x20
- assert pos == len(chunk)
- vars.update(vars2)
- elif typ == 'lyt1':
- vars = parse_data(chunk, 'lytheader')
- elif typ == 'grp1':
- vars, pos = parse_data(chunk, 'group')
- vars['subs'] = []
- for n in xrange(vars['numsubs']):
- vars['subs'].append(nullterm(chunk[pos:pos+16]))
- pos += 16
- elif typ in ('txl1', 'fnl1'):
- things = {'txl1': 'textures', 'fnl1': 'files'}[typ]
- vars, pos = parse_data(chunk, 'numoffs')
- vars[things] = []
- pos += vars['offs']
- bpos = pos
- del vars['offs'] # unneeded
- for n in xrange(vars['num']):
- offset, unk = struct.unpack('>II', chunk[pos:pos+8])
- name = nullterm(chunk[offset + bpos:])
- vars[things].append({'name': name, 'unk': unk})
- pos += 8
- if typ == 'txl1':
- textures = vars['textures']
- elif typ == 'mat1':
- vars, pos = parse_data(chunk, 'numoffs')
- vars['materials'] = []
- pos += vars['offs']
- bpos = pos
- del vars['offs']
- materials = []
- for n in xrange(vars['num']):
- offset, = struct.unpack('>I', chunk[pos:pos+4])
- mat, mpos = parse_data(chunk, 'material', start = offset - 8)
- #vars['materials'].append(mat)
- flags = mat['flags']
- materials.append(mat['name'])
- assert mpos == 0x40 + offset - 8
-
-
- #print hex(struct.unpack('>I', chunk[mpos:mpos+4])[0])
-
- # I believe material is:
- # 0x40, followed by
- # 4 * flags[28-31], followed by
-
-
- mat['texref'], mpos = get_array(chunk, mpos, bit_extract(flags, 28, 31), 4, 'texref')
-
- for a in mat['texref']:
- a['tex'] = textures[a['tex_offs']]['name']
-
- # 0x14 * flags[24-27], followed by
-
- mat['ua2'], mpos = get_array(chunk, mpos, bit_extract(flags, 24, 27), 0x14, 'ua2')
-
- # 4*flags[20-23], followed by
-
- mat['ua3'], mpos = get_array(chunk, mpos, bit_extract(flags, 20, 23), 4, '4b')
-
- # Changing ua3 things
- # 1st --> disappears.
- # 2nd --> no visible effect.
- # 3rd --> disappears.
- # 4th --> no visible effect.
-
- # 4 * flags[6]
-
- mat['ua4'], mpos = get_opt(chunk, mpos, bit_extract(flags, 6), 4, '4b')
-
- # 4 * flags[4]
-
- mat['ua5'], mpos = get_opt(chunk, mpos, bit_extract(flags, 4), 4, '4b')
+ indentlevel = 0
+ for typ, chunk in ch:
+ print ' ' * indentlevel + open_paren(typ), #+ ' ' + hex(len(chunk))
+ vars = None
+ if typ in ('pic1', 'pan1', 'bnd1', 'wnd1', 'txt1'):
+ vars, pos = parse_data(chunk, 'pane')
+ assert chunk[:pos] == unparse_data(vars, 'pane') # for testing
+ if typ == 'txt1':
+ vars2, pos = parse_data(chunk[pos:], 'text', '~text')
+ os = vars2['~text.name_offs'] - 8
+ txt = chunk[os:os + vars2['~text.len2']]
+ vars2['~text.text'] = unicode(txt, 'utf_16_be').rstrip('\x00')
+ vars2['~text.material'] = materials[vars2['~text.mat_off']]
+ vars.update(vars2)
+ #print vars['~text.cnt2'], len(vars2['~text.text']), len(txt), repr(txt)
+ elif typ == 'pic1':
+ vars2, pos = parse_data(chunk, 'pic', prefix='~pic', start=pos)
+ vars2['~pic.material'] = materials[vars2['~pic.mat_off']]
+ vars2['~pic.texcoords'] = []
+ for n in xrange(vars2['~pic.num_texcoords']):
+ vars2['~pic.texcoords'].append(struct.unpack('>ffffffff', chunk[pos:pos+0x20]))
+ pos += 0x20
+ assert pos == len(chunk)
+ vars.update(vars2)
+ elif typ == 'lyt1':
+ vars = parse_data(chunk, 'lytheader')
+ elif typ == 'grp1':
+ vars, pos = parse_data(chunk, 'group')
+ vars['subs'] = []
+ for n in xrange(vars['numsubs']):
+ vars['subs'].append(nullterm(chunk[pos:pos+16]))
+ pos += 16
+ elif typ in ('txl1', 'fnl1'):
+ things = {'txl1': 'textures', 'fnl1': 'files'}[typ]
+ vars, pos = parse_data(chunk, 'numoffs')
+ vars[things] = []
+ pos += vars['offs']
+ bpos = pos
+ del vars['offs'] # unneeded
+ for n in xrange(vars['num']):
+ offset, unk = struct.unpack('>II', chunk[pos:pos+8])
+ name = nullterm(chunk[offset + bpos:])
+ vars[things].append({'name': name, 'unk': unk})
+ pos += 8
+ if typ == 'txl1':
+ textures = vars['textures']
+ elif typ == 'mat1':
+ vars, pos = parse_data(chunk, 'numoffs')
+ vars['materials'] = []
+ pos += vars['offs']
+ bpos = pos
+ del vars['offs']
+ materials = []
+ for n in xrange(vars['num']):
+ offset, = struct.unpack('>I', chunk[pos:pos+4])
+ mat, mpos = parse_data(chunk, 'material', start = offset - 8)
+ #vars['materials'].append(mat)
+ flags = mat['flags']
+ materials.append(mat['name'])
+ assert mpos == 0x40 + offset - 8
- # 4 * flags[19]
-
- mat['ua6'], mpos = get_opt(chunk, mpos, bit_extract(flags, 19), 4, '4b')
-
- # 0x14 * flags[17-18]
-
- mat['ua7'], mpos = get_array(chunk, mpos, bit_extract(flags, 17, 18), 0x14, 'ua7')
-
- # 4 * flags[14-16]
-
- mat['ua8'], mpos = get_array(chunk, mpos, bit_extract(flags, 14, 16), 4, '4b')
-
- # 0x10 * flags[9-13]
-
- mat['ua9'], mpos = get_array(chunk, mpos, bit_extract(flags, 9, 13), 0x10, '10b')
-
- # 4 * flags[8], these are bytes btw
-
- mat['uaa'], mpos = get_opt(chunk, mpos, bit_extract(flags, 8), 4, '4b')
-
- # 4 * flags[7]
-
- mat['uab'], mpos = get_opt(chunk, mpos, bit_extract(flags, 7), 4, '4b')
+
+ #print hex(struct.unpack('>I', chunk[mpos:mpos+4])[0])
+
+ # I believe material is:
+ # 0x40, followed by
+ # 4 * flags[28-31], followed by
+
+
+ mat['texref'], mpos = get_array(chunk, mpos, bit_extract(flags, 28, 31), 4, 'texref')
+
+ for a in mat['texref']:
+ a['tex'] = textures[a['tex_offs']]['name']
+
+ # 0x14 * flags[24-27], followed by
+
+ mat['ua2'], mpos = get_array(chunk, mpos, bit_extract(flags, 24, 27), 0x14, 'ua2')
+
+ # 4*flags[20-23], followed by
+
+ mat['ua3'], mpos = get_array(chunk, mpos, bit_extract(flags, 20, 23), 4, '4b')
+
+ # Changing ua3 things
+ # 1st --> disappears.
+ # 2nd --> no visible effect.
+ # 3rd --> disappears.
+ # 4th --> no visible effect.
+
+ # 4 * flags[6]
+
+ mat['ua4'], mpos = get_opt(chunk, mpos, bit_extract(flags, 6), 4, '4b')
+
+ # 4 * flags[4]
+
+ mat['ua5'], mpos = get_opt(chunk, mpos, bit_extract(flags, 4), 4, '4b')
+
+ # 4 * flags[19]
+
+ mat['ua6'], mpos = get_opt(chunk, mpos, bit_extract(flags, 19), 4, '4b')
+
+ # 0x14 * flags[17-18]
+
+ mat['ua7'], mpos = get_array(chunk, mpos, bit_extract(flags, 17, 18), 0x14, 'ua7')
+
+ # 4 * flags[14-16]
+
+ mat['ua8'], mpos = get_array(chunk, mpos, bit_extract(flags, 14, 16), 4, '4b')
+
+ # 0x10 * flags[9-13]
+
+ mat['ua9'], mpos = get_array(chunk, mpos, bit_extract(flags, 9, 13), 0x10, '10b')
+
+ # 4 * flags[8], these are bytes btw
+
+ mat['uaa'], mpos = get_opt(chunk, mpos, bit_extract(flags, 8), 4, '4b')
+
+ # 4 * flags[7]
+
+ mat['uab'], mpos = get_opt(chunk, mpos, bit_extract(flags, 7), 4, '4b')
+
+ if n < vars['num'] - 1:
+ next_offset, = struct.unpack('>I', chunk[pos+4:pos+8])
+ if next_offset - 8 != mpos:
+ mat['~_insane'] = next_offset - 8 - mpos # Extra shit we didn't parse :(
- if n < vars['num'] - 1:
- next_offset, = struct.unpack('>I', chunk[pos+4:pos+8])
- if next_offset - 8 != mpos:
- mat['~_insane'] = next_offset - 8 - mpos # Extra shit we didn't parse :(
+ mat['unk_bit_5'] = bit_extract(flags, 5)
+ mat['unk_bits_0_3'] = bit_extract(flags, 0, 3) # Overwritten by stuff
- mat['unk_bit_5'] = bit_extract(flags, 5)
- mat['unk_bits_0_3'] = bit_extract(flags, 0, 3) # Overwritten by stuff
+ vars['materials'].append(mat)
+ pos += 4
+ elif typ in ('grs1', 'pas1'):
+ indentlevel += 1
+ elif typ in ('gre1', 'pae1'):
+ indentlevel -= 1
+ else:
+ print 'Unhandled type %s' % typ
+ print repr(chunk)
- vars['materials'].append(mat)
- pos += 4
- elif typ in ('grs1', 'pas1'):
- indent += 1
+ if vars: pr_dict(vars, ' ' * indentlevel + ' ')
+ print close_paren(typ, indentlevel)
+ #print hex(len(ch))
+
+def open_paren(typ):
+ if typ in ('grs1', 'pas1'):
+ return "'" + typ + "'"
elif typ in ('gre1', 'pae1'):
- indent -= 1
+ return "'" + typ + "'"
else:
- print 'Unhandled type %s' % typ
- print repr(chunk)
- if vars: pr_dict(vars, ' ' * indent + ' ')
-#print hex(len(ch))
+ return "('" + typ + "',\n"
+
+def close_paren(typ, indentlevel):
+ if typ in ('grs1', 'pas1'):
+ indentlevel -= 1
+ return ','
+ elif typ in ('gre1', 'pae1'):
+ indentlevel += 1
+ return ','
+ return ' ' * indentlevel + ") ,"
+
+if __name__ == "__main__":
+ print '['
+ main()
+ print ']\n' \ No newline at end of file
diff --git a/sample.xmlan b/sample.xmlan
index 9ef82d7..33dccb3 100644
--- a/sample.xmlan
+++ b/sample.xmlan
@@ -1,57 +1,47 @@
<?xml version="1.0"?>
-<xmlan>
- <framesize>70</framesize>
- <tag>
- <name>pic</name>
- <magic>RLPA</magic>
- <type>Normal</type>
- <entry>
- <type>X Translation</type>
+<xmlan framesize="70">
+ <tag name="pic" type="RLPA" format="Normal">
+ <entry type="X Translation">
<triplet>
<frame>20.000000</frame>
<value>0.000000</value>
- <interpolation>3.000000</interpolation>
+ <blend>3.000000</blend>
</triplet>
<triplet>
<frame>40.000000</frame>
<value>15.000000</value>
- <interpolation>3.000000</interpolation>
+ <blend>3.000000</blend>
</triplet>
</entry>
- <entry>
- <type>Y Translation</type>
+ <entry type="Y Translation">
<triplet>
<frame>10.000000</frame>
<value>0.000000</value>
- <interpolation>3.000000</interpolation>
+ <blend>3.000000</blend>
</triplet>
<triplet>
<frame>30.000000</frame>
<value>15.000000</value>
- <interpolation>3.000000</interpolation>
+ <blend>3.000000</blend>
</triplet>
</entry>
</tag>
- <tag>
- <name>pic</name>
- <magic>RLVC</magic>
- <type>Normal</type>
- <entry>
- <type>16</type>
+ <tag type="RLVC" format="Normal">
+ <entry type="16">
<triplet>
<frame>20.000000</frame>
<value>50.000000</value>
- <interpolation>1.000000</interpolation>
+ <blend>1.000000</blend>
</triplet>
<triplet>
<frame>40.000000</frame>
<value>200.000000</value>
- <interpolation>1.000000</interpolation>
+ <blend>1.000000</blend>
</triplet>
<triplet>
<frame>60.000000</frame>
<value>100.000000</value>
- <interpolation>1.000000</interpolation>
+ <blend>1.000000</blend>
</triplet>
</entry>
</tag>