/*		   ACK-3D ( Animation Construction Kit 3D )		      */
/* Utility routines   */
/* Author: Lary Myers */

#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <time.h>
#include <string.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <linux/kd.h>
#include <termios.h>
#include "ack3d.h"
#include "ackext.h"


void Beep(void)
{
	putchar('\007');
}

static int fd;
static struct termios oldt, newt;

void WrapUp(void)
{

	fprintf(stderr, "wrapping up\n");
	if (dfp != NULL)
    		fclose(dfp);

	vga_setmode(TEXT);

	if (ioctl(fd, KDSKBMODE, K_XLATE)) {
		perror("KDSKBMODE");
		exit(1);
	}
	tcsetattr(fd, TCSANOW, &oldt);


}

/****************************************************************************
** Allocates memory for the various trig tables and reads in the pre-	   **
** calculated values from "trig.dat".					   **
**									   **
**									   **
****************************************************************************/
int GetTables(void)
{
int	    handle,len;
int	    ca,na;

	LongTanTable = (long *)malloc(sizeof(long) * INT_ANGLE_360);
	LongInvTanTable = (long *)malloc(sizeof(long) * INT_ANGLE_360);
	CosTable = (long *)malloc(sizeof(long) * INT_ANGLE_360);
	SinTable = (long *)malloc(sizeof(long) * INT_ANGLE_360);
	InvSinTable = (long *)malloc(sizeof(long) * INT_ANGLE_360);
	InvCosTable = (long *)malloc(sizeof(long) * INT_ANGLE_360);
	LongCosTable = (long *)malloc(sizeof(long) * INT_ANGLE_360);
	xNextTable = (long *)malloc(sizeof(long) * INT_ANGLE_360);
	yNextTable = (long *)malloc(sizeof(long) * INT_ANGLE_360);
	ViewCosTable = (long *)malloc(sizeof(long) * VIEW_WIDTH);

	if (LongTanTable == NULL ||
	    LongInvTanTable == NULL ||
	    CosTable == NULL ||
	    SinTable == NULL ||
	    InvSinTable == NULL ||
	    InvCosTable == NULL ||
	    LongCosTable == NULL ||
	    xNextTable == NULL ||
	    yNextTable == NULL ||
	    ViewCosTable == NULL) {
    		printf("Unable to get initialization memory!\n");
    		return(-1);
    	}

	len = sizeof(long) * INT_ANGLE_360;
	handle = open("trig.dat",O_RDWR);
	if (handle < 1) {
    		printf("Unable to locate file TRIG.DAT\n");
    		return(-1);
    	}

	read(handle,SinTable,len);
	read(handle,CosTable,len);
	read(handle,LongTanTable,len);
	read(handle,LongInvTanTable,len);
	read(handle,InvCosTable,len);
	read(handle,InvSinTable,len);
	read(handle,LongCosTable,len);

	close(handle);

	ca = INT_ANGLE_30;
	na = -1;

	for (len = 0; len < VIEW_WIDTH; len++) {
    		ViewCosTable[len] = LongCosTable[ca];
    		ca += na;
    		if (ca <= 0) {
			ca = -ca;
			na = -na;
		}
    	}

	for (len = 0; len < INT_ANGLE_360; len++) {
    		yNextTable[len] = (long)GRID_SIZE * LongTanTable[len];
    		xNextTable[len] = (long)GRID_SIZE * LongInvTanTable[len];
    	}

	return(0);
}


void CheckKeyboard(void)
{
int scanCode;
unsigned char ch[1];
fd_set fdset;
struct timeval t;
int r;

#if 0
	FD_ZERO(&fdset);
	FD_SET(fd, &fdset);
	t.tv_sec = 0;
	t.tv_usec = 0;
	r = select(fd+1, &fdset, NULL, NULL, &t);
	if (r == 0)
		return;
#endif
	read(fd, ch, 1);
	scanCode = (int)ch[0];

  	if(scanCode==RIGHT_ARROW_PRESSED)keyBoard.rightArrow=1;
  	if(scanCode==RIGHT_ARROW_RELEASED)keyBoard.rightArrow=0;
  	if(scanCode==UP_ARROW_PRESSED)keyBoard.upArrow=1;
  	if(scanCode==UP_ARROW_RELEASED)keyBoard.upArrow=0;
  	if(scanCode==LEFT_ARROW_PRESSED)keyBoard.leftArrow=1;
  	if(scanCode==LEFT_ARROW_RELEASED)keyBoard.leftArrow=0;
  	if(scanCode==DOWN_ARROW_PRESSED)keyBoard.downArrow=1;
  	if(scanCode==DOWN_ARROW_RELEASED)keyBoard.downArrow=0;
  	if(scanCode==CONTROL_PRESSED)keyBoard.control=1;
  	if(scanCode==CONTROL_RELEASED)keyBoard.control=0;
  	if(scanCode==ESCAPE)keyBoard.escape=1;
  	if(scanCode==PLUS_PRESSED)keyBoard.plus = 1;
  	if(scanCode==PLUS_RELEASED)keyBoard.plus = 0;
  	if(scanCode==MINUS_PRESSED)keyBoard.minus = 1;
  	if(scanCode==MINUS_RELEASED)keyBoard.minus = 0;
  	if(scanCode==LETTER_A_PRESSED)keyBoard.letA = 1;
  	if(scanCode==LETTER_A_RELEASED)keyBoard.letA = 0;
  	if(scanCode==LETTER_S_PRESSED)keyBoard.letS = 1;
  	if(scanCode==LETTER_S_RELEASED)keyBoard.letS = 0;

#if 0
  	if(scanCode==HOME_PRESSED)keyBoard.home=1;
  	if(scanCode==HOME_RELEASED)keyBoard.home=0;
  	if(scanCode==END_PRESSED)keyBoard.end=1;
  	if(scanCode==END_RELEASED)keyBoard.end=0;
  	if(scanCode==PGUP_PRESSED)keyBoard.pgup=1;
  	if(scanCode==PGUP_RELEASED)keyBoard.pgup=0;
  	if(scanCode==PGDN_PRESSED)keyBoard.pgdn=1;
  	if(scanCode==PGDN_RELEASED)keyBoard.pgdn=0;
#endif

}


