Created
April 11, 2012 13:25
-
-
Save magcius/2359276 to your computer and use it in GitHub Desktop.
Flash 5 Page Files File Format
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
FLA format, "Page N" files as found in Flash 5. | |
Partially reverse engineered by Jasper St. Pierre. | |
FLA files are CFBF files (COM Structured Storage). You can parse/make them with: | |
http://msdn.microsoft.com/en-us/library/aa380369%28VS.85%29.aspx | |
http://git.gnome.org/browse/libgsf | |
Very helpful while making this: | |
http://mh-nexus.de/en/hxd/ | |
http://www.mitec.cz/ssv.html | |
For a trial copy of Flash 5 (Windows): | |
http://mothball.mecheye.net/Abandonware/Flash5.7z | |
Unless specified otherwise, format is little-endian. | |
Formats: | |
struct LengthString { | |
uint16_t length; | |
char name[length]; | |
}; | |
struct Chunk { | |
char *magic; /* FF FF 01 00 */ | |
/* TODO: could the 01 00 be a count, like the number of contained chunks in | |
* the structure? Will investigate with multiple layers/frames later */ | |
LengthString string; | |
char marker; /* 01 00 */ | |
/* TODO: could be related to file magic header, or count in magic */ | |
}; | |
struct PageFile { | |
char *magic; /* 01 */ | |
Chunk chunk; | |
}: | |
For a page file, chunks look like: | |
CPicPage | |
CPicLayer | |
CPicFrame | |
struct FillStyle { | |
char *magic; /* 00 */ | |
/* TODO: see comment re: num_fillstyles. Also, this could | |
* be the type of fillstyle. Needs testing with gradients. */ | |
uint8_t r; | |
uint8_t g; | |
uint8_t b; | |
uint8_t a; | |
}; | |
struct LineStyle { | |
char *magic; /* 00 */ | |
uint8_t r; | |
uint8_t g; | |
uint8_t b; | |
uint8_t a; | |
char *UNK1; /* 14 00 */ | |
/* TODO: possibly thickness or other attributes? Test. */ | |
}; | |
/* TODO: investigate linestyles -- hairline, thickness, etc. */ | |
struct DrawingVertex { | |
uint16_t x; | |
uint16_t y; | |
char *UNK; /* 00 00 00?? seems to be variable-length?? */ | |
/* TODO: this may be where drawing commands come in here. Test with more vertices, | |
* and more interesting shapes (curves) */ | |
}; | |
struct CPicFrameContents { | |
char *UNK1; /* 00 00 00 00 00 80 00 00 80 02 00 00 */ | |
char *UNK2; /* 01 00 00 00 00 00 00 00 00 00 00 00 */ | |
char *UNK3; /* 01 00 00 00 00 00 00 00 00 00 05 */ | |
uint16_t num_vertices; | |
/* TODO: complete guess, need to investigate */ | |
char *UNK4; /* 00 00 */ | |
uint8_t num_fillstyles; | |
/* TODO: uint8_t and LineStyle/FillStyle starts with a NUL, | |
* or uint16_t with a NUL separator? Needs testing with more | |
* than 255 styles. */ | |
FillStyle fillstyles[num_fillstyles]; | |
uint16_t num_fillstyles; | |
LineStyle fillstyles[num_linestyles]; | |
char *UNK5; /* 00 00 00 00 */ | |
/* Unknown format for below -- could be operator-based like SWF (LineTo/MoveTo): | |
* or declarative (each vertex/contour listed -- this maps to JSFL DOM. | |
* | |
* XFL maps to both: | |
* http://stackoverflow.com/questions/4077200/whats-the-meaning-of-the-non-numerical-values-in-the-xfls-edge-definition | |
* | |
* Best bet is to see if I can capture an equivalent to a StyleChangeRecord. | |
* | |
* When I rearranged some byte sequences in this, Flash didn't care (outside of | |
* translating the object into a random position -- relative positions and all that), but JSFL listed | |
* the contours in "reverse" ordering (40 10 10 40) vs. (10 40 40 10). | |
* Note that changing some of the bytes made the shape disappear - but I haven't tested with | |
* both line and fill styles -- could be a quirk with rendering out of order or blanking the | |
* fillstyle. | |
* | |
* Let me just paste the bytes and mark what they do. */ | |
char *UNK6; | |
/* F3 00 00 01 - adding a style makes Flash make the second byte 01, so maybe a StyleChangeRecord? */ | |
/* NOTES: | |
* * Most (all?) values here are in halftwips: There are 40 halftwips per pixel, and one halftwip is 1/40 of a pixel. */ | |
* * Point values seems to be relative, unsure as to what. First point's values are absolute. | |
* | |
* EXAMPLE: Little endian converts this to: 0x0190, which is 400. 400 / 40 = 10. | |
* The shape is located at (10, 10).*/ | |
DrawingVertex points[n_vertices]; | |
/* Either I'm royally screwing up my math hacking or there seems to be | |
* something "validating" the byte values -- if they're not arranged correctly | |
* the shape doesn't appear on the stage. Unknown what the values mean -- for | |
* rectangles, there are four points. When one of the values that represents | |
* the "width" increase, the other needs to decrease. | |
* TODO: test. | |
*/ | |
char *UNK; | |
/* TODO: finish. There's names like "Layer 1" at the *end* of the file, | |
* which reinforces the nested chunks idea: children come first, then | |
* their own data. */ | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment