/******************************************************************************
 * mach64 Chapter 6 sample code                                               *
 *                                                                            *
 * fixpat.c - This program uses the pattern registers to draw rectangles      *
 * on the screen.  An 8x8 monochrome pattern, a 4x2 colour pattern, and       *
 * an 8x1 colour pattern is used to draw three rectangles on screen.          *
 *                                                                            *
 * Copyright (c) 1994-1998 ATI Technologies Inc. All rights reserved.         *
 ******************************************************************************/

#include <stdio.h>
#include <i86.h>
#include "..\util\atim64.h"
#include "..\util\defines.h"
#include "..\util\main.h"

/******************************************************************************
 * Main Program to demonstrate simple 1 to 1 bitblits                         *
 *  Function: Three rectangles are drawn on screen using the pattern          *
 *            registers.  A monochrome 8x8 is used to draw a white and        *
 *            magenta patterned rectangle.  A colour 4x2 pattern (8bpp        *
 *            only) is used to draw a blue and white rectangle.  Finally,     *
 *            a colour 8x1 pattern (8bpp only) is used to draw a light        *
 *            red and yellow rectangle.                                       *
 *    Inputs: Arguments for mode spatial and colour resolution                *
 *   Outputs: NONE                                                            *
 ******************************************************************************/

void main (int argc, char *argv[])
{
    int width;                          // Width of drawing area.
    int height;                         // Height of drawing area.

    printf ("mach64 Chapter 6 sample code\n"
            "\n"
            "fixpat.c\n"
            "Pattern registers are used as a source to draw rectangles\n"
            "Three rectangles are drawn on screen using the pattern registers.  A\n"
            "monochrome 8x8 is used to draw a white and magenta patterned rectangle.\n"
            "A colour 4x2 pattern (8bpp only) is used to draw a blue and white\n"
            "rectangle.  Finally, a colour 8x1 pattern (8bpp only) is used to draw\n"
            "a light red and yellow rectangle.\n"
            "\n"
            "Spatial resolution (640, 800, 1024, 1280, 1600) and Colour Depth\n"
            "(8, 15, 16, 24, 32) should be passed as arguments.\n"
            "Default setting is 640x480 spatial resolution and 8bpp pixel depth.\n");

    // Batch command to detect the mach64, perform a hardware query, Save old
    // mode information, process mode info arguments, load and set mode, enable
    // aperture, set up palettes, initialize engine to known state, and reset
    // all engine queues.

    start (argc, argv);

    // Set up values.
    width = 640;                        // Less than or equal to xres.
    height = 480;                       // Less than or equal to yres.

    clear_screen (0, 0, MODE_INFO.xres, MODE_INFO.yres);

    // 8x8 mono pattern.

    // Draw a rectangle filled with an 8x8 monochrome fixed pattern:
    //
    //    A rectangle of size (width1, height1) is drawn at (x1, y1) and
    //    is filled by a colour expanded 8x8 monochrome fixed pattern via
    //    the pattern registers. Wrapping is supported.

    // Pattern orientation is determined by the DP_BYTE_PIXEL_ORDER bit in
    // the DP_PIX_WIDTH register. The default in this example is LSB to MSB.

    // mono source       = mono 8x8 fixed pattern,
    // foreground source = foreground colour,
    // background source = background colour

    // Set mono source to pattern, colour source to foreground colour.
    wait_for_fifo (2);
    regw (DP_SRC, MONO_SRC_PATTERN | FRGD_SRC_FRGD_CLR | BKGD_SRC_BKGD_CLR);

    // Set foreground and background mix to source (overpaint).
    regw (DP_MIX, FRGD_MIX_S | BKGD_MIX_S);

    // Enable 8x8 mono fixed pattern.
    wait_for_fifo (3);
    regw (PAT_CNTL, PAT_MONO_8x8_ENABLE);

    // This is an 8x8 monochrome pattern of a box with a border.
    regw (PAT_REG0, 0x818181FF);
    regw (PAT_REG1, 0xFF818181);

    // Setup foreground and background colours:
    //
    //    foreground colour is used when pattern bit is "1"
    //    background colour is used when pattern bit is "0"
    wait_for_fifo (2);
    regw (DP_FRGD_CLR, get_colour_code (WHITE));
    regw (DP_BKGD_CLR, get_colour_code (LIGHTMAGENTA));

    // Draw a filled pattern rectangle.
    draw_rectangle ((MODE_INFO.xres - width)/2, (MODE_INFO.yres - height)/2,
                    width/3, height);

    // Colour patterns are only supported in 8 bpp modes.
    if (MODE_INFO.bpp == 8)
    {
        // Draw a rectangle filled with an 4x2 colour fixed pattern:
        //    A rectangle of size (width2, height2) is drawn at (x2, y2) and
        //    is filled by a colour 4x2 fixed pattern via the pattern registers.
        //    Note that this fixed pattern is only available in 8bpp modes.
        //    Wrapping is supported.

        // Pattern direction is LSB to MSB for both colour pattern modes.

        // 4x2 colour pattern - only available in 8 bpp modes.

        // Foreground source = colour pattern.

        wait_for_fifo (4);
        regw (DP_SRC, FRGD_SRC_PATTERN);

        // Enable 4x2 colour pattern.

        regw (PAT_CNTL, PAT_CLR_4x2_ENABLE);

        // Setup 4x2 8 bpp colour pattern.
        // 0x09 - LIGHTBLUE, 0x0F - WHITE in 8bpp mode - strip pattern.

        regw (PAT_REG0, 0x0F09090F);
        regw (PAT_REG1, 0x0F09090F);

        // Draw a filled pattern rectangle.

        draw_rectangle (((MODE_INFO.xres - width)/2) + (width/3),
                        (MODE_INFO.yres - height)/2,
                        width / 3, height);

        // 8x1 colour pattern - only available in 8 bpp modes.

        // Draw a rectangle filled with an 8x1 colour fixed pattern:
        //
        //    A rectangle of size (width3, height3) is drawn at (x3, y3) and
        //    is filled by a colour 8x1 fixed pattern via the pattern registers.
        //    Note that this fixed pattern is only available in 8bpp modes.
        //    Wrapping is supported.

        // DP_SRC is set to FRGD_SRC_PATTERN in the 4x2 colour pattern setup.

        // Enable 8x1 colour pattern.

        wait_for_fifo (3);
        regw (PAT_CNTL, PAT_CLR_8x1_ENABLE);

        // Setup 8x1 colour pattern.
        // 0x0C - LIGHTRED, 0x0E - YELLOW in 8bpp - strip pattern.

        regw (PAT_REG0, 0x0C0C0C0E);
        regw (PAT_REG1, 0x0E0C0C0C);

        // Draw a filled pattern rectangle.

        draw_rectangle (((MODE_INFO.xres - width)/2) + (2*width/3),
                        (MODE_INFO.yres - height)/2,
                        width / 3, height);
    } // if

    // Wait for a carriage return.
    getch ();
    
    // Batch command to restore old mode.
    finish ();

    if (MODE_INFO.bpp != 8)
    {
        printf ("The 4x2 and 8x1 colour patterns are only supported in 8 bpp "
                "modes.\n");
    } // if

    exit (0);                           // No errors.

} // main
