/****************************************************************************
 * RAGE128 Chapter 6 Sample Code                                            *
 *                                                                          *
 * bitblt.c - This program demonstrates how to use Rage 128 Type-3 command  *
 * packets to blit rectangles from a source area to a destination area.     *
 *                                                                          *
 * 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 "..\..\chap5\util\cceutil.h"
#include "..\..\chap5\util\agp.h"
#include "..\util\cce.h"

extern DWORD BPPOverride;

extern RBINFO RingBuf;
extern BUFINFO VertexBuf;
extern DWORD ring_buf_offset;
extern GART_INFO *PCIGartInfo;

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

void main (int argc, char *argv[])
{
    DWORD* Buf;
    DWORD CommandBuf [4];
    WORD srcx, srcy, dstx, dsty, bpp;
    int test;
    int i, j, idstxy;
    _img_info IMG_DATA;
    DWORD iboffset;

    printf ("Rage 128 Sample Code, Chapter 6.\n"
        "BITBLT.EXE\n\n"
        "This program demonstrates how to use Rage 128 Type-3 command packets\n"
        "to blit rectangles.\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 ();

    // Set 32 BPP colour depth.

    BPPOverride = 32; 

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

    R128_StartUp (argc, argv);

    if (R128_AdapterInfo.xres <= 320)
    {
        R128_ShutDown ();
        printf ("\nThis program requires a resolution of at least 400x300.");
        printf ("\nProgram terminated.");
        exit (1);
    }

    // Clear the screen

    R128_ClearScreen (BLACK);

    // Set up the source data co-ordinates.
    srcx = 0;
    srcy = R128_AdapterInfo.yres;
    bpp = R128_GetBPPValue (R128_AdapterInfo.bpp);

    // Load the source image file into offscreen memory.

    IMG_DATA = Load_Image (TRAJECTORY_RECTANGULAR, bpp, srcx, srcy);

    // Initialize the CCE microengine.

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

    Buf = R128_GetIndirectBufferPtr ();
    iboffset = R128_GetIndirectBufferOffset ();

    // Set up a rectangle packet and fill the header with packet size
    // Note that packet size is two less than total number of packets sent

    i = 0;

    Buf[i++] = CCE_PACKET3_CNTL_BITBLT;

    // N.B. With the current microcode CCE_PACKET3_CNTL_BITBLT_MULTI
    // does exactly the same operation as CCE_PACKET3_CNTL_BITBLT,
    // i.e., the packet parameters are source-x, source-y (1st packet),
    // dest-x, dest-y (2nd packet), and width, height (3rd packet).

    // Compose GUI_CONTROL

    Buf[i++] = CCE_GC_BRUSH_NONE | CCE_GC_SRC_DSTCOLOR | ROP3_SRCCOPY |
               CCE_GC_DP_SRC_RECT | (R128_GetBPPValue (R128_AdapterInfo.bpp) << 8);

    dstx = 0;
    dsty = 0;

    // Fill rectangle data into packet

    Buf[i++] = (srcx << 16) + srcy;

    idstxy = i;

    Buf[i++] = (dstx << 16) + dsty;
    Buf[i++] = (IMG_DATA.width << 16) + IMG_DATA.height;

    Buf[0] |= ((i - 2) << 16);

    if (i & 1)
        Buf[i++] = CCE_PACKET2;

    CommandBuf[0] = CCE_PACKET0 | (PM4_IW_INDOFF >> 2) | (0x1L << 16);
	CommandBuf[1] = iboffset;
	CommandBuf[2] = i;
    test = R128_CCESubmitPackets (CommandBuf, 3);

    getch ();

    dstx = IMG_DATA.width;
    dsty = 0;
    Buf[idstxy] = (dstx << 16) + dsty;

    test = R128_CCESubmitPackets (CommandBuf, 3);

    getch ();

    dstx = 0;
    dsty = IMG_DATA.height;
    Buf[idstxy] = (dstx << 16) + dsty;

    test = R128_CCESubmitPackets (CommandBuf, 3);

    getch ();

    dstx = IMG_DATA.width;
    dsty = IMG_DATA.height;
    Buf[idstxy] = (dstx << 16) + dsty;

    test = R128_CCESubmitPackets (CommandBuf, 3);

    getch ();

    // Shut down the microengine.

    R128_CCEEnd (CCE_END_WAIT);
    R128_ShutDown ();

    return;
} // main
