/*
**  Misc Functions for TISAN
*/

#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <io.h>
#include <errno.h>
#include <process.h>
#include <math.h>

#include "MAIN.H"

void SETMODE(short,short);
void CURSOR(short,short,short,short);
void BOX(short,short,short,short,short,short);
void XPSET(short,short);
short CALLDOS(void);
extern void GHERCMODE(void);
extern void THERCMODE(void);

extern union REGS REGISTER;
extern short ERRTYPE;
extern long COLOR;
extern short   CS1, CS2, GF1, GF2, GF3;
extern struct DEVICES HARDWARE;
char far *SCREEN;

extern char *MSP[];

/***************************************************************
**
**  Subroutine to Set the Mode of the IBM Graphics Screen
**
**        case 0:  40x25 bw
**        case 1:  40x25 color
**        case 2:  80x25 bw
**        case 3:  80x25 color
**        case 4:  320x200 color
**        case 5:  320x200 bw
**        case 6:  640x200
**        case 7:  HERCULES
*/
void SETMODE(GMODE,COLR)
short GMODE, COLR;
   {
   char far *ZEROP;

   if (HARDWARE.scrn == HERC_scrn)
      {
      FP_SEG(SCREEN) = 0xB000;
      FP_OFF(SCREEN) = 0;
      if (GMODE == 7)
         GHERCMODE();
      else
         {
         THERCMODE();
         REGISTER.x.ax = 3;
         int86(0x10,®ISTER,®ISTER);
         }
      return;
      }

   FP_SEG(SCREEN) = 0xB800;
   FP_OFF(SCREEN) = 0;
   CS1 = 0;
   CS2 = 0;
   FP_OFF(ZEROP) = 0x410;
   FP_SEG(ZEROP) = 0;

   if (HARDWARE.scrn == DUAL_scrn) /* Dual Display */
      {
      if (GMODE > 3) /* Switch to Graphics */
         {
         *ZEROP &= 0xCF;
         *ZEROP |= 0x20;
         }
      else
         *ZEROP |= 0x30; /* Switch to Monochrome */
      }

   REGISTER.h.al = (char)GMODE;
   REGISTER.h.ah = (char)0;
   int86(0x10,®ISTER,®ISTER);

   if (COLR)
      {
      REGISTER.h.ah = (char)11;
      REGISTER.h.bh = (char)0; /* Set Back Ground */
      REGISTER.h.bl = (char)(COLR/10);
      int86(0x10,®ISTER,®ISTER);
      COLR = COLR - 10*(COLR/10);
      COLR = Min((int)COLOR,6);
      COLR = Max((int)COLOR,1);
      REGISTER.h.ah = (char)11;
      REGISTER.h.bh = (char)1; /* Set Palet */
      if (COLR < 4)
         REGISTER.h.bl = (char)(0);
      else
         {
         REGISTER.h.bl = (char)(1);
         COLR -= 3;
         }
      int86(0x10,®ISTER,®ISTER);
      if (COLR > 1) CS1 = 1;
      if (COLR > 2) CS2 = 255;
      GF1 = 2;
      GF2 = 3;
      GF3 = 1;
      }
   else
      {
      GF1 = 3;
      GF2 = 7;
      GF3 = 0;
      }
   return;
   }

/***************************************************************
**
** Function to draw a cross shaped cursor
*/
void CURSOR(XLOC,YLOC,SXMAX,SYMAX)
short XLOC, YLOC, SXMAX, SYMAX;
   {
   short X,Y,XP1,XP2,YP1,YP2;
   char P;

   XP1 = Max(0,XLOC - 8);
   XP2 = Min(SXMAX,XLOC+8);
   YP1 = Max(0,YLOC - 4);
   YP2 = Min(SYMAX,YLOC+4);
   for (X=XP1;X<=XP2;++X) XPSET(X,YLOC);
   for (Y=YP1;Y<=YP2;++Y) XPSET(XLOC,Y);
   return;
   }

/***************************************************************
**
** Function to Frame the Selected Window
*/
void BOX(W0,W1,W2,W3,SXMAX,SYMAX)
short W0, W1, W2, W3, SXMAX, SYMAX;
     {
   short X,Y,XP1,XP2,YP1,YP2;

   XP1 = Min(W0,W2);
   XP2 = Max(W0,W2);
   YP1 = Min(W1,W3);
   YP2 = Max(W1,W3);
   for (X=XP1;X<=XP2;++X)
      {
      XPSET(X,YP1);
      XPSET(X,YP2);
      }
   for (Y=YP1;Y<=YP2;++Y)
      {
      XPSET(XP1,Y);
      XPSET(XP2,Y);
      }
   return;
   }

/***************************************************************
**
** Function to Sound Beeper
*/
void BEEP()
   {
   printf("\a");
   }

/***************************************************************
**
** Function XOR a pixil
*/
void XPSET(X,Y)
short X,Y;
   {
   char P;

   if (HARDWARE.scrn == HERC_scrn)
      {
      FP_OFF(SCREEN) =  HERCpos(X,Y);
      *SCREEN ^= HERCpel(X);
      }
   else
      {
      P = CGApel(X);
      FP_OFF(SCREEN) =  CGApos(X,Y);
      *SCREEN ^= ((P<<CS1) + (P & CS2));
      }
   return;
   }

/***************************************************************
**
** Function to Spawn an MS-DOS Shell
*/
short CALLDOS()
   {
   short ERRFLAG = 0;
   char *COMM = "COMMAND";

   if (spawnlp(P_WAIT,COMM,COMM,NULL) < 0)
      {
      ERRFLAG = 1;
      printf(MSP[1]);
      switch (errno)
         {
         case E2BIG:
            printf(MSP[5]);
            break;
         case EINVAL:
            printf(MSP[12]);
            break;
         case ENOENT:
            printf("'%s.COM' Not Found\n",COMM);
            break;
         case ENOEXEC:
            printf("Invalid '%s.COM' File\n",COMM);
            break;
         case ENOMEM:
            printf(MSP[10],"DOS");
         }
      }
   return(ERRFLAG);
   }