/******************************************************************************
 * mach64 Chapter 6 sample code                                               *
 *                                                                            *
 * cursor.c - demonstrates the mach64 hardware cursor.                        *
 *                                                                            *
 * 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"

// 8x8 Cursor bitmap - 8 x 1 word/line.

unsigned int cursor8x8[8] =
{
    0x0000,
    0x3FFC,
    0x355C,
    0x369C,
    0x369C,
    0x355C,
    0x3FFC,
    0x0000
};

// 16x16 Cursor bitmap - 16 x 2 words/line.

unsigned int cursor16x16[32] =
{
    0x0000, 0x0000,
    0x0000, 0x0000,
    0xFFF0, 0x0FFF,
    0xFFF0, 0x0FFF,
    0x55F0, 0x0F55,
    0x55F0, 0x0F55,
    0xA5F0, 0x0F5A,
    0xA5F0, 0x0F5A,
    0xA5F0, 0x0F5A,
    0xA5F0, 0x0F5A,
    0x55F0, 0x0F55,
    0x55F0, 0x0F55,
    0xFFF0, 0x0FFF,
    0xFFF0, 0x0FFF,
    0x0000, 0x0000,
    0x0000, 0x0000
};

// 32x32 Cursor bitmap - 32 x 4 words/line.

unsigned int cursor32x32[128] =
{
    0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000,
    0xFF00, 0xFFFF, 0xFFFF, 0x00FF,
    0xFF00, 0xFFFF, 0xFFFF, 0x00FF,
    0xFF00, 0xFFFF, 0xFFFF, 0x00FF,
    0xFF00, 0xFFFF, 0xFFFF, 0x00FF,
    0xFF00, 0x5555, 0x5555, 0x00FF,
    0xFF00, 0x5555, 0x5555, 0x00FF,
    0xFF00, 0x5555, 0x5555, 0x00FF,
    0xFF00, 0x5555, 0x5555, 0x00FF,
    0xFF00, 0xAA55, 0x55AA, 0x00FF,
    0xFF00, 0xAA55, 0x55AA, 0x00FF,
    0xFF00, 0xAA55, 0x55AA, 0x00FF,
    0xFF00, 0xAA55, 0x55AA, 0x00FF,
    0xFF00, 0xAA55, 0x55AA, 0x00FF,
    0xFF00, 0xAA55, 0x55AA, 0x00FF,
    0xFF00, 0xAA55, 0x55AA, 0x00FF,
    0xFF00, 0xAA55, 0x55AA, 0x00FF,
    0xFF00, 0x5555, 0x5555, 0x00FF,
    0xFF00, 0x5555, 0x5555, 0x00FF,
    0xFF00, 0x5555, 0x5555, 0x00FF,
    0xFF00, 0x5555, 0x5555, 0x00FF,
    0xFF00, 0xFFFF, 0xFFFF, 0x00FF,
    0xFF00, 0xFFFF, 0xFFFF, 0x00FF,
    0xFF00, 0xFFFF, 0xFFFF, 0x00FF,
    0xFF00, 0xFFFF, 0xFFFF, 0x00FF,
    0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000
};

// 64x64 Cursor bitmap - 64 x 8 words/line.

unsigned int cursor64x64[512] =
{
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0x5555, 0x5555, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0x5555, 0x5555, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0x5555, 0x5555, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0x5555, 0x5555, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0x5555, 0x5555, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0x5555, 0x5555, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0x5555, 0x5555, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0x5555, 0x5555, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0xAAAA, 0xAAAA, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0xAAAA, 0xAAAA, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0xAAAA, 0xAAAA, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0xAAAA, 0xAAAA, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0xAAAA, 0xAAAA, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0xAAAA, 0xAAAA, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0xAAAA, 0xAAAA, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0xAAAA, 0xAAAA, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0xAAAA, 0xAAAA, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0xAAAA, 0xAAAA, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0xAAAA, 0xAAAA, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0xAAAA, 0xAAAA, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0xAAAA, 0xAAAA, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0xAAAA, 0xAAAA, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0xAAAA, 0xAAAA, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0xAAAA, 0xAAAA, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0x5555, 0x5555, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0x5555, 0x5555, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0x5555, 0x5555, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0x5555, 0x5555, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0x5555, 0x5555, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0x5555, 0x5555, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0x5555, 0x5555, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0x5555, 0x5555, 0x5555, 0x5555, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
    0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
};


/******************************************************************************
 * Main Program to demonstrate use of the hardware cursor                     *
 *  Function: The screen is filled with red.  The cursor data is located      *
 *            10 lines up from the bottom of the screen.                      *
 *    Inputs: Arguments for mode spatial and colour resolution                *
 *   Outputs: NONE                                                            *
 *     Notes: see ..\util\hwcursor.c for all the routines ised here           *
 ******************************************************************************/

