/******************************************************************************
 * Rage 128 Chapter 4 sample code                                             *
 *                                                                            *
 * pat32.c - This program uses the pattern registers to draw rectangles       *
 * on the screen.                                                             *
 *                                                                            *
 * Copyright (c) 1999 ATI Technologies Inc. All rights reserved.              *
 ******************************************************************************/
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <i86.h>
#include "..\util\regdef.h"
#include "..\util\defines.h"
#include "..\util\main.h"

void R128_CopyPatternData (WORD numdwords, DWORD *data);

DWORD pattern_data [32] = {
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0300C0FF, 0x390080FF,
0x7D0080FF, 0x7D0000FF, 0x7D0000FE, 0x390000FE, 0x030000FC, 0xFF0106F8, 0xFF030FF8, 0xC3030FF0,
0x81031FE0, 0x81033FE0, 0x810323C0, 0x8103C180, 0x8103C180, 0x8103C101, 0x8103C101, 0x8103E303,
0x8103FF07, 0x8103FF07, 0xC387FF8F, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
};

/******************************************************************************
 * Main Program to demonstrate pattern rectangle blts                         *
 *  Function: A 32x32 monochrome pattern is used for a rectangle blt.         *
 *            The BRUSH_Y_X registers are programmed so that the pattern      *
 *            is always aligned to the top left corner of the blt.            *
 *    Inputs: Arguments for mode spatial and colour resolution                *
 *   Outputs: NONE                                                            *
 ******************************************************************************/
void main (int argc, char *argv[])
{
    DWORD width, height, x, y, bppvalue;
    DWORD temp;
    DWORD shiftx, shifty;

    printf ("Rage 128 Chapter 4 sample code\n"
            "\n"
            "pat32.c\n"
            "Pattern registers are used as a source to draw rectangles\n"
            "\n");

    R128_StartUp (argc, argv);

    // clear screen.
    R128_ClearScreen (BLACK);

    // call function to copy pattern data in the the brush data registers
    R128_CopyPatternData (32, &pattern_data);

    // Set up values.
    width = R128_AdapterInfo.xres;
    height = R128_AdapterInfo.yres;
    bppvalue = R128_GetBPPValue (R128_AdapterInfo.bpp);

    // We will use a 32x32 mono pattern, expanding it to the foreground,
    // and background.
    R128_WaitForFifo (1);
    regw (DP_DATATYPE, SRC_DSTCOLOR | BRUSH_32x32MONO | bppvalue);


    while (!kbhit ())
    {
        x = (rand()%(R128_AdapterInfo.xres-64));

        // shiftx determines how much we will have to shift the brushes
        // to position the pattern at the right edge of the rectangle
        shiftx = 32 - x%32;

        width = rand()%(R128_AdapterInfo.xres - x);
        if (width <=32) width = 64;
        y = (rand()%(R128_AdapterInfo.yres));

        // shifty determines how much we will have to shift the brushes
        // to position the pattern at the top edge of the rectangle
        shifty = 32 - y%32;

        height = rand()%(R128_AdapterInfo.yres - y);
        if (height <= 32) height = 64;

        temp = R128_GetColourCode (rand()%NUM_COLOURS);

        R128_WaitForFifo (5);
        regw (DP_BRUSH_FRGD_CLR, temp);
        // write the compliment colour to the background
        regw (DP_BRUSH_BKGD_CLR, ~(temp));

        // We will adjust the brushes so that the pattern
        // is always starting in the top right of the rectangle
        regw (BRUSH_Y_X, (shifty << 8) | shiftx);

        // Draw a filled pattern rectangle.
        regw (DST_Y_X, (y << 16) | x);
        regw (DST_HEIGHT_WIDTH, (height << 16) | width);

        R128_Delay (10);

    }

    // Wait for a carriage return.
    getch ();

    // Batch command to restore old mode.
    R128_ShutDown ();

    exit (0);                           // No errors.

} // main


/****************************************************************************
 * R128_CopyPatternData (WORD numdwords, DWORD *data)                       *
 *  Function: Load the BRUSH_DATAxx registers with the appropriate pattern  *
 *            data.                                                         *
 *    Inputs: WORD numdwords - the number of DWORDs that will be loaded     *
 *            DWORD *data - pointer to the pattern data                     *
 *   Outputs: NONE                                                          *
 ****************************************************************************/
void R128_CopyPatternData (WORD numdwords, DWORD *data)
{
    int i;
    WORD offset;

    for (i = (numdwords - 1); i >= 0; i--)
    {
        R128_WaitForFifo (1);
        offset = BRUSH_DATA0 + (i * 4);
        regw (offset, data[i]);
    }

    return;
} // R128_CopyPatternData ()
