/******************************************************************************
 * mach64 Chapter 6 sample code                                               *
 *                                                                            *
 * scissor.c - This program demonstrates the mach64 draw inhibiting           *
 * technique called scissoring or clipping.                                   *
 *                                                                            *
 * Copyright (c) 1994-1998 ATI Technologies Inc.  All rights reserved.        *
 ******************************************************************************/

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


/******************************************************************************
 * Main Program to demonstrate scissoring                                     *
 *  Function: Demonstrates mach64 engine scissor feature.                     *
 *            Scissor context is originally set to size of screen.            *
 *            A white rectangle is drawn centred on the screen, then the      *
 *            scissor context is set up a bit smaller that the white          *
 *            rectangle.  Finally, a red rectangle the same size as the       *
 *            original rectangle is drawn over the first.  You will           *
 *            notice that the scissoring inhibited the drawing of the         *
 *            entire red rectangle on the edges.                              *
 *    Inputs: Arguments for mode spatial and colour resolution                *
 *   Outputs: NONE                                                            *
 ******************************************************************************/

void main (int argc, char *argv[])
{
    int width;                          // Width of rectangle to draw
    int height;                         // Height of rectangle to draw
    int s_width;                        // Width of scissor rectangle
    int s_height;                       // Height of scissor rectangle
    int s_left;                         // Left scissor boundary
    int s_top;                          // Top scissor boundary
    int s_right;                        // Right scissor boundary
    int s_bottom;                       // Bottom scissor boundary

    printf ("mach64 Chapter 6 sample code\n"
            "\n"
            "scissor.c\n"
            "  Scissor context is originally set to the size of screen. A white\n"
            "  rectangle is drawn centred on the screen, then the scissor context\n"
            "  is set up a bit smaller that the white rectangle.  Finally, a red\n"
            "  rectangle the same size as the original rectangle is drawn over the\n"
            "  first.  You will notice that the scissoring inhibited the drawing\n"
            "  of the entire red rectangle on the edges.\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 variables.
    width = 640;                        // Width of rectangle
    height = 480;                       // Height of rectangle
    s_width = width*2/3;                // Smaller than xres
    s_height = height*2/3;              // Smaller than yres

    // Clear screen.
    clear_screen (0, 0, MODE_INFO.xres, MODE_INFO.yres);

    // Set up scissor to be the size of the full screen.
    // Note: could also set it to max values of -4096 and +4095 in x-direction
    // and -16384 and +16383 in y direction so no scissoring takes place.
    s_left = 0;
    s_top = 0;
    s_right = MODE_INFO.xres - 1;
    s_bottom = MODE_INFO.yres - 1;
    
    if (MODE_INFO.bpp == 24)
    {
       s_left = s_left*3;
       s_right = s_right*3;
    } // if
    regw (SC_LEFT, s_left);
    regw (SC_TOP, s_top);
    regw (SC_RIGHT, s_right);
    regw (SC_BOTTOM, s_bottom);

    // Draw white rectangle of size (width x height) in centre of screen.
    wait_for_fifo (1);
    regw (DP_FRGD_CLR, get_colour_code (WHITE));
    draw_rectangle ((MODE_INFO.xres - width)/2,
                    (MODE_INFO.yres - height)/2, width, height);
    
    // wait for carriage return (show screen before next operation
    getch ();

    // Set up scissor as a slightly smaller rectangle also centered.
    s_left = (MODE_INFO.xres - s_width)/2;
    s_top = (MODE_INFO.yres - s_height)/2;
    s_right = ((MODE_INFO.xres + s_width)/2) - 1;
    s_bottom = ((MODE_INFO.yres + s_height)/2) - 1;
    if (MODE_INFO.bpp == 24)
    {
       s_left = s_left*3;
       s_right = s_right*3;
    } // if
    regw (SC_LEFT, s_left);
    regw (SC_TOP, s_top);
    regw (SC_RIGHT, s_right);
    regw (SC_BOTTOM, s_bottom);

    // Draw red rectangle same size and location as original.
    // This red rectangle will be clipped due to scissoring.
    wait_for_fifo (1);
    regw (DP_FRGD_CLR, get_colour_code (LIGHTRED));
    draw_rectangle ((MODE_INFO.xres - width)/2,
                    (MODE_INFO.yres - height)/2, width, height);
    
    // wait for carriage return
    getch ();

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

    exit (0);                           // No errors.

} // main
