F64  theta, phi, omega, s;
CDC *dc0, *dc1;








                                 <1>/* Graphics Not Rendered in HTML */









U0 GrBlackLighting(CDC *dc, CD3I32 *, CD3I32 *, CD3I32 *, CColorROPU32)
{
    dc->color = 0;
}

U0 DrawShadow(CTask *task)
{
    I64 r[4][4], *r2;

    Mat4x4IdentEqu(dc1->r);
    Mat4x4RotZ(dc1->r, theta);
    Mat4x4RotX(dc1->r, phi);
    Mat4x4RotZ(dc1->r, omega);
    Mat4x4Scale(dc1->r, s);
    Mat4x4TranslationEqu(dc1->r, 200, 200, 5000);
    dc1->flags |= DCF_TRANSFORMATION;
    DCMat4x4Set(dc1, dc1->r);

    MemSet(r, 0, sizeof(r));

    r[0][0] = GR_SCALE;
    r[1][1] = GR_SCALE / 2; //Pick a plane for the shadow, to suit your taste.
    r[1][2] = GR_SCALE / 2; //It doesn't have to have a norm of 1.0.
    r[2][2] = GR_SCALE;
    r[3][3] = GR_SCALE;

    Mat4x4TranslationEqu(r, 0, -2200, 1000);
    r2 = Mat4x4MulMat4x4New(r, dc1->r, task);
    Free(dc1->r);
    DCMat4x4Set(dc1, r2);

    dc1->lighting = &GrBlackLighting;
    Sprite3(dc1, 0, 0, 0, <1>);
}

U0 DrawIt(CTask *task, CDC *)
{
    DCDepthBufReset(dc0);
    Mat4x4IdentEqu(dc0->r);
    Mat4x4RotZ(dc0->r, theta);
    Mat4x4RotX(dc0->r, phi);
    Mat4x4RotZ(dc0->r, omega);
    Mat4x4Scale(dc0->r, s);
    Mat4x4TranslationEqu(dc0->r, 200, 200, 5000);
    dc0->flags |= DCF_TRANSFORMATION;
    DCMat4x4Set(dc0, dc0->r);
    if (mp_count > 1)
        JobQueue(&DrawShadow, task, 1);
    else
        DrawShadow(task);
    Sprite3(dc0, 0, 0, 0, <1>);
}

U0 Shadow()
{//The shadow image b.s.    Any is plausible.
    dc0 = DCAlias(gr.dc2, Fs);
    dc1 = DCAlias(gr.dc2, Fs);
    DCDepthBufAlloc(dc0);
    dc1->depth_buf = dc0->depth_buf;

    theta = 0;
    phi = 0;
    omega = 0;
    s = 1.5;

    SettingsPush; //See SettingsPush
    WinMax;
    Fs->draw_it = &DrawIt;

    while (!CharScan)
    {
        theta += 2 * pi / 70;
        phi += 2 * pi / 90;
        omega += 2 * pi / 110;
        Sleep(20);
    }
    SettingsPop;
    DCDel(dc0);
    dc1->depth_buf = NULL;
    DCDel(dc1);
}

Shadow;