Beispiel #1
0
def get_texture_sprite_tags(lm_data, image_2_id, shape_2_id, image_dict):
    global prefix_for_noname

    data = lm_data[0x40:]
    symbol_list = rip_gim.get_symbol_list(data)
    img_fname_list = [symbol for symbol in symbol_list if symbol.endswith(".png")]
    define_sprite_tags = []
    ori_pic_list = rip_gim.list_tagF007_symbol(lm_data, prefix_for_noname)
    while True:
        tag_type, tag_size = struct.unpack("<HH", data[:0x4])
        if tag_type == 0xFF00:
            break
        if tag_type == 0xF022:
            sprite_id, = struct.unpack("<I", data[0x4:0x8])
            img_cnt, = struct.unpack("<H", data[0xA:0xC])
            place_object2_tags = []
            for i in xrange(img_cnt):  # handle each F023 tag
                data = rip_gim.seek_next_tag(data)
                img_fname_idx, flag = struct.unpack("<HH", data[0x44:0x48])

                # calculate upper left corner of the shape
                # in current texture sprite
                all_floats = struct.unpack("<" + "f" * 16, data[0x4 : 0x4 + 0x4 * 16])
                xs = all_floats[::4]
                ys = all_floats[1::4]
                xmin, xmax = min(xs), max(xs)
                ymin, ymax = min(ys), max(ys)

                if flag == 0x00:  # solid fill
                    matrix = swf_helper.pack_matrix(None, None, (xmin, ymin))
                    shape_id = shape_2_id[(sprite_id << 16) + i]
                else:  # clipped bitmap fill or repeating bitmap fill
                    assert flag in (0x40, 0x41), "not supported (fill type) atm! %d" % flag
                    img_fname = symbol_list[ori_pic_list[img_fname_idx][1]]
                    shape_id = image_2_id[img_fname]
                    matrix = swf_helper.pack_matrix(None, None, (xmin, ymin))

                place_object2_tag = swf_helper.make_place_object2_tag(
                    swf_helper.PLACE_FLAG_HAS_CHARACTER | swf_helper.PLACE_FLAG_HAS_MATRIX,
                    i + 1,
                    id=shape_id,
                    matrix=matrix,
                )
                place_object2_tags.append(place_object2_tag)
            show_frame_tag = swf_helper.make_show_frame_tag()

            control_tags = []
            control_tags.extend(place_object2_tags)
            control_tags.append(show_frame_tag)
            control_tags.append(swf_helper.make_end_tag())
            define_sprite_tag = swf_helper.make_define_sprite_tag(sprite_id, 1, control_tags)
            define_sprite_tags.append(define_sprite_tag)
        else:
            data = rip_gim.seek_next_tag(data)
    return define_sprite_tags
Beispiel #2
0
def make_tex_sprite(ctx, d, subds):
	sprite_id = d["character_id"]
	sub_tags = []

	for i, subd in enumerate(subds):
		shape_tag, shape_id = _make_shape(ctx, subd)
		xmin = min(subd["x0"], subd["x1"], subd["x2"], subd["x3"])
		ymin = min(subd["y0"], subd["y1"], subd["y2"], subd["y3"])
		matrix = swf_helper.pack_matrix(None, None, (xmin, ymin))
		place_obj2_tag = swf_helper.make_place_object2_tag(swf_helper.PLACE_FLAG_HAS_CHARACTER | swf_helper.PLACE_FLAG_HAS_MATRIX, i+1, id=shape_id, matrix=matrix)
		sub_tags.append(place_obj2_tag)
		ctx.setdefault("shape_tags", []).append(shape_tag)
	show_frame_tag = swf_helper.make_show_frame_tag()
	sub_tags.append(show_frame_tag)
	sub_tags.append(swf_helper.make_end_tag())
	
	return swf_helper.make_define_sprite_tag(sprite_id, 1, sub_tags)
