#include <stdio.h>
#include <math.h>
#include <graphics.h>
#include <conio.h>
#include <dos.h>
#define rotate 3
#define speed 0.12

typedef struct
{
float x, y;
} vec;

typedef struct
{
int num;
vec array[3];
} form;

typedef struct
{
vec pixel;
int view; // ship direction.
vec move; // move direction.
form make; // make form.
form dos; // screen points.
} image;

image viper;

void array(vec*dest,vec*scr,int degree) // return dest - points to x, y floats.
{
double rad; // radius.
rad=degree*0.01745;
dest->x=scr->x*cos(rad)-scr->y*sin(rad); // standard library functions.
dest->y=scr->x*sin(rad)+scr->y*cos(rad);
}

void mode(image*var) // return value of type image.
{
int i;
for(i=0;i<var->make.num;i++) // rotate.
{
array(&var->dos.array[i],&var->make.array[i],var->view);
var->dos.array[i].x+=var->pixel.x;
var->dos.array[i].y+=var->pixel.y;
}
}

void draw(image*var)
{
int i;
for(i=1;i<var->make.num;i++)
{
line(var->dos.array[i-1].x,var->dos.array[i-1].y,
var->dos.array[i].x,var->dos.array[i].y);
}
line(var->dos.array[i-1].x,var->dos.array[i-1].y,
var->dos.array[0].x,var->dos.array[0].y);
}

void power(image*var)
{
var->pixel.x+=var->move.x;var->pixel.y+=var->move.y; // move.
if(var->pixel.x<0)var->pixel.x=var->pixel.x+640; // border.
if(var->pixel.x>639)var->pixel.x=var->pixel.x-640;
if(var->pixel.y<0)var->pixel.y=var->pixel.y+480;
if(var->pixel.y>479)var->pixel.y=var->pixel.y-480;
}

void hold(){while(inp(0x3da)&8);while(!(inp(0x3da)&8)); } // prevent flash.

void init(void)
{
int GraphicsDriver=VGA;
int GraphicsMode=VGAHI;
initgraph(&GraphicsDriver,&GraphicsMode,NULL);
setwritemode(XOR_PUT);
viper.make.num = 3;
viper.make.array[ 0 ].x = 0; viper.make.array[ 0 ].y = -16; // coords.
viper.make.array[ 1 ].x = -8; viper.make.array[ 1 ].y = +8;
viper.make.array[ 2 ].x = +8; viper.make.array[ 2 ].y = +8;
viper.view = 0; viper.pixel.x = 320; viper.pixel.y = 240; // center.
viper.move.x = 0; viper.move.y = 0;
}

void main(void)
{
int c=0; unsigned short keyboard;
init();
while(c!='q'&&c!='Q')
{
mode(&viper);draw(&viper);
keyboard = *(unsigned short far *)MK_FP( 0x40, 0x17 );
power(&viper);
if(kbhit()){c=getch();}
if(keyboard&0x0002)
{viper.view-=rotate;if(viper.view<0)viper.view=360-rotate;}
if(keyboard&0x0001)
{viper.view+=rotate;if(viper.view>359)viper.view=0 +rotate;}
if(keyboard&0x0008)
{
double rad; rad = viper.view*0.01745;
viper.move.x+=sin(rad)*speed;viper.move.y-=cos(rad)*speed;
}
hold();draw(&viper);

}
closegraph();
}