diff options
| author | comex <comexk@gmail.com> | 2009-03-01 15:57:14 -0500 |
|---|---|---|
| committer | comex <comexk@gmail.com> | 2009-03-01 15:57:14 -0500 |
| commit | 0c44369b84b29a8b11121c718660d9a8ad4085ec (patch) | |
| tree | 9a0a92f7a79cf0b8f609f193c1fa4ec9ce32807b | |
| parent | 86cc61b37614443d1af703030fc12f771fddc179 (diff) | |
| parent | 9b7a102e4b8747c3c8d7f68848785425a45c27b4 (diff) | |
Merge branch 'master' of git://github.com/SquidMan/benzin
| -rw-r--r-- | BenzinWindblowsInstructions.txt | 30 | ||||
| -rw-r--r-- | brlan.c | 124 | ||||
| -rw-r--r-- | brlyt.h | 2 | ||||
| -rw-r--r-- | ethyl.py | 23 | ||||
| -rw-r--r-- | general.h | 8 | ||||
| -rw-r--r-- | parse-brlyt.py | 312 | ||||
| -rw-r--r-- | sample.xmlan | 36 |
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!!!! @@ -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); } @@ -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_ @@ -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 @@ -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> |