Beispiel #3
0
def test(fname, ID, label, pos, scale, fout, img_path, norecreate):
    global prefix_for_noname
    prefix_for_noname = os.path.splitext(os.path.split(fname)[1])[0]

    image_root = img_path or r"c:\png"
    # 	fname = "CHIBI_1P_BALLOON_01.LM"
    f = open(fname, "rb")
    lm_data = f.read()
    f.close()

    fout = fout or fname[:-3] + ".swf"
    if norecreate and os.path.exists(fout):
        return

        # init
    symbol_table = rip_gim.get_symbol_list(lm_data[0x40:])
    assert symbol_table[0] == ""
    constant_pool = "".join([str + "\x00" for str in symbol_table])
    action_constant_pool = struct.pack("<BHH", 0x88, 2 + len(constant_pool), len(symbol_table)) + constant_pool
    action_record_list = rip_gim.list_tagF005_symbol(lm_data)
    frame_label_dict = rip_gim.get_frame_label_dict(lm_data)
    # 	action_record_list = map(fix_action_record, action_record_list)
    # 	print len(action_record_list)
    # 	for i in ():
    for i in xrange(len(action_record_list)):
        print "fixing action record %d" % i
        action_record_list[i] = fix_action_record(action_record_list[i], symbol_table)
    # 	fix_action_record(action_record_list[2])

    max_characterID = rip_gim.get_max_characterID(lm_data)

    # image_dict: {filename : image_data}
    # image_dict2: {filename: (fill_style_type, shape_width, shape_height)}

    image_dict = get_image_dict(lm_data, image_root)
    shape_dict, image_dict2 = get_shape_dict(lm_data)
    # all tags append to this list
    all_tags = []

    # make FileAttributes tag
    all_tags.append(swf_helper.make_file_attributes_tag())

    # make SetBackgroundColor tag
    all_tags.append(swf_helper.make_set_background_color_tag(0xFF, 0xFF, 0xFF))

    # make all DefineBitsJPEG2 tags
    define_bits_JPEG2_tags = []
    image_2_id = {}
    id = max_characterID + 1
    for k, v in image_dict.iteritems():
        tag = swf_helper.make_define_bits_JPEG2_tag(id, v)
        define_bits_JPEG2_tags.append(tag)
        image_2_id[k] = id
        id += 1
    all_tags.extend(define_bits_JPEG2_tags)

    # make all DefineShape tags
    define_shape_tags = []
    image_2_shape_id = {}
    shape_2_shape_id = {}
    id = max_characterID + len(image_dict) + 1
    for k, v in image_dict.iteritems():
        img_data = image_dict[k]

        fill_style_type, shape_width, shape_height = image_dict2[k]
        tag = swf_helper.make_define_shape3_tag_bitmap_simple(
            id, image_2_id[k], shape_width, shape_height, fill_style_type
        )
        image_2_shape_id[k] = id
        id += 1
        define_shape_tags.append(tag)

    for k, (color, size) in shape_dict.iteritems():
        tag = swf_helper.make_define_shape3_tag_solid_simple(id, size[0], size[1], swf_helper.pack_color(color))
        shape_2_shape_id[k] = id
        id += 1
        define_shape_tags.append(tag)

    all_tags.extend(define_shape_tags)

    # make all texture mc tags
    define_sprite_tags = get_texture_sprite_tags(lm_data, image_2_shape_id, shape_2_shape_id, image_dict)
    all_tags.extend(define_sprite_tags)

    # make all general mc tags
    define_sprite_tags_general = get_define_sprite_tags(lm_data, action_constant_pool, action_record_list)
    all_tags.extend(define_sprite_tags_general)

    # test basic display
    tmp_tags = []

    # INSTANCE ID(ratio) should be enough!
    id = ID or max_characterID
    tmp_tags.append(
        swf_helper.make_place_object2_tag(
            swf_helper.PLACE_FLAG_HAS_CHARACTER
            | swf_helper.PLACE_FLAG_HAS_MATRIX
            | swf_helper.PLACE_FLAG_HAS_NAME
            | swf_helper.PLACE_FLAG_HAS_RATIO,
            1,
            id=id,
            matrix=swf_helper.pack_matrix(scale and (scale, scale) or None, None, pos or (0, 0)),
            name="main",
            ratio=0xFFFF,
        )
    )

    if label is not None:
        action_records = []
        action_records.append("\x8B\x05\x00main\x00")  # ActionSetTarget "main"
        frame_idx = frame_label_dict[id][label]
        action_records.append("\x81\x02\x00" + struct.pack("<H", frame_idx))
        action_records.append("\x06")
        action_records.append("\x8B\x01\x00")
        tmp_tags.append(swf_helper.make_do_action_tag(action_records))

    tmp_tags.append(swf_helper.make_show_frame_tag())

    all_tags.extend(tmp_tags)

    # make end tag
    end_tag = swf_helper.make_end_tag()
    all_tags.append(end_tag)

    # build swf header
    all_data = ""
    for tag in all_tags:
        all_data += tag

    swf_header = swf_helper.make_swf_header(0xA, 0, 480, 272, 60.0, 1)
    file_length = len(swf_header) + len(all_data)
    swf_header = swf_helper.make_swf_header(0xA, file_length, 480, 272, 60.0, 1)

    fout = open(fout, "wb")
    fout.write(swf_header + all_data)
    fout.close()
