#help_index "ScreenCast;Graphics/Device Contexts;Graphics/GR Files"

#define MV_FILE_MAX         0x007FF000

public I64 GR2MV(U8 *print_format="VID%03d.MV", U8 *files_find_mask, U8 *fu_flags=NULL)
{/*Merge GR list to MV file.
"+d" will delete GR list files.
*/
    I64          fuf_flags = 0, file_num = 0, size;
    CDirEntry   *tmpde, *tmpde1;
    U8          *base, *dst, *src, *st;
    CDC         *dc, *dc_base = DCNew(GR_WIDTH, GR_HEIGHT);
    CDate        cdt;
    Bool         old_silent;

    FlagsScan(&fuf_flags, Define("ST_FILE_UTIL_FLAGS"), "+f+F");
    FlagsScan(&fuf_flags, Define("ST_FILE_UTIL_FLAGS"), fu_flags);
    tmpde = tmpde1 = FilesFind(files_find_mask, fuf_flags & FUG_FILES_FIND);
    if (progress1_max = LinkedListCount(tmpde1))
    {
        dst = base = MAlloc(MV_FILE_MAX);
        while (tmpde)
        {
            dc = GRRead(tmpde->full_name);
            GrBlot(dc_base, dc->x0, dc->y0, dc);
            if (dst + GR_FILE_MAX > base + MV_FILE_MAX)
            {
                st = MStrPrint(print_format, file_num++);
                FileWrite(st, base, dst-base);
                Free(st);
                dst = base;

                cdt = dc->cdt;
                dc = DCCopy(dc_base);
                dc->cdt = cdt;
            }
            src = DCSave(dc, &size);
            DCDel(dc);
            MemCopy(dst, src, size);
            dst += size;
            Free(src);
            if (fuf_flags & FUF_DEL)
            {
                old_silent = Silent;
                Del(tmpde->full_name);
                Silent(old_silent);
            }
            progress1++;
            tmpde = tmpde->next;
        }
        if (dst > base)
        {
            st = MStrPrint(print_format, file_num++);
            FileWrite(st, base, dst-base);
            Free(st);
        }
        Free(base);
    }
    progress1 = progress1_max = 0;
    DirTreeDel(tmpde1);
    DCDel(dc_base);

    return file_num;
}

#help_index "ScreenCast;Sound/AU Files"
public U0 SoundShift(CSoundData *head, F64 dt=0)
{//Shift CSoundData in time.
    CSoundData *tmpsd, *tmpsd1;

    if (dt)
    {
        tmpsd = head->next;
        while (tmpsd != head)
        {
            tmpsd1 = tmpsd->next;
            tmpsd->tS -= dt;
            if (tmpsd->tS < tmpsd->last->tS)
            {
                QueueRemove(tmpsd);
                Free(tmpsd);
            }
            tmpsd = tmpsd1;
        }
    }
}

public I64 AUWrite(U8 *filename, CSoundData *head, CDate *t0_now, F64 t0_tS)
{//Write AU file.
    CSoundData  *tmpsd;
    CAUData     *base, *dst;
    I64          size = (1 + QueueCount(head)) * sizeof(CAUData);
    U8          *st = ExtDefault(filename, "AU");

    base = dst = MAlloc(size);
    tmpsd = head;
    do
    {
        dst->cdt = t0_now(I64) + ToI64(CDATE_FREQ * (tmpsd->tS - t0_tS));
        dst->ona = tmpsd->ona;
        dst++;
        tmpsd = tmpsd->next;
    }
    while (tmpsd != head);

    FileWrite(st, base, dst(U8 *) - base(U8 *));
    Free(base);
    Free(st);

    return size;
}