/*		   ACK-3D ( Animation Construction Kit 3D )		      */
/* Utility routines   */
/* Author: Lary Myers */

#include <stdlib.h>
#include <stdio.h>
#include <dos.h>
#include <mem.h>
#include <alloc.h>
#include <io.h>
#include <fcntl.h>
#include <time.h>
#include <string.h>
#include <sys\stat.h>
#include "ack3d.h"
#include "ackext.h"


/****************************************************************************
**									   **
****************************************************************************/
void Beep(void)
{
sound(440);
delay(20);
nosound();
}

/****************************************************************************
**									   **
****************************************************************************/
void WrapUp(void)
{

if (dfp != NULL)
    fclose(dfp);

textmode(3);
setvect(KEYBD,oldvec);

}

/****************************************************************************
** 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 far *)malloc(sizeof(long) * INT_ANGLE_360);
LongInvTanTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
CosTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
SinTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
InvSinTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
InvCosTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
LongCosTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
xNextTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
yNextTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
ViewCosTable = (long far *)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|O_BINARY);
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);
}

/****************************************************************************
** Checks the scancode from the INT 9 interrupt and sets the appropriate   **
** item in the keyboard structure.					   **
****************************************************************************/
void keyCheck(void)
{
  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

}


/****************************************************************************
** Keyboard interrupt 9							   **
****************************************************************************/
void interrupt myInt(void)
{
  register char x;

  scanCode = inp(0x60); // read keyboard data port
  x = inp(0x61);
  outp(0x61, (x | 0x80));
  outp(0x61, x);
  outp(0x20, 0x20);
  keyCheck();
}

/****************************************************************************
**									   **
****************************************************************************/
void keyBoardInit(void)
{
  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);
}