Beispiel #4
0
def get_define_sprite_tags(lm_data, action_constant_pool, action_record_list):
    # some tables for referrence
    color_list = rip_gim.list_tagF002_symbol(lm_data)
    point_list = rip_gim.list_tagF103_symbol(lm_data)
    matrix_list = rip_gim.list_tagF003_symbol(lm_data)
    symbol_list = rip_gim.get_symbol_list(lm_data[0x40:])
    define_sprite_tags = []

    data = lm_data[0x40:]
    data = rip_gim.seek_next_tag(data, (0x0027,))
    while True:
        # 		print len(data[:0x4])
        tag_type, tag_size = struct.unpack("<HH", data[:0x4])
        if tag_type == 0xFF00:
            break
        if tag_type == 0x0027:

            control_tags = []
            sprite_id, = struct.unpack("<H", data[0x4:0x6])
            frame_count, = struct.unpack("<H", data[0xC:0xE])
            # 			print "frame_count %d" % frame_count

            frame_label_cnt, = struct.unpack("<H", data[0xA:0xC])
            # 			print "frame lable cnt %d" % frame_label_cnt
            frame_label_dict = {}
            for i in xrange(frame_label_cnt):
                data = rip_gim.seek_next_tag(data, (0x002B,))
                frame_label_idx, the_frame = struct.unpack("<HH", data[0x4:0x8])
                frame_label = symbol_list[frame_label_idx]
                frame_label_dict[the_frame] = frame_label

            depth2matrix = {}
            depth2color_trans = {}

            for i in xrange(frame_count):
                data = rip_gim.seek_next_tag(data, (0x0001,))
                ptag_cnt, = struct.unpack("<H", data[0x6:0x8])
                # 				print "frame %d, placeobject%d" % (i, ptag_cnt)
                if i in frame_label_dict:
                    control_tags.append(swf_helper.make_frame_label_tag(frame_label_dict[i]))
                for j in xrange(ptag_cnt):
                    data = rip_gim.seek_next_tag(data, (0x0004, 0x0005, 0x000C))
                    _type = struct.unpack("<H", data[:0x2])[0]
                    if _type == 0x0005:
                        depth, = struct.unpack("<H", data[0x6:0x8])
                        control_tags.append(swf_helper.make_remove_object2_tag(depth + 1))
                        continue
                    if _type == 0x000C:
                        as_idx, = struct.unpack("<H", data[0x4:0x6])
                        control_tags.append(
                            swf_helper.make_do_action_tag([action_constant_pool, action_record_list[as_idx]])
                        )
                        continue
                    elif _type != 0x0004:
                        print "Ignore other tags ATM"
                        continue

                    _flags = struct.unpack("<H", data[0xC:0xE])[0]
                    flags = 0
                    if _flags & 1:
                        flags |= swf_helper.PLACE_FLAG_HAS_CHARACTER
                    if _flags & 2:
                        flags |= swf_helper.PLACE_FLAG_MOVE
                    id, = struct.unpack("<H", data[0x4:0x6])
                    trans_idx = struct.unpack("<H", data[0x18:0x1A])[0]
                    if trans_idx == 0xFFFF:
                        pass
                    elif (trans_idx & 0x8000) == 0:
                        translate = (matrix_list[trans_idx][4], matrix_list[trans_idx][5])
                        scale = (matrix_list[trans_idx][0], matrix_list[trans_idx][3])
                        rotateskew = (matrix_list[trans_idx][1], matrix_list[trans_idx][2])
                        flags |= swf_helper.PLACE_FLAG_HAS_MATRIX
                    else:
                        trans_idx &= 0x7FFF
                        translate = point_list[trans_idx]
                        scale = rotateskew = None
                        flags |= swf_helper.PLACE_FLAG_HAS_MATRIX
                    if flags & swf_helper.PLACE_FLAG_HAS_MATRIX:
                        matrix = swf_helper.pack_matrix(scale, rotateskew, translate)
                    else:
                        matrix = None
                    depth = struct.unpack("<H", data[0x10:0x12])[0] + 1
                    name_idx = struct.unpack("<H", data[0xA:0xC])[0]
                    name = symbol_list[name_idx]
                    if name != "":
                        flags |= swf_helper.PLACE_FLAG_HAS_NAME
                    color_mul_idx = struct.unpack("<h", data[0x1A:0x1C])[0]
                    color_add_idx = struct.unpack("<h", data[0x1C:0x1E])[0]
                    # 					color_mul_idx = -1
                    # 					color_add_idx = -1
                    if color_mul_idx >= 0 or color_add_idx >= 0:
                        flags |= swf_helper.PLACE_FLAG_HAS_COLOR_TRANSFORM
                    if color_mul_idx < 0:
                        color_mul = None
                    else:
                        color_mul = [c / 256.0 for c in color_list[color_mul_idx]]
                    if color_add_idx < 0:
                        color_add = None
                    else:
                        color_add = color_list[color_add_idx]
                    if flags & swf_helper.PLACE_FLAG_HAS_COLOR_TRANSFORM:
                        color_trans = swf_helper.pack_color_transform_with_alpha(color_add, color_mul)
                    else:
                        color_trans = None

                    clip_depth, = struct.unpack("<H", data[0x12:0x14])
                    if clip_depth > 0:
                        flags |= swf_helper.PLACE_FLAG_HAS_CLIP_DEPTH

                    ratio, = struct.unpack("<h", data[0x6:0x8])
                    if ratio >= 0:
                        flags |= swf_helper.PLACE_FLAG_HAS_RATIO

                    if flags & swf_helper.PLACE_FLAG_HAS_CHARACTER and flags & swf_helper.PLACE_FLAG_MOVE:
                        control_tags.append(swf_helper.make_remove_object2_tag(depth))
                        flags &= 0xFFFF - swf_helper.PLACE_FLAG_MOVE
                        if not (flags & swf_helper.PLACE_FLAG_HAS_MATRIX):
                            flags |= swf_helper.PLACE_FLAG_HAS_MATRIX
                            matrix = depth2matrix[depth]

                    clip_action_cnt, = struct.unpack("<H", data[0x20:0x22])
                    if clip_action_cnt > 0:
                        clip_action_records = []
                        for k in range(clip_action_cnt):
                            data = rip_gim.seek_next_tag(data, (0xF014,))
                            as_idx, event_flags, keycode = struct.unpack("<HIB", data[0x4:0xB])
                            clip_action_records.append(
                                swf_helper.pack_clip_action_record(
                                    event_flags, [action_constant_pool, action_record_list[as_idx]], keycode
                                )
                            )

                        flags |= swf_helper.PLACE_FLAG_HAS_CLIP_ACTIONS
                        clip_actions = swf_helper.pack_clip_actions(clip_action_records)
                    else:
                        clip_actions = None

                    ptag = swf_helper.make_place_object2_tag(
                        flags,
                        depth,
                        id,
                        name=name,
                        matrix=matrix,
                        color_trans=color_trans,
                        clip_actions=clip_actions,
                        ratio=ratio,
                        clip_depth=clip_depth,
                    )
                    control_tags.append(ptag)

                    if matrix:
                        depth2matrix[depth] = matrix
                    if color_trans:
                        depth2color_trans[depth] = color_trans

                show_frame_tag = swf_helper.make_show_frame_tag()
                control_tags.append(show_frame_tag)
                # append end tag
            control_tags.append(swf_helper.make_end_tag())
            # build define sprite tag
            define_sprite_tag = swf_helper.make_define_sprite_tag(sprite_id, frame_count, control_tags)
            define_sprite_tags.append(define_sprite_tag)
        else:
            data = rip_gim.seek_next_tag(data)

    return define_sprite_tags