/****************************************************************************
**									   **
****************************************************************************/
void keyBoardInit(void)
{
	/* set keyboard to return scan codes */
	/* system dependant */
	fprintf(stderr, "initializing keyboard\n");
	if ((fd = open("/dev/console", O_RDONLY)) < 0) {
		perror("/dev/console");
		exit(1);
	}
	tcgetattr(fd, &oldt);
	newt = oldt;
	newt.c_lflag &= ~ (ICANON | ECHO | ISIG);
	newt.c_iflag &= ~ (IXON | IXOFF | ICRNL | INLCR);
	newt.c_cc[VMIN] = 1;
	newt.c_cc[VTIME] = 0;	

	tcsetattr(fd, TCSAFLUSH, &newt);
	if (ioctl(fd, KDSKBMODE, K_MEDIUMRAW)) {
		perror("KDSKBMODE");
		exit(1);
	}

  	keyBoard.rightArrow=0;
  	keyBoard.upArrow=0;
  	keyBoard.leftArrow=0;
  	keyBoard.downArrow=0;
  	keyBoard.control=0;
  	keyBoard.escape=0;
  	numLockKeyStatus=0;
}

/****************************************************************************
** Return the square root of a long value				   **
****************************************************************************/
long long_sqrt(long v)
{
int		i;
unsigned	long result,tmp;
unsigned	long low,high;

	if (v <= 1L) 
		return((unsigned)v);

	low = v;
	high = 0L;
	result = 0;

	for (i = 0; i < 16; i++) {
    		result += result;
    		high = (high << 2) | ((low >>30) & 0x3);
    		low <<= 2;

    		tmp = result + result + 1;
    		if (high >= tmp) {
			result++;
			high -= tmp;
		}
    	}

	if (v - (result * result) >= (result - 1))
    		result++;

	return(result);
}


/****************************************************************************
**									   **
****************************************************************************/
char *GetExtent(char *s)
{
char    *e;

	e = strchr(s,'.');
	if (e == NULL)
    		return(s);
	e++;

	return(e);
}

/****************************************************************************
**									   **
****************************************************************************/
char *StripEndOfLine(char *s)
{
    int	    len;
    char    ch;

	len = strlen(s);

	while (--len >= 0) {
    		ch = s[len];
    		if (ch != ' ' && ch != ';' && ch != '\t' && ch != 13 && ch != 10)
			break;

    		s[len] = '\0';
    	}

	return(s);
}

/****************************************************************************
**									   **
****************************************************************************/
char *SkipSpaces(char *s)
{

	while (*s == ' ' || *s == '\t' || *s == ',')
    		strcpy(s,&s[1]);

	return(s);
}

/****************************************************************************
**									   **
****************************************************************************/
char *AddExtent(char *s,char *ext)
{
	if (strchr(s,'.') == NULL)
    		strcat(s,ext);

	return(s);
}

/****************************************************************************
**									   **
****************************************************************************/
char *CopyToComma(char *dest,char *src)
{
    char    ch;

	while (*src) {
    		ch = *src++;
    		if (ch == ' ' || ch == '\t' || ch == ',')
			break;

    		*dest++ = ch;
    	}

	*dest = '\0';

	return(src);
}

/****************************************************************************
**									   **
****************************************************************************/
void CheckMouse(MOUSE *m)
{
int	    dx,dy;
int	    x,y,buttons;


	if (HaveMouse) {
    		mouse_read_cursor(&buttons,&y,&x);
    		dx = x - 160;
    		dy = y - 120;
    		m->mButtons = buttons;
    		mouse_set_cursor(120,160);

    		if (abs(dy) > 10 && abs(dx) < 32)
			dx >>= 2;

    		m->mdx = dx;
    		m->mdy = dy;

    	}

}

/****************************************************************************
**									   **
****************************************************************************/
unsigned char CheckSpecialCodes(int MapPosn)
{
int i;

	for (i = 0; i < TotalSpecial; i++) {
    	if (SpecialCodes[i].mPos == MapPosn)
		return(SpecialCodes[i].mCode);
    	}

	return(0);
}

