/**
 *  Sega Saturn SatCom test program
 *  by cafe-alpha.
 *  WWW: http://ppcenter.free.fr/
 *
 *  Based on Sega Saturn VDP1 example program
 *  by Charles MacDonald
 *  WWW: http://cgfm2.emuviews.com
**/

#include "shared.h"

/* Texture map size */
#define TX_W    128
#define TX_H    128

/* Create a 5:5:5 RGB color with the MSB set */
#define COLOR(r,g,b)    (((r)&0x1F)|((g)&0x1F)<<5|((b)&0x1F)<<10|0x8000)



unsigned short list_index = 1;  /* Offset into the command list */
unsigned short mesh_flag = 0;   /* Global mesh enable flag */

/* Point direction flags */
#define DIR_V       1
#define DIR_H       2

/* Coordinate structure */
typedef struct { short x,y; } point_t;

/* Describe a single point position and movement */
typedef struct {
    point_t c[4];
    unsigned char dir[4];
} object_t;

/* Move four points of an object */
void update_pos(object_t *p)
{
    int i;
    for(i = 0; i < 4; i++)
    {
        if(p->dir[i] & DIR_V)
            p->c[i].y--;
        else
            p->c[i].y++;

        if(p->dir[i] & DIR_H)
            p->c[i].x--;
        else
            p->c[i].x++;

        if((p->c[i].y < 0) || (p->c[i].y > 224))
            p->dir[i] ^= DIR_V;

        if((p->c[i].x < 0) || (p->c[i].x > 320))
            p->dir[i] ^= DIR_H;
    }
}

/* Clear command list */
void list_clear(void)
{
    unsigned short *p = (unsigned short *)VDP1_VRAM;
    int i;
    for(i=0;i<16;i++)
        p[i] = 0xFFFF;
    p[CMDCTRL] = 0x4000;
    list_index = 1;
}

/* Add end marker to command list */
void list_end(void)
{
    unsigned short *p = (unsigned short *)(VDP1_VRAM + (list_index << 5));
    p[CMDCTRL] = 0x8000;
    list_index++;
}

/* Add system clip to command list */
void list_set_system_clip(short x, short y)
{
    unsigned short *p = (unsigned short *)(VDP1_VRAM + (list_index << 5));

    p[CMDCTRL] = 0x0009; /* Set system clip */
    p[CMDLINK] = 0x0000; /* Jump address */
    p[CMDXC]   = x;
    p[CMDYC]   = y;
    list_index++;
}


/* Add user clip to command list */
void list_set_user_clip(short x1, short y1, short x2, short y2)
{
    unsigned short *p = (unsigned short *)(VDP1_VRAM + (list_index << 5));

    p[CMDCTRL] = 0x0008; /* Set user clip */
    p[CMDLINK] = 0x0000; /* Jump address */
    p[CMDXA]   = x1;
    p[CMDYA]   = y1;
    p[CMDXC]   = x2;
    p[CMDYC]   = y2;
    list_index++;
}

/* Add local coords to command list */
void list_set_local_coords(short x, short y)
{
    unsigned short *p = (unsigned short *)(VDP1_VRAM + (list_index << 5));

    p[CMDCTRL] = 0x000A; /* Set local coords */
    p[CMDLINK] = 0x0000; /* Jump address */
    p[CMDXA]   = x;
    p[CMDYA]   = y;
    list_index++;
}

/* Add local coords to command list */
void list_polyline(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, unsigned short color)
{
    unsigned short *p = (unsigned short *)(VDP1_VRAM + (list_index << 5));

    p[CMDCTRL] = 0x0005; /* Polyline */
    p[CMDLINK] = 0x0000; /* Jump address */
    p[CMDPMOD] = 0x00C0 | mesh_flag;
    p[CMDCOLR] = color;
    p[CMDXA]   = x1;
    p[CMDYA]   = y1;
    p[CMDXB]   = x2;
    p[CMDYB]   = y2;
    p[CMDXC]   = x3;
    p[CMDYC]   = y3;
    p[CMDXD]   = x4;
    p[CMDYD]   = y4;
    list_index++;
}

