// mirror.c
//
// This is meant to be compiled with Quick C for Windows version 1.0
// (the makefile will not work with other make utilities)
//
// Mirror - Dynalink zum Betreiben der Spiegeloptik für den Fahrsimulator über
// das Gerät von Josef Bernhardt. ACHTUNG: Die Spiegelschwenkmetrik (Schwenken auf
// bestimmte Winkelgradauslenkung) funktioniert nur für den von mir durchgeführten
// Versuchsaufbau. Es handelt sich auch nicht um die tatsächliche Spiegelauslenkung,
// sondern um den (theoretischen, simulierten) HeadingAngle-Fehler. Dabei gilt für
// meinen Aufbau: Um eine HeadingAngle-Änderung um 1 Winkelgrad zu simulieren, muß
// der Spiegel um 0.5 Winkelgrad versetzt werden. 1 WINKELGRAD HEADINGCHANGE IST
// 21.73913043 EINZELSCHRITTE bei der Spiegelansteuerung.
// Dabei wurde nicht exakt gerechnet, was aber wurscht ist: der Spiegel erreicht
// ohnehin nicht die Genauigkeit der Berechnung, wie sie jetzt durchgeführt wird,
// sondern positioniert tatsächlich wesentlich ungenauer.

// Nach jedem abgeschickten Befehl gibt das Gerät echomäßig den abgeschickten Befehl zurück

#include <windows.h>
#include <stdlib.h>
#include <memory.h>
#include "mirror.h"

// Globals
const double ONEDEGISSTEPS = 21.73913043;
static int NCom;                                   // Communication device handle
static COMSTAT Comstat;
static BYTE readBuffer[INQUEUSIZE];
static char ComName[5];                            // Name der Schnittstelle (COM1 - COM4)

// Local helpers
void explainError(int errCode);

// Using a WEP speeds up dll termination
int FAR PASCAL _WEP(int idExit)
{
  return 1;
}

BOOL FAR PASCAL MIRRORSetupCommunication(LPSTR comName)
{
  static DCB dcb;               // A device control block

  if (lstrlen(comName) != 4)
  {
    MessageBox(NULL,"Argument must consist of 4, e.g. COM1","MIRROR.DLL SetupCommunication error",MB_ICONHAND);
    return FALSE;
  }
  else
  {
    lstrcpy(ComName,comName);
  }

  NCom=OpenComm(ComName,INQUEUSIZE,OUTQUEUSIZE); // Lieber spät als nie !

  if (NCom < 0)
  {
    switch (NCom)
    {
      case IE_BADID:
           MessageBox(NULL,"Invalid or unsupported ID","MIRROR.DLL OpenComm error",MB_ICONHAND);
           return FALSE;

      case IE_BAUDRATE:
           MessageBox(NULL,"Unsupported baud rate","MIRROR.DLL OpenComm error",MB_ICONHAND);
           return FALSE;

      case IE_BYTESIZE:
           MessageBox(NULL,"Invalid byte size","MIRROR.DLL OpenComm error",MB_ICONHAND);
           return FALSE;

      case IE_DEFAULT:
           MessageBox(NULL,"Error in default parameters","MIRROR.DLL OpenComm error",MB_ICONHAND);
           return FALSE;

      case IE_HARDWARE:
           MessageBox(NULL,"Hardware not present","MIRROR.DLL OpenComm error",MB_ICONHAND);
           return FALSE;

      case IE_MEMORY:
           MessageBox(NULL,"Unable allocate queues","MIRROR.DLL OpenComm error",MB_ICONHAND);
           return FALSE;

      case IE_NOPEN:
           MessageBox(NULL,"Device not open","MIRROR.DLL OpenComm error",MB_ICONHAND);
           return FALSE;

      case IE_OPEN:
           MessageBox(NULL,"Device already open","MIRROR.DLL OpenComm error",MB_ICONHAND);
           return FALSE;
    }
  }

  // Configure COMx
  if (GetCommState(NCom,&dcb) < 0)
  {
    MessageBox(NULL,"Unable to read settings","MIRROR.DLL GetCommState error",MB_ICONHAND);
    return FALSE;
  }

  dcb.BaudRate=9600;
  dcb.ByteSize=8;
  dcb.Parity=NOPARITY;
  dcb.StopBits=TWOSTOPBITS;
  dcb.fBinary=0;
  dcb.fRtsDisable=1;
  dcb.fParity=0;
  dcb.fOutxCtsFlow=0;
  dcb.fOutxDsrFlow=0;
  dcb.fDtrDisable=1;
  dcb.fOutX=0;
  dcb.fInX=0;
  dcb.fPeChar=0;
  dcb.fNull=0;
  dcb.fChEvt=0;
  dcb.fDtrflow=0; // In meiner windows.h steht abweichend zur Docu nicht fDtrFlow
  dcb.fRtsflow=0; // In meiner windows.h steht abweichend zur Docu nicht fRtsFlow

  if (SetCommState(&dcb) < 0)
  {
    MessageBox(NULL,"Unable to set communication device","MIRROR.DLL SetCommState error",MB_ICONHAND);
    return FALSE;
  }

  return TRUE;
}