void main (int argc, char *argv[])
{
    printf ("mach64 Chapter 6 sample code\n"
            "\n"
            "cursor.c\n"
            "This  program demonstrates the hardware cursor.  Colour 0 is\n"
            "LIGHTBLUE, and colour 1 is YELLOW.  The background is Red, making it's\n"
            "complement cyan.  The cursor bitmap consists of concentric squares,\n"
            "from the outside-in of colour0(00), 1's complement(11), colour1(01),\n"
            "and transparent(10).\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);

    // Paint the screen with DARKRED.
    wait_for_fifo (1);
    regw (DP_FRGD_CLR, get_colour_code (DARKRED));
    draw_rectangle (0, 0, MODE_INFO.xres, MODE_INFO.yres);

    // The hardware cursor definition requires 2 bits per pixel. The cursor
    // size regardless of the visible cursor size is 64 pixels x 64 lines.
    // The total memory required to define the cursor is 16 bytes / line
    // for 64 lines or 1024 bytes of data. The data must be in a contigious
    // format. The 2 bit cursor code values are as follows:
    //
    //   00 - pixel colour = CURSOR_CLR_0
    //   01 - pixel colour = CURSOR_CLR_1
    //   10 - pixel colour = transparent (current display pixel)
    //   11 - pixel colour = 1's complement of current display pixel

    // ---- Use 16 bpp to draw the cursor data information. ----
    //
    // By programming the starting address ('offset'), all destination draw
    // operations will start at this address. This is useful for setting up
    // data that is resolution and colour depth independent.

    // The cursor data area will be first filled with 'transparent code'
    // data. Cursor data that is transparent will not be visible when the
    // hardware cursor is enabled. Secondly, the cursor pattern will be drawn
    // to the appropriate area within the cursor data area. Note that the
    // cursor data is in linearized format. It can be thought of as a
    // rectangle whose lines are joined contigiously together in memory.

    // Setup a 32x32 hardware cursor and set the cursor's hot spot to the
    // center of the cursor. The cursor data will be visible at the bottom
    // of the screen.

    set_hwcursor (MODE_INFO.yres - 10, 32, 32, 16, 16,
                  get_colour_code (LIGHTBLUE), get_colour_code (YELLOW),
                  cursor32x32);

    // Set the hardware cursor's hot spot to the center of the screen.
    set_hwcursor_pos ((MODE_INFO.xres / 2) - (32 / 2),
                      (MODE_INFO.yres / 2) - (32 / 2));

    // Enable the hardware cursor.
    enable_hwcursor ();

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

    // Set the hardware cursor's hot spot to the upper left corner of
    // the screen.

    set_hwcursor_pos (0, 0);

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

    // Set the hardware cursor's hot spot to the lower right corner of
    // the screen.
    set_hwcursor_pos (MODE_INFO.xres - 1, MODE_INFO.yres - 1);

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

    // Disable the hardware cursor.
    disable_hwcursor ();

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

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

    exit (0);                           // No errors.

} // main