/* Add local coords to command list */
void list_polygon(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, unsigned short color, unsigned long grda)
{
    unsigned short *p = (unsigned short *)(VDP1_VRAM + (list_index << 5));

    p[CMDCTRL] = 0x0004; /* Polygon */
    p[CMDLINK] = 0x0000; /* Jump address */
    p[CMDPMOD] = 0x00C0 | mesh_flag | 4;
    p[CMDCOLR] = color;
    p[CMDXA]   = x1;
    p[CMDYA]   = y1;
    p[CMDXB]   = x2;
    p[CMDYB]   = y2;
    p[CMDXC]   = x3;
    p[CMDYC]   = y3;
    p[CMDXD]   = x4;
    p[CMDYD]   = y4;
    p[CMDGRDA] = grda>>3;
    list_index++;
}

/* Add local coords to command list */
void list_distorted_sprite(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, unsigned long source, int w, int h)
{
    unsigned short *p = (unsigned short *)(VDP1_VRAM + (list_index << 5));

    p[CMDCTRL] = 0x1002; /* Distorted sprite, RGB mode */
    p[CMDLINK] = 0x0000; /* Jump address */
    p[CMDPMOD] = 0x00A8 | mesh_flag;
    p[CMDCOLR] = 0;
    p[CMDSRCA] = source;
    p[CMDSIZE] = (((w>>3)&0x3F)<<8)|(h&0xFF);
    p[CMDXA]   = x1;
    p[CMDYA]   = y1;
    p[CMDXB]   = x2;
    p[CMDYB]   = y2;
    p[CMDXC]   = x3;
    p[CMDYC]   = y3;
    p[CMDXD]   = x4;
    p[CMDYD]   = y4;
    list_index++;
}




/* Define line filled with spaces in order to erase a line. */
char* empty_line = "                                     ";




/* CDC test. */
void cdrom_test(void);


typedef struct fread_callback_t
{
    unsigned char row; /* Row where to write progress. */
} fread_callback_t;
fread_callback_t _fread_callback_data;
void fread_callback(unsigned long data_transfer, unsigned long data_total, void* callback_data)
{
    char txt[256];
    fread_callback_t* dat = (fread_callback_t*)callback_data;

    sprintf(txt, "Loading data = %3d / 100 ...    ", (int)((100*data_transfer)/data_total));
    scd_logout("loading = >%s<", txt); scd_logflush();
    _printf(2, dat->row, COLOR_SILVER, txt);
}
unsigned char buff[256*1024];






