/******************************************************************************
 * RAGE128 Chapter 5 Sample Code                                              *
 *                                                                            *
 * type1.c -  This program demonstrates the Concurrent Command Execution      *
 * (CCE) programming model by drawing a series of rectangles using CCE        *
 * Programmed I/O mode and Type-1 packets.                                    *
 *                                                                            *
 * Copyright (c) 1999 ATI Technologies Inc.  All rights reserved.             *
 ******************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <i86.h>
#include <conio.h>
#include "..\util\regdef.h"
#include "..\util\defines.h"
#include "..\util\main.h"
#include "..\util\cce.h"


/******************************************************************************
 * main                                                                       *
 *  Function: Main loop.                                                      *
 *    Inputs: none                                                            *
 *   Outputs: none                                                            *
 ******************************************************************************/

void main (int argc, char *argv[])
{
    int test;
    DWORD Buf[20];
    DWORD x, y, width, height, colour;

    printf ("Rage 128 Sample Code, Chapter 5.\n"
            "TYPE1.EXE\n\n"
            "This program will demonstrate using Type-1 packets with the CCE\n"
            "microengine of the Rage 128.\n\n"
            "Mode resolution (eg 640 480) and colour depth (8, 15, 16, 24, 32)\n"
            "should be passed as command line arguments.\n"
            "Default resolution and colour depth is 640x480, 8bpp.\n\n"
            "Press any key to continue.\n\n");
    getch ();

    // First, run StartUp function to set up the application

    R128_StartUp (argc, argv);

    // Clear the screen

    R128_ClearScreen (BLACK);

    // Initialize the CCE microengine.

    if (R128_CCEInit (CCE_MODE_192PIO) != CCE_SUCCESS)
    {
        R128_ShutDown ();
        printf ("R128_CCEInit failed!!\n");
        exit (1);
    } // if

    while (!kbhit ())
    {
        x = (rand () % (R128_AdapterInfo.xres));
        y = (rand () % (R128_AdapterInfo.yres));
        width = rand () % (R128_AdapterInfo.xres - x);
        height = rand () % (R128_AdapterInfo.yres - y);
        colour = R128_GetColourCode (rand () % NUM_COLOURS);

        // Set up a packet for the brush colour and x, y.  Since Type-1 packets
        // need to be pairs of registers, it will be necessary to send out an
        // even number of register writes.  Note that register indices are in
        // DWORD offsets, hence the ">> 2".

        Buf[0] = CCE_PACKET1 | ((DST_Y_X >> 2) << 11) | (DP_BRUSH_FRGD_CLR >> 2);
        Buf[1] = colour;
        Buf[2] = x + (y << 16);

        // Set up a packet for the rectangle height, width.  Since
        // DST_HEIGHT_WIDTH is the only real register that we are writing, we
        // need to write out a dummy value to a scratch register to satisfy the
        // packet requirements.

        Buf[3] = CCE_PACKET1 | ((GUI_SCRATCH_REG0 >> 2) << 11) | (DST_HEIGHT_WIDTH >> 2);
        Buf[4] = width + (height << 16);
        Buf[5] = 0x00000000;

        test = R128_CCESubmitPackets (Buf, 6);
    } // while

    getch ();

    // Shut down the microengine.

    R128_CCEEnd (CCE_END_WAIT);
    R128_ShutDown ();

    return;
} // main
