/****************************************************************************
 * RAGE128 Chapter 6 Sample Code                                            *
 *                                                                          *
 * line3d.c - This program demonstrates how to draw a line list primitive   *
 * using Rage 128 CCE Type-3 command packets.                               *           
 *                                                                          *
 * Copyright (c) 1999 ATI Technologies Inc.  All rights reserved.           *
 ****************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <i86.h>
#include <conio.h>
#include <math.h>
#include "..\..\util\regdef.h"
#include "..\..\util\defines.h"
#include "..\..\util\main.h"
#include "..\..\util\cce.h"
#include "..\util\cntx3d.h"
#include "..\util\prim.h"

#define NUM_LINES 40
#define PI_X_2 6.28319f

char gErrMsg [64] = {0};

extern DWORD BPPOverride; // Override default 8bpp mode in Chap 3 lib.


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

void main (int argc, char *argv[])
{
    int i, exitcode = 0;
    PRIMDATA linelist;
    float centerx, centery, radius, angle, deltaangle, sinval, cosval;

    printf ("Rage 128 Sample Code, Chapter 6.\n"
        "LINE.EXE\n\n"
        "This program demonstrates how to draw a line list using Rage 128\n"
        "CCE Type-3 command packets.\n\n"
        "Mode resolution (eg 640 480) and colour depth (15, 16, 32)\n"
        "should be passed as command line arguments.\n"
        "Default resolution and colour depth is 640x480, 32bpp.\n\n"
        "Press any key to continue.\n\n");

    getch ();

    // Inspect arguments for invalid color depth.

    for (i = 1; i < argc; i++)
    {
        if ((strcmp (argv[i], "8") == 0) || (strcmp (argv[i], "24") == 0))
		{
			printf ("\nThis program does not operate at 8 or 24 bpp.");
			printf ("\nProgram terminated.");
			exit (1);
		}
	}

    // Override default 8bpp mode in Chap 3 lib.

    BPPOverride = 32;

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

    R128_StartUp (argc, argv);

    // Clear the screen

    R128_ClearScreen (BLACK);

    // Initialize the CCE microengine.

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

	// Set the default 3D context.

    R128_Init3DContext ();

	// Allocate a buffer for point vertices.

    linelist.verts = (TLVERTEX2*) malloc (NUM_LINES * 2 * sizeof (TLVERTEX2));
	if (linelist.verts == NULL)
	{
        sprintf (gErrMsg, "linelist malloc failed!!");
        exitcode = 1;
        goto exit_app;
	}

	// Set count of vertices.

    linelist.numverts = NUM_LINES * 2;

	centerx = R128_AdapterInfo.xres/2.0f;
	centery = R128_AdapterInfo.yres/2.0f; 
	radius = (centery * 0.9f); 
	angle = 0.0f;
    deltaangle = PI_X_2/((float) NUM_LINES * 2);

    for (i=0; i < NUM_LINES; i++)
    {
		sinval = (float)sin ((double)angle);
		cosval = (float)cos ((double)angle);

		linelist.verts[i*2].x = centerx + (sinval * radius);
		linelist.verts[i*2].y = centery - (cosval * radius);
		linelist.verts[i*2].z = 0.5f;
		linelist.verts[i*2].rhw = 1.0f;
		linelist.verts[i*2].diffuse = 0x00ffffff;
		linelist.verts[i*2].specular = 0x00000000;
		linelist.verts[i*2].s2 = linelist.verts[i*2].s1 = 
		linelist.verts[i*2].t2 = linelist.verts[i*2].t1 = 0.0f;

		linelist.verts[(i*2)+1].x = centerx - (sinval * radius);
		linelist.verts[(i*2)+1].y = centery + (cosval * radius);
		linelist.verts[(i*2)+1].z = 0.5f;
		linelist.verts[(i*2)+1].rhw = 1.0f;
		linelist.verts[(i*2)+1].diffuse = 0x00ffffff;
		linelist.verts[(i*2)+1].specular = 0x00000000;
		linelist.verts[(i*2)+1].s2 = linelist.verts[(i*2)+1].s1 = 
		linelist.verts[(i*2)+1].t2 = linelist.verts[(i*2)+1].t1 = 0.0f;

		angle += deltaangle;
    }

    // Draw the line list.

    ATTEMPT (R128_DrawLineList (&linelist),
        "DrawLineList failed!!")

	// Wait for key press to exit.

    getch ();

exit_app:

	// Close 3D context, shut down micro-engine and restore original mode.

	R128_Close3DContext ();
    R128_CCEEnd (CCE_END_WAIT);
    R128_ShutDown ();

	// print error message if any.

	if (exitcode == 1)
		printf ("%s\n", gErrMsg);

	exit (exitcode);
} // main