void _main(void)
{
    pad_t pad;
    unsigned short* p;
    int x, y, frame_count = 0;
    object_t foo[4];
    char* str = NULL;

    /* SatCom: initialization. */
    sc_init();


    vdp_init();
    conio_init();
    pad_init();

    /* Set up VDP1 to appear under VDP2 graphics (0=hide, 1-7=visible) */
    PRISA = 0x0101;
    PRISB = 0x0101;
    PRISC = 0x0101;
    PRISD = 0x0101;

    /* Set up VDP1 registers */
    TVMR = 0x0000;
    FBCR = 0x0000;
    PTMR = 0x0002;
    EWDR = COLOR(7,7,7);    /* Erase color: gray */
    EWLR = 0x0000;          /* Erase range: (0,0) -> (352,240) */
    EWRR = 0x50DF;



    /* Print message */
    int row=1, datarow;

    _printf(2, row++, COLOR_TEAL, "=/       SatCom DUMMY SAMPLE      \\=");
    _printf(2, row++, COLOR_YELLOW, "= By cafe-alpha (ppcenter.free.fr) =");
    _printf(2, row++, COLOR_YELLOW, "Build on " RELEASE_DATE);
    row++;
    _printf(2, row++, COLOR_SILVER, "From VDP1EX by Charles MacDonald");
    _printf(2, row++, COLOR_SILVER, "WWW: http://cgfm2.emuviews.com");
    row++;

    /* Help screen end. */
    row++;
    datarow=row;


    /* Screen on */
    TVMD = 0x8000;
    TVMR = 0x0000;
    FBCR = 0x0001;
    EWRR = 0x50DF;


    /* Make texture map */
    p = (unsigned short *)0x25C40000;
    for(y=0;y<TX_H;y++)
    {
        for(x=0;x<TX_W;x++)
        {
            p[y*TX_W+x] = COLOR(x*x/16, x*y/16, y*y/16);
            //p[y*TX_W+x] = COLOR((x*x-y*y)>>4,x^y,(x*x+y*y)>>6);
        }
    }

    /* Make Gouraud shading table */
    p = (unsigned short *)0x25C60000;
    p[0] = COLOR(31,0,0);
    p[1] = COLOR(0,31,0);
    p[2] = COLOR(0,0,31);
    p[3] = COLOR(31,31,31);

    /* Initialize object positions */
    for(y = 0; y < 4; y++)
    for(x = 0; x < 4; x++)
    {
        foo[y].c[x].x = rand() % 320;
        foo[y].c[x].y = rand() % 224;
        foo[y].dir[x] = rand() & 3;
    }

    /* Initialize display list */
    list_clear();
    list_end();










    /* bget tayst STT */
    scm_alloc_init(SCM_LRAM);
    unsigned char* buff = (unsigned char*)scm_malloc(500, /*SCM_LRAM | */SCM_RAMCART);
    while(1)
    {
        sc_check();
    }
    /* bget tayst END */




    /* Sleep tayst STT */
    while(1)
    {
        int ii;

        /* SatCom: if needed, transfer data. */
        sc_check();

        /* Wait for V-Blank. */
        wait_vblank_out();
        wait_vblank_in();

        /* Poll joypad */
        pad_read(&pad);


        if(pad.new & PAD_X)
        {
            scd_logout("Sleep for 5 seconds ...", 0); scd_logflush();
            sc_usleep(5*1000*1000);
            scd_logout("Sleep ended !", 0); scd_logflush();
        }
        if(pad.new & PAD_Y)
        {
            scd_logout("Sleep for 5msec * 1000 ...", 0); scd_logflush();
            for(ii=0; ii<1000/20; ii++)
            {
                sc_usleep(5*1000 * 20);
            }
            scd_logout("Sleep ended !", 0); scd_logflush();
        }
    }
    /* Sleep tayst END */



#if 0
    /* BUP tayst STT */
//typedef struct BupDate {
//	Uint8	year;		/* Year - 1980 */
//	Uint8	month;		/* Month (1~12) */
//	Uint8	day;		/* Day (1~31) */
//	Uint8	time;		/* Hour (0~23) */
//	Uint8	min;		/* Minute (0~59) */
//	Uint8	week;
//}
BupDate date;
unsigned long ret;
int ii;

for(ii=0; ii<8; ii++)
{
if(ii == 0)
{
    date.year  = 0;
    date.month = 0;
    date.day   = 0;
    date.time  = 0;
    date.min   = 0;
    date.week  = 0;
}
else if(ii == 1)
{
    date.year  = 2010 - 1980;
    date.month = 11;
    date.day   = 10;
    date.time  = 0;
    date.min   = 47;
    date.week  = 3;
}
else if(ii == 2)
{
    date.year  = 2010 - 1980;
    date.month = 11;
    date.day   = 10;
    date.time  = 1;
    date.min   = 47;
    date.week  = 3;
}
else if(ii == 3)
{
    date.year  = 2010 - 1980;
    date.month = 11;
    date.day   = 10;
    date.time  = 1;
    date.min   = 46;
    date.week  = 3;
}
else if(ii == 4)
{
    date.year  = 2010 - 1980;
    date.month = 11;
    date.day   = 10;
    date.time  = 1;
    date.min   = 46;
    date.week  = 4;
}
else if(ii == 5)
{
    date.year  = 2010 - 1980;
    date.month = 11;
    date.day   = 11;
    date.time  = 1;
    date.min   = 46;
    date.week  = 4;
}
else if(ii == 6)
{
    date.year  = 2010 - 1980;
    date.month = 12;
    date.day   = 11;
    date.time  = 1;
    date.min   = 46;
    date.week  = 4;
}
else if(ii == 7)
{
    date.year  = 2011 - 1980;
    date.month = 12;
    date.day   = 11;
    date.time  = 1;
    date.min   = 46;
    date.week  = 4;
}
ret = BUP_SetDate(&date);
scd_logout("%4d/%2d/%2d %2d:%2d (%d) => 0x%08X (%d)", date.year+1980, date.month, date.day, date.time, date.min, date.week, ret, ret);
}
#endif

    //char* bupstr = "HELLO";
    //char* bupstr = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In pulvinar molestie elit non consequat. Sed facilisis nibh nec arcu euismod viverra. Mauris quis pretium orci. Sed magna purus, adipiscing vel gravida quis, dictum nec risus. Praesent libero sem, mollis sit amet congue vitae, ornare vel urna. Duis cursus rhoncus lectus, vitae porttitor ligula fermentum sed. Ut nibh odio, rutrum vitae sagittis ut, mattis sed sem. Duis vehicula purus molestie orci gravida quis tincidunt massa luctus. Nullam scelerisque euismod leo, sit amet dictum orci lobortis at. Quisque consequat consectetur dictum. Donec adipiscing ultrices purus, pretium scelerisque turpis adipiscing mattis. Ut in dui lectus. Sed et nisi neque. Vestibulum dignissim vulputate erat at volutpat. Nulla convallis, ipsum vel aliquet tempus, ligula nisl porta nibh, quis euismod nisi ipsum a enim. Sed et velit metus. Phasellus vehicula vehicula elit at tempus. Vestibulum dolor leo, elementum non mattis sit amet, molestie nec tellus. Nam scelerisque enim id metus pulvinar et iaculis leo cursus. Nunc dictum cursus dui sed posuere. Ut mattis vulputate libero. Morbi sodales justo risus. Fusce arcu magna, posuere eu auctor vel, adipiscing vel massa. Pellentesque ultrices lorem vel diam convallis id imperdiet mi lobortis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Integer tortor est, vulputate ut consequat vitae, varius eget purus. Nunc dictum posuere ornare. Duis mollis nulla non augue ornare ac facilisis nunc venenatis. Suspendisse in purus nunc. Aliquam pharetra, nibh a dictum gravida, felis ante adipiscing mi, eget pulvinar purus arcu non turpis. Praesent luctus felis sit amet dolor accumsan ut feugiat velit vehicula. Mauris semper erat leo, sed feugiat velit. Donec sed pulvinar dui. Mauris lacus odio, tempor sed faucibus eu, euismod vitae elit. Maecenas feugiat fringilla tincidunt. Praesent eu metus vitae quam venenatis euismod. Nulla velit lacus, adipiscing nec pulvinar eu, tempus eu orci. Donec dui diam, molestie sit amet elementum ac, lacinia eu libero. Aliquam mauris risus, scelerisque eleifend tristique ut, accumsan eu odio. Maecenas fringilla dapibus nisl in egestas. Nam euismod risus id libero tristique eget viverra velit rutrum. Maecenas eget dui vitae massa varius luctus vel quis turpis. In sagittis sodales nisi. Morbi vitae dolor purus, eu aliquet tortor. Vestibulum euismod neque eget justo elementum varius. Vivamus mauris magna, sodales sit amet ultricies sit amet, dignissim a neque. Aliquam pretium convallis sollicitudin. Nam ut nunc a nisi porta egestas. Vestibulum scelerisque blandit erat vel rhoncus. Donec ac elit eros, eu tempus dui. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aenean risus nulla, venenatis ut consequat a, venenatis eget nunc. Vivamus facilisis metus et metus imperdiet aliquam vel quis dolor. In euismod diam eros.";
    char* bupstr = "ZZZZZZZZZZZZZZZZZZZZZZZZZ";
    //long sc_bup_write(void* data, unsigned long datalen, char* name, char* comment);
    sc_bup_write((void*)bupstr, strlen(bupstr), "TEST0", "COMMENT");
    /* BUP tayst END */




    /* Pad tayst STT */
    scd_logout("1000  ticks  = %d usec", sc_tmr_tick2usec(1000));
    scd_logout("65535 ticks = %d usec", sc_tmr_tick2usec(65535));
    _printf(2, row+0, COLOR_TEAL, "Hit any key !");
    while(1)
    {
        /* SatCom: if needed, transfer data. */
        sc_check();

        /* Wait for V-Blank. */
        wait_vblank_out();
        wait_vblank_in();

        /* Poll joypad */
        pad_read(&pad);

        /* Up */
        _printf( 5, row+1, COLOR_TEAL, " %c", 
                    (pad.new & PAD_UP ? 'U' : ' '));
        /* Left, Right */
        _printf( 5, row+2, COLOR_TEAL, "%c %c", 
                    (pad.new & PAD_LEFT  ? 'L' : ' '), 
                    (pad.new & PAD_RIGHT ? 'R' : ' '));
        /* Down */
        _printf( 5, row+3, COLOR_TEAL, " %c", 
                    (pad.new & PAD_DOWN ? 'D' : ' '));



        /* L,R */
        _printf(20, row+1, COLOR_TEAL, "%c   %c", 
                    (pad.new & PAD_LBUTTON ? 'L' : ' '), 
                    (pad.new & PAD_RBUTTON ? 'R' : ' '));
        /* X,Y,Z */
        _printf(20, row+2, COLOR_TEAL, "%c %c %c", 
                    (pad.new & PAD_X ? 'X' : ' '), 
                    (pad.new & PAD_Y ? 'Y' : ' '), 
                    (pad.new & PAD_Z ? 'Z' : ' '));
        /* A,B,C */
        _printf(20, row+3, COLOR_TEAL, "%c %c %c", 
                    (pad.new & PAD_A ? 'A' : ' '), 
                    (pad.new & PAD_B ? 'B' : ' '), 
                    (pad.new & PAD_C ? 'C' : ' '));

        /* Start */
        _printf(10, row+4, COLOR_TEAL, "%s", (pad.new & PAD_START ? "START" : "     "));

    }






    /* Timer tayst STT */
    unsigned char cntr = 0;
    _printf(2, row++, COLOR_TEAL, "TAYST START");
    while(1)
    {
//#define TEST1
//#define TEST2
#define TEST3

#ifdef TEST1
        /* SatCom: if needed, transfer data. */
        sc_check();

        /* Wait for V-Blank. */
        wait_vblank_out();
        wait_vblank_in();


        sc_tmr_start();
        int pouet = rand();
        _printf(2, row+0, COLOR_TEAL, "-> %02X, T=%7d , P%7d", cntr++, sc_tmr_lap_usec(), pouet);
        pouet+=rand();
        _printf(2, row+1, COLOR_TEAL, "-> %02X, T=%7d , P%7d", cntr++, sc_tmr_lap_usec(), pouet);
        pouet+=rand();
        _printf(2, row+2, COLOR_TEAL, "-> %02X, T=%7d , P%7d", cntr++, sc_tmr_lap_usec(), pouet);
#endif

#ifdef TEST2
        /* Wait for V-Blank. */
        sc_tmr_start();
        wait_vblank_out();
        wait_vblank_in();
        unsigned short delay = sc_tmr_lap_usec();
        _printf(2, row+0, COLOR_TEAL, "-> %02X, T=%7d", cntr++, delay);
#endif

#ifdef TEST3
        sc_tmr_start();
        sc_check();
        unsigned short delay = sc_tmr_lap_usec();
        _printf(2, row+0, COLOR_TEAL, "=> %02X, T=%7d", cntr++, delay);

        /* Wait for V-Blank. */
        wait_vblank_out();
        wait_vblank_in();
#endif
    }
    /* Timer tayst END */




    /* Main loop */
    unsigned short fctr=0;
    for(;;)
    { fctr++;
        int i;

        /* SatCom: if needed, transfer data. */
        sc_check();

        /* Wait for V-Blank. */
        wait_vblank_out();
        wait_vblank_in();

        /* Bump frame counter */
        frame_count++;

        /* Poll joypad */
        pad_read(&pad);


        /* Test debugger: STT */
        if(pad.new & PAD_LBUTTON)
        { /* Send debug message to PC. */
            //scd_logout("**[%d]Test %s %s %s -%d-**", fctr, "crac", "boum", "hue !", 42);
            scd_logout("==FRAME=%d, rand1=0x%04X, rand2=0x%04X", fctr, rand()&0xFFFF, rand()&0xFFFF);
            if(fctr%2 == 0) scd_logout("**[%d]Test2", fctr, 42);
        }
        if(pad.delta & PAD_RBUTTON)
        { /* Prompt message from PC. */
            _printf(2, row-1, COLOR_WHITE, empty_line);
            _printf(2, row-1, COLOR_WHITE, "What's your name ?");
            str = scd_prompt("Your name:");
            _printf(2, row-1, COLOR_WHITE, empty_line);
            _printf(2, row-1, COLOR_WHITE, "Hello %s !", str);

        }
        /* Test debugger: END */


        /* Test CD-ROM: STT */
        if(pad.new & PAD_X)
        { /* Send debug message to PC. */
            /* CD-ROM test. */
            _printf(2, row, COLOR_SILVER, "Start test ...                  ");
            scd_logout("Start ...", 0); scd_logflush();
            sc_file_t* fh1 = NULL;
            sc_file_t* fh2 = NULL;
            sc_file_t* fh3 = NULL;
            unsigned long ret;

            _printf(2, row, COLOR_SILVER, "Start fopen ...                 ");
            scd_logout("fopen ...", 0); // scd_logflush();
            fh1 = sc_fopen(SC_FILE_CDROM, "./FOLDER1/pouet\\file.txt");
            scd_logout("handle1 = %d", fh1); // scd_logflush();
#ifndef SC_RELEASE
            unsigned long s1 = sc_fsize(fh1); // scd_logflush();
#endif
            memset((void*)buff, '\0', sizeof(buff));
            ret = sc_fread(fh1, 0/*offset*/, sizeof(buff)-1/*size*/, (void*)buff/*buff*/);
            scd_logout("READ1 = %d bytes, >%s<", ret, buff); // scd_logflush();

            fh2 = sc_fopen(SC_FILE_CDROM, "FOLDER2/test.txt");
            scd_logout("handle2 = %d", fh2); // scd_logflush();
#ifndef SC_RELEASE
            unsigned long s2 = sc_fsize(fh2); // scd_logflush();
#endif
            memset((void*)buff, '\0', sizeof(buff));
            ret = sc_fread(fh2, 2040/*offset*/, 6000/*size*/, (void*)buff/*buff*/);
            scd_logout("READ2 = %d bytes, >%s<", ret, buff); // scd_logflush();
            sc_fclose(fh2);
            sc_fclose(fh1);

            fh3 = sc_fopen(SC_FILE_CDROM, "abs.txt");
            scd_logout("handle3 = %d", fh3); // scd_logflush();
            unsigned long s3 = sc_fsize(fh3); // scd_logflush();
            memset((void*)buff, '\0', sizeof(buff));
            ret = sc_fread(fh3, 0/*offset*/, sizeof(buff)-1/*size*/, (void*)buff/*buff*/);
            scd_logout("READ3 = %d bytes, >%s<", ret, buff); // scd_logflush();
            sc_fclose(fh3);

            scd_logout("size1 = %d, size2 = %d, size3 = %d", s1, s2, s3); scd_logflush();


            fh3 = sc_fopen(SC_FILE_CDROM, "0.bin");
            scd_logout("handle4 = %d", fh3); // scd_logflush();
            s3 = sc_fsize(fh3); // scd_logflush();
            memset((void*)buff, '\0', sizeof(buff));
            _fread_callback_data.row = row;
            ret = sc_callback_fread(fh3, 0/*offset*/, sizeof(buff)-1/*size*/, (void*)buff/*buff*/, 
                                    10/*callback_count*/, 
                                    fread_callback/*callback_fct*/, (void*)(&_fread_callback_data)/*callback_data*/);
            scd_logout("READ4 = %d bytes", ret); // scd_logflush();
            sc_fclose(fh3);

            _printf(2, row, COLOR_SILVER, "Read test ended !               ");
        }
        /* Test CD-ROM: END */




        /* Start - Quit program */
        if(pad.new & PAD_START)
        { /* Exit to multiplayer. */
            int (*pFun)(void);
            pFun = (int(*)(void))0x600026C;
            (*pFun)();
        }


        /* Print selected protocol. */
        row=datarow;





        /* Move objects */
        for(i=0;i<4;i++)
            update_pos(&foo[i]);

        /* Make new list */
        list_clear();
        list_set_system_clip(320, 224);
        list_set_user_clip(0, 0, 320, 224);
        list_set_local_coords(0, 0);

        MESH(0);
        list_polyline(319,0,319,223,0,223,0,0,COLOR(31,0,0));

        MESH(1);
        list_polygon( \
            foo[0].c[0].x,foo[0].c[0].y, \
            foo[0].c[1].x,foo[0].c[1].y, \
            foo[0].c[2].x,foo[0].c[2].y, \
            foo[0].c[3].x,foo[0].c[3].y, \
            COLOR(15,15,15), 0x60000);

        MESH(0);
        list_polyline( \
            foo[1].c[0].x,foo[1].c[0].y, \
            foo[1].c[1].x,foo[1].c[1].y, \
            foo[1].c[2].x,foo[1].c[2].y, \
            foo[1].c[3].x,foo[1].c[3].y, \
            COLOR(31,0,31));

        list_distorted_sprite( \
            foo[2].c[0].x,foo[2].c[0].y, \
            foo[2].c[1].x,foo[2].c[1].y, \
            foo[2].c[2].x,foo[2].c[2].y, \
            foo[2].c[3].x,foo[2].c[3].y, \
            (0x40000)>>3, TX_W, TX_H);

        list_end();
    }

    vdp_shutdown();
    pad_shutdown();
}