Beispiel #5
0
def dump(fname, ID, label, pos, scale, fout, img_path, norecreate):
	
	image_root = img_path or r"c:\png"

	f = open(fname, "rb")
	lm_data = f.read()
	f.close()
	
	fout = fout or fname[:-3] + ".swf"
	if norecreate and os.path.exists(fout):
		return
	
	ctx = {"tags": [], "img_root": image_root, "tex_sprite": [], "normal_sprite": [], }
	for off, tag_type, tag_size_bytes, tag in iter_tag(lm_data):
		d = tag_reader.read_tag(format.DATA[tag_type], tag)
		if d["tag_type"] == 0xF001:
			ctx["symbol_list"] = []
			for symbol_info in d["symbol_list"]:
				ctx["symbol_list"].append(symbol_info["symbol"])
			if ctx["symbol_list"][0] is None:
				ctx["symbol_list"][0] = ""
		elif d["tag_type"] == 0xF002:
			ctx["color_list"] = d["color_list"]
		elif d["tag_type"] == 0xF007:
			ctx["img_info_list"] = d["img_list"]
		elif d["tag_type"] == 0xF103:
			ctx["pos_list"] = d["pos_list"]
		elif d["tag_type"] == 0xF003:
			ctx["mat_list"] = d["mat_list"]
		elif d["tag_type"] == 0xF004:
			ctx["box_list"] = d["box_list"]
		elif d["tag_type"] == 0xF005:
			ctx["as_list"] = d["as_list"]
		elif d["tag_type"] == 0xF008:
			assert d["unk_cnt"] == 0, "tag F008 is not empty!"
		elif d["tag_type"] == 0xF009:
			assert d["unk"] == 0, "tag F009 is not empty!"
		elif d["tag_type"] == 0xF00A:
			print "Ignore text!"
		elif d["tag_type"] == 0xF00B:
			assert d["unk"] == 1, "tag F00B is not consistent!"
		elif d["tag_type"] == 0xF00D:
			assert d["const0_0"] == 0
			assert d["const1_0"] == 0
			assert d["const2_0"] == 0						
		elif d["tag_type"] == 0xF105:
			ctx["last_sprite"] = []
		elif d["tag_type"] == 0x000A:
			print "Font Ignored!"
		elif d["tag_type"] == 0xF00C:
			ctx["max_character_id"] = d["max_character_id"]
		elif d["tag_type"] == 0xF022:
			ctx["tex_sprite"].append([d])
		elif d["tag_type"] in (0xF023, 0xF024):
			ctx["tex_sprite"][-1].append(d)
		elif d["tag_type"] == 0x0027:
			ctx["normal_sprite"].append([d])
			ctx["last_sprite"] = ctx["normal_sprite"][-1]
		elif d["tag_type"] in (0x0001, 0x0004, 0x0005, 0x002b, 0xf014, 0x000c):
			ctx["last_sprite"].append(d)
		elif d["tag_type"] == 0x0007:
			pass
		elif d["tag_type"] == 0xf018:
			pass
		elif d["tag_type"] == 0xf019:
			pass		
		elif d["tag_type"] == 0x000B:	# static text
			pass				
		elif d["tag_type"] == 0xF00E:	# static text line
			pass					
		elif d["tag_type"] == 0x0025:
			pass									
		elif d["tag_type"] == 0xFF00:
			pass			
		else:
			assert False, "unhandled tag! Type = 0x%04x" % d["tag_type"]
		
		
	max_characterID = ctx["max_character_id"]
	ctx["last_cid"] = max_characterID + 1
	
	# all tags append to this list
	all_tags = []
	
	# make FileAttributes tag
	all_tags.append(swf_helper.make_file_attributes_tag())
	
	# make SetBackgroundColor tag
	all_tags.append(swf_helper.make_set_background_color_tag(0xFF, 0xFF, 0xFF))

	# make all DefineBitsJPEG2 tags
	ctx["img_idx_2_cid"], img_tags = make_imgs(ctx)
	all_tags.extend(img_tags)

	# export all images(For UDK)
	img_info_list = ctx["img_info_list"]
	exp_id_name_list = []
	for i in xrange(len(img_tags)):
		img_idx = img_info_list[i]["img_idx"]
		exp_id_name_list.append((ctx["img_idx_2_cid"][img_idx], "noname_%d" % img_idx))
	all_tags.append(swf_helper.make_export_assets_tag(exp_id_name_list))
		
		
	# make all Texture sprite tags
	tex_sprite_tags = []
	for data in ctx["tex_sprite"]:
		tex_sprite_tags.extend(make_tex_sprite(ctx, data[0], data[1:]))

	# make all DefineShape tags
	if ctx.get("shape_tags"):
		all_tags.extend(ctx["shape_tags"])
		
	all_tags.extend(tex_sprite_tags)
		
	# make all normal sprite tags
	for data in ctx["normal_sprite"]:
		all_tags.extend(make_normal_sprite(ctx, data[0], data[1:]))	
			
	# test basic display
	tmp_tags = []
	
	id = ID or max_characterID
	tmp_tags.append(swf_helper.make_place_object2_tag(swf_helper.PLACE_FLAG_HAS_CHARACTER|swf_helper.PLACE_FLAG_HAS_MATRIX|swf_helper.PLACE_FLAG_HAS_NAME|swf_helper.PLACE_FLAG_HAS_RATIO, 1, id=id, matrix=swf_helper.pack_matrix(scale and (scale, scale) or None, None, pos or (0, 0), ),name="main",ratio=0xFFFF))

	if label is not None and label != "all_as":
		action_records = []
		action_records.append("\x8B\x05\x00main\x00")   # ActionSetTarget "main"
		frame_idx = frame_label_dict[id][label]
		action_records.append("\x81\x02\x00" + struct.pack("<H", frame_idx))
		action_records.append("\x06")
		action_records.append("\x8B\x01\x00")
		tmp_tags.append(swf_helper.make_do_action_tag(action_records))		
	if label is not None and label == "all_as":
		print "?"
		for as_record in ctx["as_list"]:
			fixed_bytecode = as_fixer.fix(as_record["bytecode"], ctx["symbol_list"])
			tmp_tags.append(swf_helper.make_do_action_tag([fixed_bytecode]))
		
	tmp_tags.append(swf_helper.make_show_frame_tag())
	
	all_tags.extend(tmp_tags)
	
	# make end tag
	end_tag = swf_helper.make_end_tag()
	all_tags.append(end_tag)
	
	# build swf header
	all_data = ""
	for tag in all_tags:
		all_data += tag
		
	swf_header = swf_helper.make_swf_header(0xa, 0, 480, 272, 60.0, 1)
	file_length = len(swf_header) + len(all_data)
	swf_header = swf_helper.make_swf_header(0xa, file_length, 480, 272, 60.0, 
		1)
	
	fout = open(fout, "wb")
	fout.write(swf_header + all_data)
	fout.close()