void FAR PASCAL MIRRORPosExtremeRight(void)
{
  TransmitCommChar(NCom,'1');

  // Antwort abwarten
  do
  {
    GetCommError(NCom,&Comstat);
  } while(Comstat.cbInQue < 1);

  // Antwort lesen
  ReadComm(NCom,readBuffer,INQUEUSIZE);

  // Antwort wegwerfen
  _fmemset(readBuffer,0x00,INQUEUSIZE);
}

void FAR PASCAL MIRRORPosExtremeLeft(void)
{
  TransmitCommChar(NCom,'3');

  // Antwort abwarten
  do
  {
    GetCommError(NCom,&Comstat);
  } while(Comstat.cbInQue < 1);

  // Antwort lesen
  ReadComm(NCom,readBuffer,INQUEUSIZE);

  // Antwort wegwerfen
  _fmemset(readBuffer,0x00,INQUEUSIZE);
}

// Immer beim Start aufzurufen
void FAR PASCAL MIRRORPosMiddle(void)
{
  TransmitCommChar(NCom,'2');

  // Antwort abwarten
  do
  {
    GetCommError(NCom,&Comstat);
  } while(Comstat.cbInQue < 1);

  // Antwort lesen
  ReadComm(NCom,readBuffer,INQUEUSIZE);

  // Antwort wegwerfen
  _fmemset(readBuffer,0x00,INQUEUSIZE);
}

void FAR PASCAL MIRRORPosSignedSingleStep(char step)
{
  switch (step)
  {
    case '+':
         TransmitCommChar(NCom,'a');
         break;

    case '-':
         TransmitCommChar(NCom,'A');
         break;
  }

  // Antwort abwarten
  do
  {
    GetCommError(NCom,&Comstat);
  } while(Comstat.cbInQue < 1);

  // Antwort lesen
  ReadComm(NCom,readBuffer,INQUEUSIZE);

  // Antwort wegwerfen
  _fmemset(readBuffer,0x00,INQUEUSIZE);
}

