/** 3DGPL *************************************************\
 * A demo allowing to rotate a polygon rendering it as    *
 * either ambient, shaded or textured. ( <TAB> to change  *
 * rendering option ).                                    *
 *                                                        *
 *  If it doesn't work:                                   *
 *   1) make sure you are using right hardware interface  *
 *      source and your system sutisfies requirements     *
 *      described in it's head comment.                   *
 *   2) if this application does quit on <ENTER> but      *
 *      shows nothing, adjust colour intensities assigned *
 *      in main(), hardware interface function doesn't    *
 *      convert them.                                     *
 *   3) if the demo crashes recompile with bigger stack.  *
 *                                                        *
 *  (6/1995) By Sergei Savhenko. (savs@cs.mcgill.ca).     *
 *  Copyright (c) 1995 Sergei Savchenko.                  *
 *  THIS SOURCE CODE CAN'T BE USED FOR COMERCIAL PURPOSES *
 *  WITHOUT AUTHORISATION                                 *
\**********************************************************/

#include <stdio.h>
#include "../hardware/hardware.h"
#include "../engine/engine.h"
#include "../graphics/graphics.h"
#include "../trans/trans.h"

unsigned char alp=0,bet=0,gam=0;
int x=0,y=0,z=200;

unsigned char texture[16][16]=
{
 {0xef,0xee,0xed,0xec,0xeb,0xea,0xe9,0xe8,0xe7,0xe6,0xe5,0xe4,0xe3,0xe2,0xe1,0xe0},
 {0xef,0x55,0x55,0x55,0x55,0x55,0x55,0xe8,0xe7,0x55,0x55,0x55,0x55,0x55,0xe1,0xe0},
 {0xef,0xee,0xed,0xec,0xeb,0x55,0xe9,0xe8,0xe7,0x55,0xe5,0xe4,0xe3,0xe2,0x55,0xe0},
 {0xef,0xee,0xed,0xec,0x55,0xea,0xe9,0xe8,0xe7,0x55,0xe5,0xe4,0xe3,0xe2,0x55,0xe0},
 {0xef,0xee,0xed,0x55,0x55,0x55,0x55,0xe8,0xe7,0x55,0xe5,0xe4,0xe3,0xe2,0x55,0xe0},
 {0xef,0xee,0xed,0xec,0xeb,0xea,0x55,0xe8,0xe7,0x55,0xe5,0xe4,0xe3,0xe2,0x55,0xe0},
 {0xef,0x55,0x55,0x55,0x55,0x55,0xe9,0xe8,0xe7,0x55,0x55,0x55,0x55,0x55,0xe1,0xe0},
 {0xef,0xee,0xed,0xec,0xeb,0xea,0xe9,0xe8,0xe7,0xe6,0xe5,0xe4,0xe3,0xe2,0xe1,0xe0},
 {0xef,0xee,0x77,0x77,0xeb,0xea,0x76,0x76,0x76,0xe6,0xe5,0x75,0xe3,0xe2,0xe1,0xe0},
 {0xef,0x77,0xed,0xec,0x77,0xea,0x76,0xe8,0xe7,0x76,0xe5,0x75,0xe3,0xe2,0xe1,0xe0},
 {0xef,0x77,0xed,0xec,0xeb,0xea,0x76,0xe8,0xe7,0x76,0xe5,0x75,0xe3,0xe2,0xe1,0xe0},
 {0xef,0x77,0xed,0xec,0xeb,0xea,0x76,0xe8,0xe7,0x76,0xe5,0x75,0xe3,0xe2,0xe1,0xe0},
 {0xef,0x77,0xed,0x77,0x77,0xea,0x76,0x76,0x76,0xe6,0xe5,0x75,0xe3,0xe2,0x75,0xe0},
 {0xef,0x77,0xed,0xec,0x77,0xea,0x76,0xe8,0xe7,0xe6,0xe5,0x75,0xe3,0xe2,0x75,0xe0},
 {0xef,0xee,0x77,0x77,0x77,0xea,0x76,0xe8,0xe7,0xe6,0xe5,0x75,0x75,0x75,0x75,0xe0},
 {0xef,0xee,0xed,0xec,0xeb,0xea,0xe9,0xe8,0xe7,0xe6,0xe5,0xe4,0xe3,0xe2,0xe1,0xe0}
};

struct M_polygon a= {M_AMBIENT,56,NULL,0,0,0,0,4,{0,3,6,9,0}};
struct M_polygon s= {M_SHADED,0,NULL,0,0,0,0,4,{0,5,3,42,6,58,9,21,0,11}};
struct M_polygon t= {M_TEXTURED,0,(unsigned char*)texture,4,6,0,3,4,
                    {0,0,64,3,64,64,6,64,0,9,0,0,0,0,64}};
struct M_polygon *p=&t;
int m_no_verteces=4;
int verteces[]={-50,50,0,50,50,0,50,-50,0,-50,-50,0};
int m_no_vectors=2;
int vectors[]={100,0,0,0,100,0};

/**********************************************************\
 * being called to treat key press.                       *
\**********************************************************/

void app_handler(int kk)
{
 switch(kk)
 {
  case HW_KEY_ENTER:       HW_quit_event_loop(); break;
  case HW_KEY_ARROW_RIGHT: gam+=10; break;
  case HW_KEY_ARROW_LEFT:  gam-=10; break;
  case HW_KEY_ARROW_UP:    bet+=10; break;
  case HW_KEY_ARROW_DOWN:  bet-=10; break;
  case 'X': case 'x':      alp+=10; break;
  case 'S': case 's':      alp-=10; break;
  case 'A': case 'a':      z-=10;   break;
  case 'Z': case 'z':      z+=10;   break;
  case HW_KEY_TAB: if(p==&a) p=&s; else if(p==&s) p=&t; else p=&a;
 }
}

/**********************************************************\
 * being called to render a frame.                        *
\**********************************************************/

void app_main(void)
{
 int tmp_verteces[50];
 int tmp_vectors[50];
 char str[100];

 G_clear();

 T_set_self_rotation(alp,bet,gam);
 T_self_rotation(verteces,tmp_verteces,m_no_verteces);
 T_translation(tmp_verteces,tmp_verteces,m_no_verteces,x,y,z);
 T_self_rotation(vectors,tmp_vectors,m_no_vectors);
 M_render_polygon(p,tmp_verteces,tmp_vectors);

 sprintf(str,"3DGPL <%d %d %d %d>",alp,bet,gam,z); G_text(0,0,str,63);
 if(p==&a) G_text(200,0,"AMBIENT",63);
 if(p==&s) G_text(200,0,"SHADED",63);
 if(p==&t) G_text(200,0,"TEXTURED",63);
 G_text(0,190,"<ARROWS> <TAB> <A> <Z> <S> <X> <ENTER>",63);

 HW_blit();
}

/**********************************************************\
 * assignes colours and starts the event loop.            *
\**********************************************************/

int main(void)
{
 struct HW_colour pal[256];
 int i;

 for(i=0;i<256;i++) { pal[i].hw_r=i; pal[i].hw_g=0; pal[i].hw_b=0; }
 HW_open_screen(NULL,"3DGPL",pal,G_init_graphics()); T_init_math();
 HW_run_event_loop(app_main,app_handler);
 HW_close_screen();

 return(1);
}

/**********************************************************/
