int printTextRecord(FILE *f, int glyphBits, int advanceBits, int type) { int i, numGlyphs; int flags = readUInt8(f); if(flags == 0) return 0; if(flags & TEXTRECORD_STATECHANGE) { if(flags & TEXTRECORD_HASFONT) println("font id: %i", readUInt16(f)); if(flags & TEXTRECORD_HASCOLOR) { print("color: "); if(type == 2) printRGBA(f); else printRGB(f); putchar('\n'); } if(flags & TEXTRECORD_HASXOFF) println("X Offset: %i", readSInt16(f)); if(flags & TEXTRECORD_HASYOFF) println("Y Offset: %i", readSInt16(f)); if(flags & TEXTRECORD_HASFONT) println("font height: %i", readUInt16(f)); } else { numGlyphs = flags & TEXTRECORD_NUMGLYPHS; for(i=0; i<numGlyphs; ++i) { println("glyph index: %i", readBits(f, glyphBits)); println("glyph x advance: %i", readSBits(f, advanceBits)); } } return 1; }
void readDefineSound(ddMovieClip* p, ddReader* r, int length) { int end = ddReader_getOffset(r) + length; int characterID = readUInt16(r); int flags = readUInt8(r); ddSoundFormat format; int sampleCount; unsigned char* data; int sampleRate; int bitsPerSample; boolean stereo; int delay; int size; ddSound* sound; switch ( (flags & 0xf0) >> 4 ) { case 0: format = DDSOUND_UNCOMPRESSED; break; case 1: format = DDSOUND_ADPCM; break; case 2: format = DDSOUND_MP3; break; case 3: format = DDSOUND_UNCOMPRESSED_LITTLEENDIAN; break; case 6: format = DDSOUND_NELLYMOSER; break; default: dd_warn("Unknown sound format: %i", (flags & 0xf0) >> 4); } sampleCount = readUInt32(r); if ( format == DDSOUND_MP3 ) delay = readSInt16(r); size = end - ddReader_getOffset(r); data = readBlock(r, size); switch ( (flags & 0x0c) >> 2 ) { case 0: sampleRate = 5500; break; case 1: sampleRate = 11000; break; case 2: sampleRate = 22000; break; case 3: sampleRate = 44000; break; } bitsPerSample = ((flags & 0x02) != 0) ? 16 : 8; stereo = ((flags & 0x01) != 0) ? DD_TRUE : DD_FALSE; sound = dd_newSound(format, sampleRate, bitsPerSample, stereo, sampleCount, size, data, delay); ddMovieClip_addCharacter(p, characterID, (ddCharacter*)sound); }
void readSoundStreamHead(ddMovieClip* p, ddReader* r, int length) { int flags; ddSoundFormat format; int sampleRate; int bitsPerSample; boolean stereo; int samplesPerFrame; int delay = 0; readUInt8(r); // recommended playback settings - ignore flags = readUInt8(r); switch ( (flags & 0xf0) >> 4 ) { case 0: format = DDSOUND_UNCOMPRESSED; break; case 1: format = DDSOUND_ADPCM; break; case 2: format = DDSOUND_MP3; break; case 3: format = DDSOUND_UNCOMPRESSED_LITTLEENDIAN; break; case 6: format = DDSOUND_NELLYMOSER; break; default: dd_warn("Unknown sound format: %i", (flags & 0xf0) >> 4); } switch ( (flags & 0x0c) >> 2 ) { case 0: sampleRate = 5500; break; case 1: sampleRate = 11000; break; case 2: sampleRate = 22000; break; case 3: sampleRate = 44000; break; } bitsPerSample = ((flags & 0x02) != 0) ? 16 : 8; stereo = ((flags & 0x01) != 0) ? DD_TRUE : DD_FALSE; samplesPerFrame = readUInt16(r); if ( format == DDSOUND_MP3 ) delay = readSInt16(r); ddMovieClip_setSoundStreamFormat(p, format, sampleRate, bitsPerSample, stereo, samplesPerFrame, delay); }
static Stack readActionRecord(FILE *f) { int length = 0, type = readUInt8(f); if((type&0x80) == 0x80) length = readUInt16(f); switch(type) { /* no-arg */ case SWFACTION_GETTIMER: case SWFACTION_STOPDRAGMOVIE: case SWFACTION_NEXTFRAME: case SWFACTION_PREVFRAME: case SWFACTION_PLAY: case SWFACTION_STOP: case SWFACTION_TOGGLEQUALITY: case SWFACTION_STOPSOUNDS: return newTree(NULL, type, NULL); case SWFACTION_POP: /* pop(); */ return newTree(NULL, type, NULL); /* one-arg */ case SWFACTION_STRINGLENGTH: case SWFACTION_INT: case SWFACTION_RANDOM: case SWFACTION_MBLENGTH: case SWFACTION_ORD: case SWFACTION_CHR: case SWFACTION_MBORD: case SWFACTION_MBCHR: case SWFACTION_LOGICALNOT: case SWFACTION_GETVARIABLE: case SWFACTION_REMOVECLIP: case SWFACTION_TRACE: case SWFACTION_SETTARGETEXPRESSION: case SWFACTION_CALLFRAME: return newTree(pop(), type, NULL); /* two-arg */ case SWFACTION_ADD: case SWFACTION_MULTIPLY: case SWFACTION_DIVIDE: case SWFACTION_EQUAL: case SWFACTION_LESSTHAN: case SWFACTION_LOGICALAND: case SWFACTION_LOGICALOR: case SWFACTION_STRINGEQ: case SWFACTION_SETVARIABLE: case SWFACTION_STRINGCONCAT: case SWFACTION_STRINGCOMPARE: { Stack right = pop(); Stack left = pop(); return newTree(left, type, right); } case SWFACTION_GETPROPERTY: { Stack right = pop(); Stack left = pop(); if(right->type == 's') { Stack New = newProperty(atoi(right->data.string)); destroy(right); right = New; } return newTree(left, type, right); } case SWFACTION_SUBTRACT: { Stack right = pop(); Stack left = pop(); if(left->type == 's' && strcmp(left->data.string, "0") == 0) { destroy(left); right->data.string = negateString(right->data.string); return right; } return newTree(left, type, right); } /* three-arg */ case SWFACTION_SETPROPERTY: { Stack value = pop(); Stack property = pop(); Stack target = pop(); if(property->type == 's') { Stack New = newProperty(atoi(property->data.string)); destroy(property); property = New; } return newTree(newTree(target, type, property), SWFACTION_SETVARIABLE, value); } case SWFACTION_MBSUBSTRING: case SWFACTION_SUBSTRING: { Stack s3 = pop(); Stack s2 = pop(); Stack s1 = pop(); return newTree(s1, type, newTree(s2, type, s3)); } case SWFACTION_DUPLICATECLIP: { Stack level = pop(); Stack target = pop(); Stack source = pop(); Stack arg; if(level->type != 't' || level->data.tree->action != SWFACTION_ADD) error("WTHIT property not found in duplicateClip target level!"); if(level->data.tree->left->type == 'p' && level->data.tree->left->data.prop == PROPERTY_WTHIT) { arg = level->data.tree->right; level->data.tree->right = NULL; } else if(level->data.tree->right->type == 'p' && level->data.tree->right->data.prop == PROPERTY_WTHIT) { arg = level->data.tree->left; level->data.tree->left = NULL; } else error("WTHIT property not found in duplicateClip target level!"); destroy(level); return newTree(source, type, newTree(target, type, arg)); } /* weird ops */ case SWFACTION_STARTDRAGMOVIE: { Stack target = pop(); Stack lockmouse = pop(); Stack constraint = pop(); if(constraint->type != 's') error("Sorry, decompiler can't deal with conditional constraint!"); if(strcmp(constraint->data.string, "0") == 0) return newTree(constraint, type, newTree(lockmouse, type, target)); else { Stack s4 = pop(); Stack s3 = pop(); Stack s2 = pop(); Stack s1 = pop(); return newTree(newTree(newTree(s1, type, s2), type, newTree(s3, type, s4)), type, newTree(lockmouse, type, target)); } } case SWFACTION_PUSHDATA: { int local_type = readUInt8(f); if(local_type==0) return newString(readString(f)); else { readUInt16(f); /* 0x0000 */ return newProperty(getSetProperty(readUInt16(f))); } } case SWFACTION_GOTOFRAME: return newTree((Stack)readUInt16(f), type, NULL); case SWFACTION_GETURL: { char *url = readString(f); char *target = readString(f); return newTree((Stack)url, type, (Stack)target); } case SWFACTION_GETURL2: { Stack target = pop(); Stack url = pop(); return newTree((Stack)readUInt8(f), type, newTree(url, type, target)); } case SWFACTION_WAITFORFRAMEEXPRESSION: return newTree((Stack)readUInt8(f), type, NULL); case SWFACTION_GOTOEXPRESSION: return newTree(pop(), type, (Stack)readUInt8(f)); case SWFACTION_SETTARGET: case SWFACTION_GOTOLABEL: return newTree((Stack)readString(f), type, NULL); /* branches */ case SWFACTION_BRANCHIFTRUE: return newTree(pop(), type, (Stack)readSInt16(f)); case SWFACTION_BRANCHALWAYS: return newTree(NULL, type, (Stack)readSInt16(f)); case SWFACTION_WAITFORFRAME: { Stack left = (Stack)readUInt16(f); Stack right = (Stack)readUInt8(f); return newTree(left, type, right); } case SWFACTION_END: return NULL; default: printf("Unknown Action: %02X\n", type); dumpBytes(f, length); return NULL; } }
int printActionRecord(FILE *f) { int length = 0, type = readUInt8(f); if((type&0x80) == 0x80) length = readUInt16(f); switch(type) { case SWFACTION_ADD: println("Add"); break; case SWFACTION_SUBTRACT: println("Subtract"); break; case SWFACTION_MULTIPLY: println("Multiply"); break; case SWFACTION_DIVIDE: println("Divide"); break; case SWFACTION_EQUAL: println("Equals"); break; case SWFACTION_STRICTEQ: println("Strictly Equals"); break; case SWFACTION_LESSTHAN: println("Less Than"); break; case SWFACTION_LOGICALAND: println("And"); break; case SWFACTION_LOGICALOR: println("Or"); break; case SWFACTION_LOGICALNOT: println("Not"); break; case SWFACTION_STRINGEQ: println("String eq"); break; case SWFACTION_STRINGLENGTH: println("String Length"); break; case SWFACTION_SUBSTRING: println("Substring"); break; case SWFACTION_INT: println("Int"); break; case SWFACTION_POP: println("Pop"); break; case SWFACTION_SWAP: println("Swap"); break; case SWFACTION_INITOBJECT: println("Init Object"); break; case SWFACTION_INITARRAY: println("Init Array"); break; case SWFACTION_GETVARIABLE: println("Get Variable"); break; case SWFACTION_SETVARIABLE: println("Set Variable"); break; case SWFACTION_SETTARGETEXPRESSION: println("Set Target Expression"); break; case SWFACTION_STRINGCONCAT: println("String Concat"); break; case SWFACTION_GETPROPERTY: println("Get Property"); break; case SWFACTION_SETPROPERTY: println("Set Property"); break; case SWFACTION_DUPLICATECLIP: println("Duplicate Clip"); break; case SWFACTION_REMOVECLIP: println("Remove Clip"); break; case SWFACTION_TRACE: println("Trace"); break; case SWFACTION_STARTDRAGMOVIE: println("Start Drag Movie"); break; case SWFACTION_STOPDRAGMOVIE: println("Stop Drag Movie"); break; case SWFACTION_STRINGCOMPARE: println("String Compare"); break; case SWFACTION_RANDOM: println("Random"); break; case SWFACTION_MBLENGTH: println("String MB Length"); break; case SWFACTION_ORD: println("Ord"); break; case SWFACTION_CHR: println("Chr"); break; case SWFACTION_GETTIMER: println("Get Timer"); break; case SWFACTION_MBSUBSTRING: println("MB Substring"); break; case SWFACTION_MBORD: println("MB Ord"); break; case SWFACTION_MBCHR: println("MB Chr"); break; case SWFACTION_NEXTFRAME: println("Next Frame"); break; case SWFACTION_PREVFRAME: println("Previous Frame"); break; case SWFACTION_PLAY: println("Play"); break; case SWFACTION_STOP: println("Stop"); break; case SWFACTION_TOGGLEQUALITY: println("Toggle Quality"); break; case SWFACTION_STOPSOUNDS: println("Stop Sounds"); break; /* ops with args */ case SWFACTION_PUSHDATA: { int type; int start = fileOffset; int count = 0; print("Push:"); while(fileOffset < start+length) { if ( count++ ) putchar(','); switch(type = readUInt8(f)) { case 0: /* string */ printf(" string:%s", readString(f)); break; case 1: /* property */ readUInt16(f); /* always 0? */ printf(" property:%04x", readUInt16(f)); break; case 2: /* null */ printf(" NULL"); break; case 3: /* ??? */ printf(" type_3:"); break; case 4: printf(" register:%i", readUInt8(f)); break; case 5: if(readUInt8(f)) printf(" TRUE"); else printf(" FALSE"); break; case 6: /* double */ printf(" double:%f", readDouble(f)); break; case 7: /* int */ printf(" int:%i", readSInt32(f)); break; case 8: /* dictionary */ printf(" dict:\"%s\"", dictionary[readUInt8(f)]); break; default: printf(" unknown_type_%i", type); } } putchar('\n'); break; } case SWFACTION_GOTOFRAME: println("Goto Frame %i", readUInt16(f)); break; case SWFACTION_GETURL: { char *url = readString(f); println("Get URL \"%s\" target \"%s\"", url, readString(f)); break; } case SWFACTION_WAITFORFRAMEEXPRESSION: println("Wait For Frame Expression, skip %i\n", readUInt8(f)); break; case SWFACTION_BRANCHALWAYS: println("Branch Always %i", readSInt16(f)); break; case SWFACTION_GETURL2: { int flags = readUInt8(f); switch(flags) { case 0: println("Get URL2 (Don't send)"); break; case 1: println("Get URL2 (GET)"); break; case 2: println("Get URL2 (POST)"); break; default: println("GET URL2 (0x%x)", flags); } break; } case SWFACTION_BRANCHIFTRUE: println("Branch If True %i", readSInt16(f)); break; case SWFACTION_CALLFRAME: println("Call Frame"); dumpBytes(f, length); break; case SWFACTION_GOTOEXPRESSION: print("Goto Expression"); if(readUInt8(f) == 1) printf(" and Play\n"); else printf(" and Stop\n"); break; case SWFACTION_WAITFORFRAME: { int frame = readUInt16(f); println("Wait for frame %i else skip %i", frame, readUInt8(f)); break; } case SWFACTION_SETTARGET: println("Set Target %s", readString(f)); break; case SWFACTION_GOTOLABEL: println("Goto Label %s", readString(f)); break; case SWFACTION_END: return 0; break; /* f5 ops */ case SWFACTION_DELETE: println("Delete"); break; case SWFACTION_DELETEVAR: println("Delete2"); break; case SWFACTION_VAR: println("Var"); break; case SWFACTION_VAREQUALS: println("Var Assign"); break; case SWFACTION_CALLFUNCTION: println("Call Function"); break; case SWFACTION_RETURN: println("Return"); break; case SWFACTION_MODULO: println("Modulo"); break; case SWFACTION_NEW: println("New"); break; case SWFACTION_NEWMETHOD: println("NewMethod"); break; case SWFACTION_TYPEOF: println("Typeof"); break; case SWFACTION_TARGETPATH: println("TargetPath"); break; case SWFACTION_NEWADD: println("New Add"); break; case SWFACTION_NEWLESSTHAN: println("New Less Than"); break; case SWFACTION_NEWEQUAL: println("New Equals"); break; case SWFACTION_DUP: println("Dup"); break; case SWFACTION_GETMEMBER: println("Get Member"); break; case SWFACTION_SETMEMBER: println("Set Member"); break; case SWFACTION_INCREMENT: println("Increment"); break; case SWFACTION_DECREMENT: println("Decrement"); break; case SWFACTION_CALLMETHOD: println("Call Method"); break; case SWFACTION_BITWISEAND: println("Bitwise And"); break; case SWFACTION_BITWISEOR: println("Bitwise Or"); break; case SWFACTION_BITWISEXOR: println("Bitwise Xor"); break; case SWFACTION_SHIFTLEFT: println("Shift Left"); break; case SWFACTION_SHIFTRIGHT: println("Shift Right"); break; case SWFACTION_SHIFTRIGHT2: println("Shift Right 2"); break; case SWFACTION_DECLARENAMES: { int i, n = readUInt16(f); print("Declare Dictionary:"); for(i=0; i<n; ++i) printf(" %s%c", dictionary[i]=readString(f), (i<n-1)?',':'\n'); break; } case SWFACTION_WITH: { println("With"); ++gIndent; printDoAction(f, readUInt16(f)); --gIndent; break; } case SWFACTION_DEFINEFUNCTION: { char *name = readString(f); int n = readUInt16(f); print("function %s(", name); if(n>0) { printf("%s", readString(f)); --n; } for(; n>0; --n) printf(", %s", readString(f)); putchar(')'); putchar('\n'); ++gIndent; printDoAction(f, readUInt16(f)); --gIndent; break; } case SWFACTION_ENUMERATE: println("Enumerate"); break; case SWFACTION_SETREGISTER: println("Set Register %i", readUInt8(f)); break; default: println("Unknown Action: %02X", type); dumpBytes(f, length); } return 1; }
void printDefineFont2(FILE *f, int length) { int flags, nGlyphs, namelen, i, fillBits, lineBits; int here = fileOffset; int *offset; println("fontID: %i", readUInt16(f)); flags = readUInt8(f); readUInt8(f); /* "reserved" */ namelen = readUInt8(f); print("Font Name: "); for(; namelen>0; --namelen) putchar((unsigned char)readUInt8(f)); putchar('\n'); nGlyphs = readUInt16(f); println("number of glyphs: %i\n", nGlyphs); offset = (unsigned int *)malloc(nGlyphs*sizeof(int)); /* offset table */ here = fileOffset; for(i=0; i<=nGlyphs; ++i) { if(flags & FONTINFO2_WIDEOFFSETS) offset[i] = readUInt32(f)-4*nGlyphs-2; else offset[i] = readUInt16(f)-2*nGlyphs-2; println("Offset%i: %i", i, offset[i]); } here = fileOffset; /* shape table */ for(i=0; i<nGlyphs; ++i) { byteAlign(); println("Glyph %i:", i); fillBits = readBits(f, 4); lineBits = readBits(f, 4); byteAlign(); while(printShapeRec(f, &fillBits, &lineBits, 2)) ; putchar('\n'); } /* code table */ for(i=0; i<nGlyphs; ++i) { if(flags & FONTINFO2_WIDECODES) println("glyph code %i: %i", i, readUInt16(f)); else println("glyph code %i: %i", i, readUInt8(f)); } if(flags & FONTINFO2_HASLAYOUT) { int kernCount, code1, code2; println("ascender height: %i", readSInt16(f)); println("descender height: %i", readSInt16(f)); println("leading height: %i", readSInt16(f)); for(i=0; i<nGlyphs; ++i) printf("\tadvance %i: %i\n", i, readSInt16(f)); for(i=0; i<nGlyphs; ++i) { print("bounds %i: ", i); printRect(f); putchar('\n'); } kernCount = readUInt16(f); for(i=0; i<kernCount; ++i) { code1 = (flags & FONTINFO2_WIDECODES) ? readUInt16(f) : readUInt8(f); code2 = (flags & FONTINFO2_WIDECODES) ? readUInt16(f) : readUInt8(f); println("(%i,%i): adjustment = %i", code1, code2, readSInt16(f)); } } }