// targetPosition ist der zu simulierende HeadingAngle in Winkelgrad (das ist nicht identisch
// mit der Spiegelauslenkung, sondern hängt stark vom Versuchsaufbau ab)
// target Position-Werte < 0 bezeichnen Winkel LINKS von der 0-Stellung,
// target Position-Werte > 0 bezeichnen Winkel RECHTS von der 0-Stellung.
// Um Vibrationen zu vermeiden ist die Anzahl der abgesetzten Befehle an
// Sepp´s Gerät zu minimieren; die Funktion macht daher nur Schritte in die
// richtige Richtung. Mag primitiv wirken, ist aber Ergebnis eines langen
// Optimierungsprozesses: es geht wirklichz nicht besser.
void FAR PASCAL MIRRORPosAbsolute(double targetPosition)
{
  static double target;               // theoreticalPosition in Josef Bernhard´s Einheiten
  static int seppDegrees;             // theoreticalPosition in Josef Bernhard´s Einheiten
  static int seppStatus;              // tatsächliche Spiegelposition in Josef Bernhard´s Einheiten
  static int marschBefehl;            // Vorzeichenbehafter zurückzulegender Weg

  // Links == 2000 Mitte == 1500 Rechts == 1000
  target = 1500. - targetPosition*ONEDEGISSTEPS;
  seppDegrees = (int) target;

  // Später wird eine Vierstellige Zahl "sXXXX" als Antwort auf 's' erwartet, daher können
  // Positionen < 1000 gar nicht verarbeitet werden. Sie sind auch nicht nötig.
  if (seppDegrees < 1000 || seppDegrees > 2000)
  {
    return; // Out of range, rejected !
  }

  // Eingabeschlange leerlesen
  ReadComm(NCom,readBuffer,INQUEUSIZE);
  _fmemset(readBuffer,0x00,INQUEUSIZE);

  // Abwarten, bis Ausgabeschlange leer ist (sonst sind frühere Befehle noch nicht abgeschickt)
  do
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  // Status anfordern
  TransmitCommChar(NCom,'0'); // '0' == Statusabfrage

  // Antwort abwarten (es wird 's' gefolgt von einer vierstelligen Zahl erwartet)
  do
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbInQue < 4); // old: 5

  _fmemset(readBuffer,0x00,INQUEUSIZE);
  ReadComm(NCom,readBuffer,INQUEUSIZE);

  // Interpretation des String als Zahl, überlese das führende 's'
  seppStatus=atoi(readBuffer); // old: readBuffer+1

  // Möglichst schnell den Zielwert herstellen
  if ((marschBefehl = seppDegrees-seppStatus) > 0) // zu weit rechts
  {
    switch(marschBefehl)
    {
      case   1:
      case   2:
      case   3:
      case   4: break; // Nichtstun, Zittergefahr bei Mini-Schritten vermeiden
      case   5: left5(&marschBefehl); break;
      case   6:
      case   7:
      case   8:
      case   9:
      case  10: left10(&marschBefehl); break;
      case  11:
      case  12:
      case  13:
      case  14:
      case  15: left15(&marschBefehl); break;
      case  16:
      case  17:
      case  18:
      case  19:
      case  20: left20(&marschBefehl); break;
      case  21:
      case  22:
      case  23:
      case  24:
      case  25: left25(&marschBefehl); break;
      case  26:
      case  27:
      case  28:
      case  29:
      case  30: left30(&marschBefehl); break;
      case  31:
      case  32:
      case  33:
      case  34:
      case  35: left35(&marschBefehl); break;
      case  36:
      case  37:
      case  38:
      case  39:
      case  40: left40(&marschBefehl); break;
      case  41:
      case  42:
      case  43:
      case  44:
      case  45: left45(&marschBefehl); break;
      case  46:
      case  47:
      case  48:
      case  49:
      case  50: left50(&marschBefehl); break;
      case  51:
      case  52:
      case  53:
      case  54:
      case  55: left55(&marschBefehl); break;
      case  56:
      case  57:
      case  58:
      case  59:
      case  60: left60(&marschBefehl); break;
      case  61:
      case  62:
      case  63:
      case  64:
      case  65: left65(&marschBefehl); break;
      case  66:
      case  67:
      case  68:
      case  69:
      case  70: left70(&marschBefehl); break;
      case  71:
      case  72:
      case  73:
      case  74:
      case  75: left75(&marschBefehl); break;
      case  76:
      case  77:
      case  78:
      case  79:
      case  80: left80(&marschBefehl); break;
      case  81:
      case  82:
      case  83:
      case  84:
      case  85: left85(&marschBefehl); break;
      case  86:
      case  87:
      case  88:
      case  89:
      case  90: left90(&marschBefehl); break;
      case  91:
      case  92:
      case  93:
      case  94:
      case  95: left95(&marschBefehl); break;
      case  96:
      case  97:
      case  98:
      case  99:
      case 100: left100(&marschBefehl); break;
       default: left100(&marschBefehl); break; // > 100, kann kaum vorkommen
    }
  }
  else if (marschBefehl < 0)                         // zu weit links
  {
    switch(marschBefehl)
    {
      case   -1:
      case   -2:
      case   -3:
      case   -4: break; // Nichtstun, Zittergefahr bei Mini-Schritten vermeiden
      case   -5: right5(&marschBefehl); break;
      case   -6:
      case   -7:
      case   -8:
      case   -9:
      case  -10: right10(&marschBefehl); break;
      case  -11:
      case  -12:
      case  -13:
      case  -14:
      case  -15: right15(&marschBefehl); break;
      case  -16:
      case  -17:
      case  -18:
      case  -19:
      case  -20: right20(&marschBefehl); break;
      case  -21:
      case  -22:
      case  -23:
      case  -24:
      case  -25: right25(&marschBefehl); break;
      case  -26:
      case  -27:
      case  -28:
      case  -29:
      case  -30: right30(&marschBefehl); break;
      case  -31:
      case  -32:
      case  -33:
      case  -34:
      case  -35: right35(&marschBefehl); break;
      case  -36:
      case  -37:
      case  -38:
      case  -39:
      case  -40: right40(&marschBefehl); break;
      case  -41:
      case  -42:
      case  -43:
      case  -44:
      case  -45: right45(&marschBefehl); break;
      case  -46:
      case  -47:
      case  -48:
      case  -49:
      case  -50: right50(&marschBefehl); break;
      case  -51:
      case  -52:
      case  -53:
      case  -54:
      case  -55: right55(&marschBefehl); break;
      case  -56:
      case  -57:
      case  -58:
      case  -59:
      case  -60: right60(&marschBefehl); break;
      case  -61:
      case  -62:
      case  -63:
      case  -64:
      case  -65: right65(&marschBefehl); break;
      case  -66:
      case  -67:
      case  -68:
      case  -69:
      case  -70: right70(&marschBefehl); break;
      case  -71:
      case  -72:
      case  -73:
      case  -74:
      case  -75: right75(&marschBefehl); break;
      case  -76:
      case  -77:
      case  -78:
      case  -79:
      case  -80: right80(&marschBefehl); break;
      case  -81:
      case  -82:
      case  -83:
      case  -84:
      case  -85: right85(&marschBefehl); break;
      case  -86:
      case  -87:
      case  -88:
      case  -89:
      case  -90: right90(&marschBefehl); break;
      case  -91:
      case  -92:
      case  -93:
      case  -94:
      case  -95: right95(&marschBefehl); break;
      case  -96:
      case  -97:
      case  -98:
      case  -99:
      case -100: right100(&marschBefehl); break;
        default: right100(&marschBefehl); break; // < 100, kann kaum vorkommen
    }
  }
}

