#help_index "Misc/TOS"

Bool fg_on = FALSE;

I64 CopyVideo()
{
        I64  res = 0;
        Bool old_silent = Silent;

        Del("D:/Tmp/*.AU");
        Del("D:/Tmp/*.MV");
        Silent(old_silent);
        SoundShift(&screencast.sound_head, 0.185);
        AUWrite("D:/Tmp/AUDIO", &screencast.sound_head, screencast.t0_now, screencast.t0_tS);
        QueueDel(&screencast.sound_head, TRUE);
        GR2MV("D:/Tmp/VID%03d.MV", "B:/Tmp", "+d");

        return res;
}

#help_index "ScreenCast/TOS"
U0 DelScreenShots()
{
        Bool old_silent = Silent;

        DelTree("B:/Tmp");
        DirMake("B:/Tmp");
        Del("D:/Tmp/*.AU");
        Del("D:/Tmp/*.MV");
        Del("C:/Tmp/*.AU");
        Del("C:/Tmp/*.MV");
        Silent(old_silent);
}

public U0 FrameGrabberToggle(Bool sync_tone, Bool tos_theme, Bool just_audio=FALSE)
{//The frame grabber saves GR files to B:/Tmp.
        static F64 last_time = 0;

        if (tS - last_time > 3.0)
        {
                last_time = tS;
                if (fg_on)
                {
                        fg_on = FALSE;
                        ScreenCast(OFF);
                        User("CopyVideo;Exit;\n");
                }
                else
                {
                        DelScreenShots;
                        fg_on = TRUE;
                        ScreenCast(ON, just_audio);
                        if (sync_tone)
                        {
                                Beep;
                        }
                        if (tos_theme)
                        {
                                User("ExeFile(\"~/TOS/TOSTheme\");Exit;\n");}
                }
        }
}

public U0 JukeSongTAD(I64 num, I64 passes=2)
{//Make movie of one song.
        if (!fg_on)
                FrameGrabberToggle(FALSE, FALSE);
        Sleep(200);
        JukeSongsPuppet("~/TAD/Songs", passes, num, num + 1);
        if (fg_on)
                FrameGrabberToggle(FALSE, FALSE);
}

public U0 JukeSongSup(I64 vol, I64 num, I64 passes=2)
{//Make movie of one song.
        U8 *st = MStrPrint("~/Sup%d/Sup%dHymns", vol, vol);

        if (!fg_on)
                FrameGrabberToggle(FALSE, FALSE);
        JukeSongsPuppet(st, passes, num, num + 1);
        if (fg_on)
                FrameGrabberToggle(FALSE, FALSE);
        Free(st);
}

public U0 JukeLines(I64 vol, I64 start_line, I64 end_line)
{//Make movie of many lines of songs,  starting at 0.
        U8 *st = MStrPrint("~/Sup%d/Sup%dHymns", vol, vol);

        if (!fg_on)
                FrameGrabberToggle(FALSE, FALSE);
        JukeSongsPuppet(st,, start_line * 5, end_line * 5);
        if (fg_on)
                FrameGrabberToggle(FALSE, FALSE);
        Free(st);
}

public U0 TADHymns(I64 vol, I64 let)
{//Make 2-lines of songs movie
        I64 line = 2 * (ToUpper(let) - 'A');

        JukeLines(vol, line, line + 2);
}

#help_index "Misc/TOS"
public U0 DiskCheckAll()
{//DiskCheck on C & D.
        U8 *ptr = TOS_HDS;

        while (*ptr)
        {
                "DiskCheck('%c')\n", *ptr;
                DiskCheck(*ptr++, TRUE);
        }
}

public CDoc *DC2Doc(CDC *dc, I64 dx=0, I64 dy=0, I64 *_total_score=NULL)
{//Use OCR to make a text DolDoc from CDC.
        U8               byte_bit_counts[256];
        I64              i, j, *ptr, row, col, ch, best_ch, score, best_score, 
                         cur_char_image, diff_image, total_score = 0;
        CDoc    *doc = DocNew;

        MemSet(byte_bit_counts, 0, sizeof(byte_bit_counts));
        for (i = 0; i < 256; i++)
                for (j = 0; j < 7; j++)
                        if (Bt(&i, j))
                                byte_bit_counts[i]++;

        for (row = 0; row < dc->height / FONT_HEIGHT; row++)
        {
                for (col = 0; col < dc->width / FONT_WIDTH; col++)
                {

                        cur_char_image = 0;
                        for (i = 0; i < FONT_HEIGHT; i++)
                                for (j = 0; j < FONT_WIDTH; j++)
                                        if (GrPeek(dc, col * FONT_WIDTH + j + dx, row * FONT_HEIGHT + i + dy) != WHITE)
                                                LBts(&cur_char_image, i * 8 + j);

                        best_score = I64_MAX;
                        best_ch = 0;
                        ptr = &text.font[32];
                        for (ch = 32; ch < 127; ch++)
                        {
                                diff_image = *ptr++ ^ cur_char_image;
                                score = 0;
                                for (i = 0; i < 8; i++)
                                        score += byte_bit_counts[diff_image.u8[i]];
                                if (score < best_score)
                                {
                                        best_score = score;
                                        best_ch = ch;
                                }
                        }
                        if (best_ch == '$')
                                DocPrint(doc, "$$");
                        else
                                DocPrint(doc, "%c", best_ch);
                        total_score += best_score;
                }
                DocPrint(doc, "\n");
        }
        if (_total_score)
                *_total_score = total_score;

        return doc;
}

#define MEM_TEST_SIZE   1024 * 1024
U0 MemTest()
{
        U8 *b;

        while (sys_data_bp->alloced_u8s - sys_data_bp->used_u8s > 0x1000000)
        {
                b = MAlloc(MEM_TEST_SIZE, Fs->data_heap);
                MemSet(b, 0x88, MSize(b));
                "Data:%X\n", sys_data_bp->alloced_u8s - sys_data_bp->used_u8s;
                Yield;
        }
        while (sys_code_bp->alloced_u8s - sys_code_bp->used_u8s > 0x1000000)
        {
                b = MAlloc(MEM_TEST_SIZE, Fs->code_heap);
                MemSet(b, 0x88, MSize(b));
                "Code:%X\n", sys_code_bp->alloced_u8s - sys_code_bp->used_u8s;
                Yield;
        }
}