Beispiel #6
0
def make_normal_sprite(ctx, d, subds):
	color_list = ctx["color_list"]
	point_list = ctx["pos_list"]
	matrix_list = ctx["mat_list"]
	symbol_list = ctx["symbol_list"]
	as_list = ctx["as_list"]
	
	frame_label_cnt = d["frame_label_cnt"]
	frame_cnt = d["0001_cnt"]
	sprite_id = d["character_id"]
#	print "sprite id = %d" % sprite_id
	frame_label_dict = {}
	
	# build a frame label dict for later ref	
	for subd in subds[:frame_label_cnt]:
		assert subd["tag_type"] == 0x002B
		frame_id = subd["frame_id"]
		frame_label = symbol_list[subd["name_idx"]]
		frame_label_dict[frame_id] = frame_label
		
#	print "frame_label_cnt = %d" % frame_label_cnt
	# handle the rest, all the frames
	sub_tags = []
	depth2matrix = {}
	depth2color_trans = {}
	clip_action_cnt = -1
	frame_cmd_cnt = -1
	for subd in subds[frame_label_cnt:]:
			
		if subd["tag_type"] == 0x0001:
			frame_cmd_cnt = subd["cmd_cnt"]
			frame_id = subd["frame_id"]
			frame_label = frame_label_dict.get(frame_id, None)
			if frame_label is not None:
				frame_label_tag = swf_helper.make_frame_label_tag(frame_label)
				sub_tags.append(frame_label_tag)
			
		elif subd["tag_type"]	== 0x0005:
			sub_tags.append(swf_helper.make_remove_object2_tag(
				subd["depth"] + 1))
			frame_cmd_cnt -= 1
		elif subd["tag_type"] == 0x000c:
			bytecodes = as_list[subd["as_idx"]]["bytecode"]
			bytecodes = as_fixer.fix(bytecodes, symbol_list)
			sub_tags.append(swf_helper.make_do_action_tag([bytecodes]))
			frame_cmd_cnt -= 1
		elif subd["tag_type"] == 0xf014:

			clip_action_cnt -= 1
			bytecodes = as_fixer.fix(as_list[subd["as_idx"]]["bytecode"], symbol_list)
			event_flags = subd["clip_event_flags"]
			keycode = 0
			clip_action_records.append(
				swf_helper.pack_clip_action_record(event_flags, [bytecodes], keycode))
					
		elif subd["tag_type"] != 0x0004:
			assert False, "unhandled tag! %d" % subd["tag_type"]

		else:	# handle tag0004
		
			# check unknown fields
			assert subd["unk1"] == 0, "unk1 is not zero!"
			
			frame_cmd_cnt -= 1
			_flags = subd["flags"]
			flags = 0
			if _flags & 1:
				flags |= swf_helper.PLACE_FLAG_HAS_CHARACTER
			if _flags & 2:
				flags |= swf_helper.PLACE_FLAG_MOVE
			id = subd["character_id"]