void FAR PASCAL MIRRORShutDownCommunication(void)
{
  if (CloseComm(NCom))
  {
    MessageBox(NULL,"Cannot close serial communication","MIRROR.DLL error",MB_ICONEXCLAMATION);
  }
}

void explainError(int errCode)
{
  static COMSTAT comstat;
  static int ec;

  ec=GetCommError(NCom,&comstat);

  if (ec & CE_BREAK)
    MessageBox(NULL,"CE_BREAK","MIRROR.DLL Communications Error",MB_ICONHAND);

  if (ec & CE_CTSTO)
    MessageBox(NULL,"CE_CTSTO","MIRROR.DLL Communications Error",MB_ICONHAND);

  if (ec & CE_DNS)
    MessageBox(NULL,"CE_DNS","MIRROR.DLL Communications Error",MB_ICONHAND);

  if (ec & CE_DSRTO)
    MessageBox(NULL,"CE_DSRTO","MIRROR.DLL Communications Error",MB_ICONHAND);

  if (ec & CE_FRAME)
    MessageBox(NULL,"CE_FRAME","MIRROR.DLL Communications Error",MB_ICONHAND);

  if (ec & CE_IOE)
    MessageBox(NULL,"CE_IOE","MIRROR.DLL Communications Error",MB_ICONHAND);

  if (ec & CE_MODE)
    MessageBox(NULL,"CE_MODE","MIRROR.DLL Communications Error",MB_ICONHAND);

  if (ec & CE_OOP)
    MessageBox(NULL,"CE_OOP","MIRROR.DLL Communications Error",MB_ICONHAND);

  if (ec & CE_OVERRUN)
    MessageBox(NULL,"CE_OVERRUN","MIRROR.DLL Communications Error",MB_ICONHAND);

  if (ec & CE_PTO)
    MessageBox(NULL,"CE_PTO","MIRROR.DLL Communications Error",MB_ICONHAND);

  if (ec & CE_RLSDTO)
    MessageBox(NULL,"CE_RLSDTO","MIRROR.DLL Communications Error",MB_ICONHAND);

  if (ec & CE_RXOVER)
    MessageBox(NULL,"CE_RXOVER","MIRROR.DLL Communications Error",MB_ICONHAND);

  if (ec & CE_RXPARITY)
    MessageBox(NULL,"CE_RXPARITY","MIRROR.DLL Communications Error",MB_ICONHAND);

  if (ec & CE_TXFULL)
    MessageBox(NULL,"CE_TXFULL","MIRROR.DLL Communications Error",MB_ICONHAND);

  if (comstat.fCtsHold)
    MessageBox(NULL,"comstat.fCtsHold is set","MIRROR.DLL Communications Error",MB_ICONHAND);

  if (comstat.fDsrHold)
    MessageBox(NULL,"comstat.fDsrHold is set","MIRROR.DLL Communications Error",MB_ICONHAND);

  if (comstat.fRlsdHold)
    MessageBox(NULL,"comstat.fRlsdHold is set","MIRROR.DLL Communications Error",MB_ICONHAND);

  if (comstat.fXoffHold)
    MessageBox(NULL,"comstat.fXoffHold is set","MIRROR.DLL Communications Error",MB_ICONHAND);

  if (comstat.fXoffSent)
    MessageBox(NULL,"comstat.fXoffSent is set","MIRROR.DLL Communications Error",MB_ICONHAND);

  if (comstat.fEof)
    MessageBox(NULL,"comstat.fEof is set","MIRROR.DLL Communications Error",MB_ICONHAND);

  if (comstat.fTxim)
    MessageBox(NULL,"comstat.fTxim is set","MIRROR.DLL Communications Error",MB_ICONHAND);

  {
    static char strBuf[128];

    wsprintf(strBuf,"%u bytes in receive queue",comstat.cbInQue);
    MessageBox(NULL,strBuf,"comstat.cbInQue",MB_ICONHAND);

    wsprintf(strBuf,"%u bytes in transmit queue, %d bytes written",comstat.cbOutQue,abs(errCode));
    MessageBox(NULL,strBuf,"comstat.cbOutQue",MB_ICONHAND);
  }
}

