/*********************************************/
/* you just keep on pushing my luck over the */
/*          BOULDER        DASH              */
/*                                           */
/*     Jeroen Houttuin, ETH Zurich, 1990     */
/*                                           */
/*                                           */
/*	  PC-VGA version from :				*/
/*                                           */
/*		Herve SOULARD, Paris, 1990		*/
/*                                           */
/*********************************************/

#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#include <dos.h>
#include <graph.h>

#include "xbd.h"



void (interrupt far *oldVect)();

int count = 0;
Bool startCount = FALSE;
Bool newLevel = FALSE;


void far interrupt newClock()
{
	if (startCount && count)
		count--;
	_chain_intr(oldVect);
}


Bool kbdHit(void)
{ 
	if (*kbdPtrRead == *kbdPtrWrite)
		return(FALSE);
	else
		return(TRUE);
}

void getKbd(byte *TT,byte *T)
{ 
	*T = *(kbdBuffer + *kbdPtrRead);
	if (*T == 0x00 || *T == 0xE0) {
		*T = *(kbdBuffer + *kbdPtrRead + 1);
		*TT = 'F';
	}
	else
		*TT = 'T';
	*kbdPtrRead += 2;
	if (*kbdPtrRead == 0x3E)
		*kbdPtrRead = 0x1E;
}


void init_vars()
{
	blobbreak = 100;
	critical = 100;
	blobcells = 0;
	curorder = STAND;
	gamestop = TRUE;
	scoreobs = TRUE;
	stoplevel = FALSE;
	levelnum = 1;
	speed = 1;
	lives = 4;
	xin = 0;
	yin = 0;
	players = 1;
}


void adapt_timer()
{
	if (speed <= 0)
		speed = 1;
	count = 34 / speed;
}



/* Handle a key stroke by the user. */
void handle_key(byte keytype, byte keyhit)
{
	if (players <= 0) {
		init_level(levelnum);
		adapt_timer();
		stoplevel = FALSE;
		draw_field(TRUE);
		gamestop = TRUE;
		players = 1;
		return;
	}
	if (keytype == 'T') {
		switch (keyhit) {
			case K_SPACE:
				gamestop = !gamestop;
				break;
		}
	}
	else {
		switch (keyhit) {
			case K_LEFT:
				curorder = LEFT;
				gamestop = FALSE;
				break;
			case K_UP:
				curorder = UP;
				gamestop = FALSE;
				break;
			case K_DOWN:
				curorder = DOWN;
				gamestop = FALSE;
				break;
			case K_RIGHT:
				curorder = RIGHT;
				gamestop = FALSE;
				break;
		}
	}
}


/* Function which is called whenever the timer signal goes off */
void ticker()
{
	startCount = FALSE;
	if (curtime)
		curtime--;
	if (tinkact)
		tinkdur--;
	if (curtime % 10 == 1)
		scoreobs = TRUE;

	if (!gamestop) {
		if (newLevel) {
			newLevel = FALSE;
			_clearscreen(_GCLEARSCREEN);
		}
		calculate_field();
		draw_field(0);
	}
	if (stoplevel) {
		init_level(levelnum);
		adapt_timer();
		gamestop = TRUE;
		stoplevel = FALSE;
		newLevel = TRUE;
	}
	adapt_timer();
	startCount = TRUE;
}




void main(argc, argv)
int argc;
char **argv;
{
	long		period;
	char		buf[50];
	int		i;

	byte	keyhit;
	byte	keytype;
	
	init_vars();

	/* scan the command line for executing parameters and flags */
	for (i = 1; i < argc; ++i) {
		if (argv[i][0] == '-') {
			if (argv[i][1] == 'l') {
				if (argv[i][2] == '\0' && i + 1 < argc) {
					sscanf(argv[i + 1], "%d", &levelnum);
					i++;	
				} 
				else
					sscanf(argv[i] + 2, "%d", &levelnum);
			} 
			else {
				printf("usage: xbd [-l <level>] \n");
				exit(1);
			}
		}
	}

	levelstart = levelnum;
	init_level(levelnum);

	oldVect = _dos_getvect(0x1C);
	xstart();

	load();
	
	make_gcs();
	_clearscreen(_GCLEARSCREEN);
	draw_field(TRUE);
	draw_score();

	/* initialize timer structure according to speed */
	adapt_timer();

	startCount = FALSE;
	_dos_setvect(0x1C,newClock);
	
	while (lives > 0) {		/* MAIN LOOP */
		if (!count) 
			ticker();
		if (kbdHit()) {
			getKbd(&keytype,&keyhit);
			if (keytype == 'T') {
				switch (keyhit) {
					case K_ESC:
						xend();
						_dos_setvect(0x1C,oldVect);
						add_score();
						exit(-1);
						break;
					case K_D:
					case K_d:
						curorder = KILL;
						break;
					case K_R:
					case	K_r:
						_clearscreen(_GCLEARSCREEN);
						draw_field(TRUE);
						break;
					default:
						handle_key(keytype,keyhit);
						break;
				}
			}
			/*
				Handle of CTRL key is to be done
				
			if ((*kbdStatus & 0x0F) == CTL_SHIFT) {
				steal = TRUE;
				if (keytype == 'T') {
					switch (keyhit) {
						case K_C:
						case K_U:
						case K_c:
						case K_u:
							xend();
							_dos_setvect(0x1C,oldVect);
							add_score();
							exit(-1);
							break;
						case K_D:
						case K_d:
							curorder = KILL;
						case K_R:
						case	K_r:
							draw_field(TRUE);
							break;
						default:
							handle_key(keytype,keyhit);
							break;
					}
				}
			}
			*/
			else
				handle_key(keytype,keyhit);
		}
		if (!gamestop)
			startCount = TRUE;
	}
	xend();
	_dos_setvect(0x1C,oldVect);
	add_score();
	exit(-1);
}