#			print "sub character id = %d" % id
			trans_idx = subd["trans_idx"]
			if trans_idx == -1:
				pass
			elif trans_idx >= 0:
				translate = (matrix_list[trans_idx]["trans_x"],
					matrix_list[trans_idx]["trans_y"])
				scale = (matrix_list[trans_idx]["scale_x"],
					matrix_list[trans_idx]["scale_y"])
				rotateskew = (matrix_list[trans_idx]["rotateskew_x"], 
					matrix_list[trans_idx]["rotateskew_y"])
				flags |= swf_helper.PLACE_FLAG_HAS_MATRIX
			else:
				fdef = format.DATA[0x0004]
				size = 0
				for vname, size, fmt in fdef:
					if vname == "trans_idx":
						break
				mask = (1 << (size * 8 - 1))-1
				trans_idx &= mask
				translate = point_list[trans_idx]["x"], point_list[trans_idx]["y"]
				scale = rotateskew = None
				flags |= swf_helper.PLACE_FLAG_HAS_MATRIX
			if flags & swf_helper.PLACE_FLAG_HAS_MATRIX:
				matrix = swf_helper.pack_matrix(scale, rotateskew, 
					translate)
			else:
				matrix = None
			
			flags2 = 0
			if subd["blend_mode"] > 1:
				flags2 |= swf_helper.PLACE_FLAG2_HAS_BLEND_MODE
				blend_mode = subd["blend_mode"]
			else:
				blend_mode = None
				
			depth = subd["depth"]
			name_idx = subd["name_idx"]
			name = symbol_list[name_idx]
			if name != "":
				flags |= swf_helper.PLACE_FLAG_HAS_NAME
			color_mul_idx = subd["color_mul_idx"]
			color_add_idx = subd["color_add_idx"]

			if color_mul_idx >= 0 or color_add_idx >= 0:
				flags |= swf_helper.PLACE_FLAG_HAS_COLOR_TRANSFORM
			if color_mul_idx < 0:
				color_mul = None
			else:
				c = color_list[color_mul_idx]
				color_mul = [c["R"]/256.0, c["G"]/256.0, c["B"]/256.0, c["A"]/256.0]
			if color_add_idx < 0:
				color_add = None
			else:
				c = color_list[color_add_idx]
				color_add = [c["R"], c["G"], c["B"], c["A"]]
			if flags & swf_helper.PLACE_FLAG_HAS_COLOR_TRANSFORM:
				color_trans = \
					swf_helper.pack_color_transform_with_alpha(
						color_add, color_mul)
			else:
				color_trans = None
			
			if matrix:
				depth2matrix[depth] = matrix
			if color_trans:
				depth2color_trans[depth] = color_trans
				
			clip_depth = subd["clip_depth"]
			if clip_depth > 0:
				flags |= swf_helper.PLACE_FLAG_HAS_CLIP_DEPTH
				
			ratio = subd["inst_id"]	# Not sure??
			if ratio >= 0:
				flags |= swf_helper.PLACE_FLAG_HAS_RATIO

			if flags & swf_helper.PLACE_FLAG_HAS_CHARACTER and \
				flags & swf_helper.PLACE_FLAG_MOVE:
				sub_tags.append(swf_helper.make_remove_object2_tag(depth + 1))
				flags &= (0xFFFF - swf_helper.PLACE_FLAG_MOVE)
				if not (flags & swf_helper.PLACE_FLAG_HAS_MATRIX):
					flags |= swf_helper.PLACE_FLAG_HAS_MATRIX
					matrix = depth2matrix[depth]
			
			clip_action_cnt = subd["clip_action_cnt"]
			clip_action_records = []
	
		# finish all clip_action tags, pack place object2 tag
		if clip_action_cnt == 0:
			if len(clip_action_records) > 0:
				flags |= swf_helper.PLACE_FLAG_HAS_CLIP_ACTIONS
				clip_actions = \
					swf_helper.pack_clip_actions(clip_action_records)
			else:
				clip_actions = None
				
			ptag = swf_helper.make_place_object3_tag(flags, flags2, depth + 1, 
			id=id, name=name, matrix=matrix, color_trans=color_trans, 
			clip_actions=clip_actions, ratio=ratio, clip_depth=clip_depth+1,
			blend_mode=blend_mode)
			
			sub_tags.append(ptag)
			
			clip_action_cnt = -1
					
		if frame_cmd_cnt == 0:
			sub_tags.append(swf_helper.make_show_frame_tag())
			frame_cmd_cnt = -1			
	
	sub_tags.append(swf_helper.make_end_tag())	
	return swf_helper.make_define_sprite_tag(sprite_id, frame_cnt, sub_tags)