void left100(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'u'); // +100

  *totalWay -= 100;
}

void left95(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'t'); // +95

  *totalWay -= 95;
}

void left90(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'s'); // +90

  *totalWay -= 90;
}

void left85(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'r'); // +85

  *totalWay -= 85;
}

void left80(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'q'); // +80

  *totalWay -= 80;
}

void left75(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'p'); // +75

  *totalWay -= 75;
}

void left70(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'o'); // +70

  *totalWay -= 70;
}

void left65(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'n'); // +65

  *totalWay -= 65;
}

void left60(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'m'); // +60

  *totalWay -= 60;
}

void left55(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'l'); // +55

  *totalWay -= 55;
}

void left50(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'k'); // +50

  *totalWay -= 50;
}

void left45(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'j'); // +45

  *totalWay -= 45;
}

void left40(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'i'); // +40

  *totalWay -= 40;
}

void left35(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'h'); // +35

  *totalWay -= 35;
}

void left30(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'g'); // +30

  *totalWay -= 30;
}

void left25(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'f'); // +25

  *totalWay -= 25;
}

void left20(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'e'); // +20

  *totalWay -= 20;
}

void left15(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'d'); // +15

  *totalWay -= 15;
}

void left10(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'c'); // +10

  *totalWay -= 10;
}

void left5(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'b'); // +5

  *totalWay -= 5;
}

void left1(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'a'); // +1

  *totalWay -= 1;
}

void right100(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'U'); // -100

  *totalWay += 100;
}

void right95(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'T'); // -95

  *totalWay += 95;
}

void right90(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'S'); // -90

  *totalWay += 90;
}

void right85(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'R'); // -85

  *totalWay += 85;
}

void right80(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'Q'); // -80

  *totalWay += 80;
}

void right75(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'P'); // -75

  *totalWay += 75;
}

void right70(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'O'); // -70

  *totalWay += 70;
}

void right65(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'N'); // -65

  *totalWay += 65;
}

void right60(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'M'); // -60

  *totalWay += 60;
}

void right55(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'L'); // -55

  *totalWay += 55;
}

void right50(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'K'); // -50

  *totalWay += 50;
}

void right45(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'J'); // -45

  *totalWay += 45;
}

void right40(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'I'); // -40

  *totalWay += 40;
}

void right35(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'H'); // -35

  *totalWay += 35;
}

void right30(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'G'); // -30

  *totalWay += 30;
}

void right25(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'F'); // -25

  *totalWay += 25;
}

void right20(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'E'); // -20

  *totalWay += 20;
}

void right15(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'D'); // -15

  *totalWay += 15;
}

void right10(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'C'); // -10

  *totalWay += 10;
}

void right5(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'B'); // -5

  *totalWay += 5;
}

void right1(int *totalWay)
{
  do // Warten bis Ausgabeschlange leer
  {
    GetCommError(NCom,&Comstat);
  } while (Comstat.cbOutQue != 0);

  TransmitCommChar(NCom,'A'); // -1

  *totalWay += 1;
}

void waitMSECS(DWORD msecs)
{
  DWORD offStart;
  DWORD start = timeGetTime();

  do
  {
    offStart = timeGetTime();
    offStart -= start;
  } while (offStart < msecs);
}

