#include <stmutil.h>
#include <pc.h>



int
kb_hit(void)
{
 return kbhit();
}


int
get_a_key()
{
 return getkey();
}

#if 0
void wait(double);

void
utsound(unsigned int freq, unsigned int duration)
{
 sound(freq);
 wait(duration/(double)18.2);
 sound(0);
}

#define NBUF    30

/* -1 means keep default colors */
void
scattrib(int fg, int bg, char ch, unsigned count)
{
 int i;
 char s[NBUF+1];
 long oldbg;
 int oldfg;
 struct rccoord tpos;

 if(bg > 0) {
	 oldbg = _getbkcolor();
	 _setbkcolor((long)bg);
	}
 if(fg > 0) {
	 oldfg = _getcolor();
	 _settextcolor(fg);
	 }
 tpos = _gettextposition();
 for(i=0;i<NBUF;i++)
		s[i] = ch;
 s[i] = '\0';
 for(i=0;i<count/NBUF;i++)
	_outtext(s);
 s[count%NBUF] = '\0';
 if(count%NBUF != 0)
	 _outtext(s);
 _settextposition(tpos.row, tpos.col);
 if(fg > 0)
	 _settextcolor(oldfg);
 if(bg > 0)
	 _setbkcolor(oldbg);
}

/* -1 means keep default colors */
void
output_string(char *buf, int fg, int bg)
{
 long oldbg;
 int oldfg;

 if(bg > 0) {
	 oldbg = _getbkcolor();
	 _setbkcolor((long)bg);
	}
 if(fg > 0) {
	 oldfg = _getcolor();
	 _settextcolor(fg);
	 }
 _outtext(buf);
 if(fg > 0)
	 _settextcolor(oldfg);
 if(bg > 0)
	 _setbkcolor(oldbg);
}

void
cursor_set(int row, int col)
{
 _settextposition(row+1, col+1);
}

void
sccurpos(int *row, int *col)
{
 struct rccoord xy;
 xy = _gettextposition();
 *row = xy.row-1;
 *col = xy.col-1;
}

int kb_hit(void);        /* is there a keystroke in the buffer? <conio.h> */


void
scclear()
{
 _clearscreen(_GCLEARSCREEN);
}

#define SCREEN_ROWS	25
#define SCREEN_COLS 80

struct winblk{                  /* my own window block */
	int ncols;                  /* number of columns in image */
	int nrows;                  /* number of rows in image */
	unsigned char *image;   /* the actual image */
	};

void *
save_screen(int xi, int yi, int xf, int yf)
{
 unsigned r_len, nrows;           /* row length and number of rows*/
 static unsigned lbytes = 2*SCREEN_COLS;    /* number of bytes in whole line*/
 int row;
 unsigned ri;
 struct winblk * ret;

 xf -= 1; yf -= 1;                /* fixes error in gregs addressing */
 assert(xi<=xf&&yi<=yf);          /* checks to see if ranges are valid */
 assert(xi>=0&&yi>=0&&xf<SCREEN_COLS&&yf<SCREEN_ROWS);
 ret = (struct winblk *)malloc(sizeof(struct winblk));
 assert( ret);
 r_len = xf - xi + 1;
 nrows = yf - yi + 1;
 ret->ncols = r_len;
 ret->nrows = nrows;
 ret->image = (unsigned char *)malloc((unsigned)nrows*r_len*2*sizeof(char));
 assert(ret->image != NULL);
 for(row=yi;row <= yf; row++){
	ri = row-yi;
	movedata(0xb800,(unsigned)(row*lbytes+2*xi),FP_SEG(ret->image),
			(unsigned)(FP_OFF(ret->image)+r_len*2*ri), (unsigned)r_len*2);
	}
 return (void *)ret;
}

/* puts stuff back onto the screen (see save_screen ) */
/* restore_screen MUST free the space it is passed */
void
restore_screen(int xi, int yi, int xf, int yf, void *underneath)
{
 struct winblk *under;
 unsigned r_len, nrows;        /* row length and number of rows in window */
 static unsigned lbytes = 2*SCREEN_COLS; /* number of bytes in whole line*/
 int row;
 unsigned char att, sp;
 unsigned char *b_row;
 unsigned ri;

 xf -= 1; yf -= 1;
 assert(xi<=xf&&yi<=yf);          /* checks to see if ranges are valid */
 assert(xi>=0&&yi>=0&&xf<SCREEN_COLS&&yf<SCREEN_ROWS);
 if ( underneath == (void *)0 ){
	att = (unsigned char)7<<4+(unsigned char)0;
	sp = ' ';
	r_len = xf - xi + 1;
	b_row = (unsigned char *)malloc((unsigned)(r_len)*sizeof(char)*2);
	assert(b_row != NULL);
	for(row=0;row<=xf-xi;row++){
		b_row[2*row] = sp;
		b_row[2*row+1] = att;
		}
	for (row = yi; row <= yf; row++){
		ri = row - yi;
		movedata(FP_SEG(b_row), FP_OFF(b_row), (unsigned)0xB800,
				(unsigned)(row*lbytes+2*xi),(unsigned)(r_len*2));
		}
	free(b_row);
	return;
	}
 else{
	under = (struct winblk *) underneath;
	assert( under->image );/* check exists */
	r_len = xf - xi + 1;
	nrows = yf - yi + 1;
	assert( under->nrows == nrows);                 /* same height */
	assert( under->ncols == r_len);                 /* same width */
	for (row = yi; row <= yf; row++){
	   ri = row - yi;
	   movedata(FP_SEG(under->image),
			   (unsigned)(FP_OFF(under->image)+r_len*2*ri), (unsigned)0xB800,
			   (unsigned)(row*lbytes+2*xi), (unsigned)(r_len*2));
	   }
	}
 free(under->image);
 free(under);
}

#endif
