#include<exec/types.h>
#include<intuition/intuitionbase.h>
#include<graphics/gfxbase.h>
#include<libraries/dos.h>
#include<hardware/custom.h>

#define off_display *(WORD*)0xdff096=0x0300
#define on_display  *(WORD*)0xdff096=0x8300

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Library *ArpBase;
extern ULONG FileRequest();
extern void quad();
#pragma libcall ArpBase FileRequest 126 801
char path[34],filename[34];
ULONG DiskfontBase;

struct FileRequester
{ char *FR_Hail;
  char *FR_File;
  char *FR_Dir;
  struct Window *FR_Window;
  BYTE FR_FuncFlags;
  BYTE FR_Reserved1;
  APTR FR_Function;
  LONG FR_Reserved2;
};
   
struct FileRequester FileReq=
{ "",filename,path,NULL,0,0,NULL,0};

extern void OpenVGraph(),CloseVGraph(),load();
extern void separieren(),analysis(),zeigRicht(),TexteEin();
extern void inventur(),GVert(),Zeit();

#define MAXLENGTH 32000 /*Größe der Texte*/

/* Definition des Kommunikationsfensters */

/* Menüstruktur : */

struct IntuiText text13 =
  {
   0,
   1,
   JAM1,
   8,
   1,
   NULL,
   (UBYTE *) "Spiel beenden",
   NULL
  };                       

struct MenuItem unter13 =
  {
   NULL,
   0,
   36,
   208,
   10,
   ITEMTEXT|ITEMENABLED|HIGHCOMP,
   0,
   (APTR) &text13,
   NULL,
   0,
   NULL,  /*Untermenüs*/
   0
  };

struct IntuiText text12 =
  {
   0,
   1,
   JAM1,
   8,
   1,
   NULL,
   (UBYTE *) "Neubeginn",
   NULL
  };                                  /*Menüpunkt Nachladen*/

struct MenuItem unter12 =
  {
   &unter13,
   0,
   24,
   208,
   10,
   ITEMTEXT|ITEMENABLED|HIGHCOMP,
   0,
   (APTR) &text12,
   NULL,
   0,
   NULL,  /*Untermenüs*/
   0
  };

struct IntuiText text11 =
  {
   0,
   1,
   JAM1,
   8,
   1,
   NULL,
   (UBYTE *) "Spielstand laden",
   NULL
  };

struct MenuItem unter11 =     /* Menüpunkt : Grafik */
  {
   &unter12,
   0,
   12,
   208,
   10,
   ITEMTEXT|ITEMENABLED|HIGHCOMP,
   0,
   (APTR) &text11,
   NULL,
   0,
   NULL,
   0
  };
struct IntuiText text10 =
  {
   0,
   1,
   JAM1,
   8,
   1,
   NULL,
   (UBYTE *) "Spielstand sichern",
   NULL
  };

struct MenuItem unter10 =
  {
   &unter11,
   0,
   0,
   208,
   10,
   ITEMTEXT|ITEMENABLED|HIGHCOMP,
   0,
   (APTR) &text10,
   NULL,
   0,
   NULL,
   0
  };

struct IntuiText text22 =
  {
   0,
   1,
   JAM1,
   8,
   1,
   NULL,
   (UBYTE *) "Hilfe",
   NULL
  };

struct MenuItem unter22 =     /* Menüpunkt Speicher-Clear */
  {
   NULL,
   0,
   24,
   208,
   10,
   ITEMTEXT|ITEMENABLED|HIGHCOMP,
   0,
   (APTR) &text22,
   NULL,
   0,
   NULL,
   0
  };

struct IntuiText text21 =
  {
   0,
   1,
   JAM1,
   8,
   1,
   NULL,
   (UBYTE *) "Inventur",
   NULL
  };

struct MenuItem unter21 =     /* Menüpunkt (varlist) */
  {
   &unter22,
   0,
   12,
   208,
   10,
   ITEMTEXT|ITEMENABLED|HIGHCOMP,
   0,
   (APTR) &text21,
   NULL,
   0,
   NULL,
   0
  };
struct IntuiText text20 =
  {
   0,
   1,
   JAM1,
   8,
   1,
   NULL,
   (UBYTE *) "Richtungen",
   NULL
  };

struct MenuItem unter20 =
  {
   &unter21,
   0,
   0,
   208,
   10,
   ITEMTEXT|ITEMENABLED|HIGHCOMP,
   0,
   (APTR) &text20,
   NULL,
   0,
   NULL,
   0
  };

struct IntuiText text30 =
  {
   0,
   1,
   JAM1,
   8,
   1,
   NULL,
   (UBYTE *) "Infos",
   NULL
  };

struct MenuItem unter30 =     /* Abbruch */
  {
   NULL,
   0,
   0,
   208,
   10,
   ITEMTEXT|ITEMENABLED|HIGHCOMP,
   0,
   (APTR) &text30,
   NULL,
   0,
   NULL,
   0
  };

struct Menu ober3 =
  {
   NULL,
   400,
   0,
   200,
   10,
   MENUENABLED,
   "übers' Spiel",
   &unter30
  };

struct Menu ober2 =
  {
   &ober3,
   200,
   0,
   200,
   10,
   MENUENABLED,
   "Hilfen",
   &unter20
  };

struct Menu ober1 = /*Anfang der Menü-Struktur*/
  {
   &ober2,
   0,
   0,
   200,
   10,
   MENUENABLED,
   "Funktionen",
   &unter10
  };


struct NewScreen NS = { 0,600,640,161,2,3,2,HIRES,CUSTOMSCREEN,NULL,
   "",NULL,NULL };

struct NewScreen GS = { 0,600,640,160,4,0,0,HIRES,CUSTOMSCREEN,NULL,
   "",NULL,NULL };
   
struct NewWindow NW=
{ 0,0,640,160,3,2,
  MENUPICK|RAWKEY,
  ACTIVATE|BORDERLESS,
  NULL,NULL,"",NULL,NULL,100,50,640,255,CUSTOMSCREEN };
struct NewWindow NDW=
{ 0,0,640,30,0,0,
  NULL,
  BORDERLESS,
  NULL,NULL,"",NULL,NULL,100,50,640,256,CUSTOMSCREEN };

#define MaxAnzahl 100
struct Window *Display,*W1,*W2;  
struct Screen *Screen,*GScreen,*GScreenB;

/* zur Textausgabe : */
struct IntuiText iText={ 1,0,JAM2,0,0,NULL,"",NULL };
struct IntuiText Prompt={ 1,0,JAM2,0,0,NULL,">",NULL };

BYTE CFlag; /*zeigt an, wie die Eingabe beendet wurde*/

char *Texte; /*Zeiger auf die Ausgabetexte*/

void ex()
{ CloseLibrary(ArpBase); CloseLibrary(GfxBase); CloseLibrary(IntuitionBase); 
}
   
char lastline[82]; /* letzte Eingabe */
   
struct Screen* Screens[20];

UBYTE *Bilder1,*Bilder2;   
void oeffnen()
{  ULONG handle,laenge;
   UBYTE *Marke=4711;
   extern void ReadPics();
   struct Screen *TitelScreen=0;
   int i=0;
   BYTE *z;
   /*void Titel();*/

   ArpBase=OpenLibrary("arp.library",0);
   if(!ArpBase) exit(0);
   GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",0l);
   IntuitionBase=(struct IntuitionBase*)OpenLibrary("intuition.library",0l);

   /* jetzt feststellen, welche Screens vorhanden sind*/
   Screens[0]=IntuitionBase->FirstScreen;
   if(Screens[0]->UserData==Marke) 
   { TitelScreen=Screens[0]; Screens[0]=Screens[0]->NextScreen; }
   while(Screens[i]!=NULL) { Screens[i+1]=Screens[i]->NextScreen; 
                             if(Screens[i+1])
                             { if(Screens[i+1]->UserData==Marke)
                               { TitelScreen=Screens[i+1];
                                 Screens[i+1]=TitelScreen->NextScreen;
                               }  
                             } 
                             i++; }

   if(!(GScreen=OpenScreen(&GS))) ex();
   if(!(Screen=OpenScreen(&NS))) {CloseScreen(GScreen);ex();};
   if(!(GScreenB=OpenScreen(&GS))) { CloseScreen(Screen); CloseScreen(GScreen);ex();}
   SetRGB4(&Screen->ViewPort,0,0,2,4);
   SetRGB4(&Screen->ViewPort,1,14,14,14);
   SetRGB4(&Screen->ViewPort,3,15,11,0);
   SetRGB4(&Screen->ViewPort,2,2,8,8);
   for(i=0;i<16;i++)
   {  SetRGB4(&GScreen->ViewPort,i,0,2,4);
      SetRGB4(&GScreenB->ViewPort,i,0,2,4);
   } 
   SetRGB4(&GScreenB->ViewPort,5,15,15,15);
   SetRGB4(&GScreenB->ViewPort,6,7,7,7);

   NW.Screen=Screen;
   NDW.Screen=GScreen;
   OpenVGraph();

   if(!(W1=OpenWindow(&NDW))) 
   { CloseVGraph(); CloseScreen(GScreenB); CloseScreen(GScreen); CloseScreen(Screen); ex(); }

   NDW.Screen=GScreenB;
   if(!(W2=OpenWindow(&NDW))) 
   { CloseWindow(W1); CloseVGraph(); CloseScreen(GScreenB); CloseScreen(GScreen); CloseScreen(Screen); ex(); }
  
   if(!(Display=OpenWindow(&NW))) 
   { CloseWindow(W1); CloseWindow(W2);
     CloseVGraph(); CloseScreen(GScreenB); CloseScreen(GScreen); CloseScreen(Screen); ex(); }
  /* Titel();*/
   if(!(Texte=AllocMem(MAXLENGTH,0x1))) 
   { CloseVGraph(); CloseWindow(Display);
     CloseScreen(GScreenB); CloseScreen(GScreen); CloseScreen(Screen); 
     ex(); 
   }

   handle=Open("Texte.ADV",MODE_OLDFILE);
   if(handle>0)
   {  laenge=Read(handle,Texte,MAXLENGTH);
      Close(handle);
      z=Texte;
      for(i=0;i<laenge;i++)
      { *z=*z^178; z++; }
   }
   else
   { FreeMem(Texte,MAXLENGTH); CloseVGraph(); CloseWindow(Display);
     CloseScreen(GScreen); CloseScreen(GScreenB); CloseScreen(Screen); CloseLibrary(ArpBase); 
     ex(); 
   }  
   SetMenuStrip(Display,&ober1);  

   TexteEin();
   strcpy(path,":");
   strcpy(filename,"Spielstand");
   lastline[0]=0;
   Bilder1=AllocMem(100000L,1L);
   if(Bilder1)
   { Bilder2=AllocMem(100000L,1L);
     if(!Bilder2) { FreeMem(Bilder1,100000L); Bilder1=0L; }
   }
   if(Bilder1) ReadPics();    
   MoveScreen(GScreenB,0,-600);
   MoveScreen(GScreen,0,-600);
   MoveScreen(Screen,0,-600);
   MoveScreen(Screen,0,136);
   if(TitelScreen) 
   { if(TitelScreen->FirstWindow)
       CloseWindow(TitelScreen->FirstWindow);
     CloseScreen(TitelScreen); 
   }
}

char NameOfTheGame[]="Huitzilopochtli";

/*
void Titel()
{ extern BYTE MausKlick();
  int i; 
  struct TextFont *textfont;
  struct TextAttr textattr;

  DiskfontBase = OpenLibrary("diskfont.library",0);
  if(DiskfontBase != NULL)
  { textattr.ta_Name = "diamond.font";
    textattr.ta_YSize = 20;
    textattr.ta_Style = 2;
    textattr.ta_Flags = 0;
    textfont = (struct TextFont *)OpenDiskFont(&textattr);
    if(textfont != 0)
    { SetFont(&GScreenB->RastPort,textfont);
      i=TextLength(&GScreenB->RastPort,NameOfTheGame,15);
      Move(&GScreenB->RastPort,(360-i)/2-2,52);
      SetAPen(&GScreenB->RastPort,6);
      Text(&GScreenB->RastPort,NameOfTheGame,15);
    
      Move(&GScreenB->RastPort,(360-i)/2,50);
      SetAPen(&GScreenB->RastPort,5);
      Text(&GScreenB->RastPort,NameOfTheGame,15);
 
      CloseFont(textfont);
    }
    CloseLibrary(DiskfontBase);
  }
}
*/

void schliessen()
{  FreeMem(Texte,MAXLENGTH);
   if(Bilder1) {FreeMem(Bilder1,100000L); FreeMem(Bilder2,100000L);}
   CloseVGraph();
   CloseWindow(W1);
   CloseWindow(W2);
   CloseScreen(GScreenB);
   CloseScreen(GScreen);
   ClearMenuStrip(Display);
   CloseWindow(Display);
   CloseScreen(Screen);
   CloseLibrary(ArpBase);
   CloseLibrary(IntuitionBase);
   CloseLibrary(GfxBase);
}

/*Kleinschrifttabelle :*/
char tabelle1[]="[1234567890ß'\\[0qwertzuiopü+]123asdfghjklöä#/456<yxcvbnm,.-  789 ";

/*Großschrifttabelle :*/
char tabelle2[]="]!\"§$%&/()=?`|{0QWERTZUIOPÜ*}123ASDFGHJKLÖÄ^ 456>YXCVBNM;:_  789 ";

/* transform wandelt RAW-Codes in ASCII-Codes um*/
BYTE ctrl=0; /*Flags zum Mitteilen der Sondertasten*/
BYTE alt=0;
char transform(code)
BYTE code;
{  static BYTE shift=0,CapsLock=0; /*shift gedrückt : 1 */
   static BYTE ct=0,al=0;
   char zeichen=0;
   BYTE los=0;
   if(code&128) {los=1; code&=127; } /*Bit 7 ausmaskieren*/
   alt=al;ctrl=ct;
   if(los)
   {  if((code==96)||(code==97)) shift=0; /*Shift losgelassen*/
      if(code==98) CapsLock=0;
      if((code==0x64)||(code==0x65)) alt=al=0;
      if(code==0x63) ctrl=ct=0;
   }
   else if((code<65)&&(code!=60))
   {  if((!shift)&&(!CapsLock)) zeichen=tabelle1[code];
            else zeichen=tabelle2[code];
      if((zeichen==')')||(zeichen=='s')||(zeichen=='q')||(zeichen=='e'))
         ct=al=0;
      if((zeichen=='ä')&&al) zeichen='\'';
   }
   else if((code>75)&&(code<80)) /*Cursortasten*/
        { zeichen=code-48;
          if(shift) /*Page up-down*/
             zeichen=code-73; /*3:up, 4:down, 5:right, 6:left*/
        }
   else if(code==65) /*Backspace*/
      zeichen=9;
   else if((code==70)||(code==60))  /*Vorsicht : Diese Zeichen sind keine ASCII !*/
      zeichen=8; /*DEL*/
   else if((code>=80)&&(code<=83)) /* f1-f4 */
      zeichen=code-66;
   else if((code==96)||(code==97)) shift=1; /*Shift gedrückt*/
   else if(code==98) CapsLock=1;
   else if((code==0x64)||(code==0x65)) alt=al=1;
   else if(code==0x63) ctrl=ct=1;
   else if((code==68)||(code==67)) zeichen=10; /*return*/
   if((code==0x42)&&(!los)) /*tab*/
   {  ctrl=1;ct=0; zeichen='t'; }
   return(zeichen);
}

int strlen(z)
char *z;
{ int i=0;
  while(*z!=0) {z++; i++;}
  return(i);
}
    
BYTE emptystring(z)
char *z;
{ while(*z==' ') z++;
  if(*z==0) return(1);
  return(0);
}
       
/* benötigt Platz für anzahl+1 Zeichen, am besten ist string 3 Zeichen größer
als benötigt... */
int input(mstring,anzahl,x,y,TYP)/* anzahl : Länge der Eingabe,x,y Bildpos.*/
char *mstring;
int anzahl,x,y;
BYTE TYP; /*falls TYP==1 : Zahl einlesen */
{  int cursor=0,i,ende;
   char *z1,*z2;
   char einlesen(),string[83];
   char ein;
   strcpy(string,mstring);
   ende=strlen(string);
   SetDrMd(Display->RPort,JAM2); 
   SetAPen(Display->RPort,0); RectFill(Display->RPort,x,y,x+8*anzahl+7,y+7);
   SetDrMd(Display->RPort,JAM2|COMPLEMENT);
   ActivateWindow(Display);
   
   iText.IText=string; 
   PrintIText(Display->RPort,&iText,x,y);
   
   SetAPen(Display->RPort,3);
   RectFill(Display->RPort,x,y,x+7,y+7);
   CFlag=0;
   do
   {  ein=einlesen();
      if(ein==10)
      { if(emptystring(string)) ein=0;
      }  
      if((((ein>=32)&&(ein<=94))||((ein>=97)&&(ein<=126))
        ||(ein=='ö')||(ein=='Ö')||(ein=='ä')||(ein=='Ä')||
          (ein=='ü')||(ein=='Ü')||(ein=='ß')      
        )&&(ende<anzahl))
      {  if((!TYP)||(TYP&&(ende<anzahl)&&((ein>=48)&&(ein<=57))))
         {  z1=string+ende; z2=z1+1;
            for(i=cursor;i<=ende;i++) *z2--=*z1--; /*Lücke schaffen*/
            ende++; *(string+cursor)=ein;
            iText.IText=string+cursor; 
            PrintIText(Display->RPort,&iText,x+cursor*8,y);
            cursor++;
            SetAPen(Display->RPort,3);
            RectFill(Display->RPort,x+cursor*8,y,x+cursor*8+7,y+7);
         }
      }   
      else if((ein==9)&&(cursor>0)) /*Backspace*/
      {  z2=string+cursor; z1=z2-1;
         for(i=cursor;i<ende;i++) *z1++=*z2++;
         ende--; *(string+ende)=' ';*(string+ende+1)=0; 
         /*Cursor löschen*/
         SetAPen(Display->RPort,3);
         RectFill(Display->RPort,x+cursor*8,y,x+cursor*8+7,y+7);
         cursor--;
         iText.IText=string+cursor; 
         PrintIText(Display->RPort,&iText,x+cursor*8,y);
         *(string+ende)=(char)0;
         SetAPen(Display->RPort,3);
         RectFill(Display->RPort,x+cursor*8,y,x+cursor*8+7,y+7);
      }
      else if((ein==8)&&(cursor<ende)) /* DEL */
      {  z1=string+cursor; z2=z1+1;
         for(i=cursor;i<ende;i++) *z1++=*z2++;
         ende--;
         *(string+ende)=' ';
         iText.IText=string+cursor; 
         PrintIText(Display->RPort,&iText,x+cursor*8,y);
         *(string+ende)=(char)0;
         SetAPen(Display->RPort,3);
         RectFill(Display->RPort,x+cursor*8,y,x+cursor*8+7,y+7);
      }                     
      else if((ein==30)&&(cursor<ende)) /*rechts*/
      {  SetAPen(Display->RPort,3);
         RectFill(Display->RPort,x+cursor*8,y,x+cursor*8+7,y+7);
         cursor++;
         SetAPen(Display->RPort,3);
         RectFill(Display->RPort,x+cursor*8,y,x+cursor*8+7,y+7);
      }
      else if((ein==31)&&(cursor>0)) /*links*/
      {  SetAPen(Display->RPort,3);
         RectFill(Display->RPort,x+cursor*8,y,x+cursor*8+7,y+7);
         cursor--;
         SetAPen(Display->RPort,3);
         RectFill(Display->RPort,x+cursor*8,y,x+cursor*8+7,y+7);
      }
      else if(ein==5) /*zum rechten Ende*/
      {  SetAPen(Display->RPort,3);
         RectFill(Display->RPort,x+cursor*8,y,x+cursor*8+7,y+7);
         cursor=ende;
         SetAPen(Display->RPort,3);
         RectFill(Display->RPort,x+cursor*8,y,x+cursor*8+7,y+7);
      }
      else if(ein==6)
      {  SetAPen(Display->RPort,3);
         RectFill(Display->RPort,x+cursor*8,y,x+cursor*8+7,y+7);
         cursor=0;
         SetAPen(Display->RPort,3);
         RectFill(Display->RPort,x+cursor*8,y,x+cursor*8+7,y+7);
      }
      else if(ein==28) /*Cursor hoch*/ 
      { CFlag=ein; ein=10; } 
      else if(ein==1) /*beenden*/
      { ein=10; CFlag=1; }
      else if(((BYTE)ein>=16)&&((BYTE)ein<=26)) /*Menüs*/
      {  CFlag=(BYTE)ein; ein=10; }        
   }while(ein!=10);
   *(string+ende)=(char)0;   
   
   SetAPen(Display->RPort,3); /*Cursor löschen*/
   RectFill(Display->RPort,x+cursor*8,y,x+cursor*8+7,y+7);
   strcpy(mstring,string);
    
   if(TYP) /* Zahl ermitteln*/
   {  int Zahl=0;
      z1=string;
      for(i=0;i<ende;i++) {Zahl=10*Zahl+((int)*z1)-48; z1++;}
      return(Zahl);
   }   
   else return(0);
}
   
char einlesen()
{ ULONG class;
  USHORT code;
  struct IntuiMessage *message;

  if(!(message=GetMsg(Display->UserPort)))   
  { Wait(1<<Display->UserPort->mp_SigBit);
    message=GetMsg(Display->UserPort);
  }
  if(message)
  {  class=message->Class;
     code=message->Code;
     ReplyMsg(message);
     if(class==RAWKEY)
     {  /* Ziffern :*/
        return(transform(code));
     }
     /*if(class==CLOSEWINDOW) return((char)1); beenden*/
     if(class==MENUPICK) 
     {  if(MENUNUM(code)!=MENUNULL)
        switch(MENUNUM(code))
        {  case 0 : switch(ITEMNUM(code))
                    { case 0 : return((char)16);
                      case 1 : return((char)17);
                      case 2 : return((char)18);
                      case 3 : return((char)1);
                    }
           case 1 : switch(ITEMNUM(code))
                    { case 0 : return((char)19);
                      case 1 : return((char)20);
                      case 2 : return((char)21);
                    }
           case 2 : return((char)22);
        }
     } 
     return((char)0); 
  }
  return((char)0);
}       
int SZ=0;
void warten() /*wartet auf einen Tastendruck*/
{ char ein; 
  void MenuAn(),MenuAus(); 
  void nprint();
 
  MenuAus(); SZ=0;
  iText.IText="Bitte die Leertaste (Space) drücken";
  iText.FrontPen=15;
  PrintIText(Display->RPort,&iText,176,111);
  iText.FrontPen=1;
  ActivateWindow(Display);
  do  ein=einlesen(); while(ein!=' ');
  ScrollRaster(Display->RPort,0,8,4,15,635,118);
  MenuAn();
}   
char nzeile[81];

/* nread liest eine Zeile in das Feld nzeile ein*/
BYTE nread()
{  SZ=0;
   PrintIText(Display->RPort,&Prompt,4,111);
   nzeile[0]=0;
   do 
   {  input(nzeile,77,12,111,0);
      if(CFlag==28) strcpy(nzeile,lastline);
   }while(CFlag==28);   
   strcpy(lastline,nzeile);
   if(CFlag==0) ScrollRaster(Display->RPort,0,8,4,15,635,118);
   else
   { SetDrMd(Display->RPort,JAM2);
     SetAPen(Display->RPort,0); 
     RectFill(Display->RPort,4,111,627,118);
     SetDrMd(Display->RPort,JAM2|COMPLEMENT);
   }  
   if(CFlag==1) return(0); /* Aus-Gadget*/
   /* Hier auch alle anderen Abfragen einbauen*/
     
   return(1);
} 

/* nprint druckt einen Text aus, der mit 0 abschließt */
/* Zeilenumbruch gemäß Leerzeichen oder , . ! ? */
void nprint(z)
char *z;
{ int i,j;
  char *c,m,*x;
  x=z;
  while(*x!=0)
  { c=x; i=0;j=-1;
    
    if(SZ>=11) warten();
    
    while(((*c)!=0)&&(i<79))
    { if((*c==' ')||(*(c-1)==',')||(*(c-1)=='.')||(*(c-1)=='!')||
                    (*(c-1)=='?')) j=i;
      i++; c++;     
    }  
    if(*c==0)
    { 
      iText.IText=x;
      PrintIText(Display->RPort,&iText,4,111);
      ScrollRaster(Display->RPort,0,8,4,15,635,118);
      x=c;
      SZ++;
    }
    else  
    {  if((*c==' ')||(*(c-1)==',')||(*(c-1)=='.')||(*(c-1)=='!')||
                     (*(c-1)=='?')) j=i; /*auch letztes Zeichen testen*/
       if(j<=0) /* keine Trennung möglich*/
       {  m=*c; *c=0;
          iText.IText=x;
          PrintIText(Display->RPort,&iText,4,111);
          ScrollRaster(Display->RPort,0,8,4,15,635,118);
          *c=m; x=c;
          SZ++;
       }
       else
       {  c=x+j; /* hier Trennen */
          m=*c;
          *c=0;
          iText.IText=x;
          PrintIText(Display->RPort,&iText,4,111);
          ScrollRaster(Display->RPort,0,8,4,15,635,118);
          *c=m; if(m==' ') x=c+1; else x=c;
          SZ++;
       }
    }
  }           
}      

void MenuAus()
{ ClearMenuStrip(Display); }

void MenuAn()
{ SetMenuStrip(Display,&ober1); }
     
void buildname(q1,q2,z)
char *q1,*q2,*z;
{ if(*q1!=0)
  { while(*q1) *z++=*q1++;
    q1--; if(*q1!=':') *z++='/';
  }
  while(*q2) *z++=*q2++; *z=0;
}

#define RAN 44 /*Anzahl der Räume*/        
BYTE newliesdata(typ)
BYTE typ; /*0 : lesen, 1 : schreiben */   
{ char Name[100],code;
  void reset(); 
  ULONG filehandle;
  int i,k;
  struct ROOM { int Nachbarn[8]; ULONG Gegenstaende; char *txt; char *txt2; };
  extern struct ROOM Raum[RAN]; 
  extern int POS,DABEI,STRA,SUMPF,TIME,KALTT,LUFT,GAS;
  extern BYTE DANACH,BOMBE,SNAKE,VERSCHL,ENDE,OMA,WASSER,KALT,LAMPE,EINSTURZ,GAST,KIND;
  extern void malen();
 
  FileReq.FR_Window=Display;
  MenuAus();
  if(typ)
  {  FileReq.FR_Hail="Spielstand sichern :";
     MoveScreen(Screen,0,-40);
     if(FileRequest(&FileReq))
     { buildname(path,filename,Name);
       filehandle=Open(Name,MODE_NEWFILE);
       if(filehandle)
       {  Write(filehandle,"§",1);
          Write(filehandle,&POS,sizeof(int));
          Write(filehandle,&DABEI,sizeof(int));
          Write(filehandle,&STRA,sizeof(int));
          Write(filehandle,&SUMPF,sizeof(int));
          Write(filehandle,&TIME,sizeof(int));
          Write(filehandle,&KALTT,sizeof(int));
          Write(filehandle,&LUFT,sizeof(int));
          Write(filehandle,&GAS,sizeof(int));

          Write(filehandle,&ENDE,1);
          Write(filehandle,&OMA,1);
          Write(filehandle,&WASSER,1);
          Write(filehandle,&KALT,1);
          Write(filehandle,&LAMPE,1);
          Write(filehandle,&EINSTURZ,1);
          Write(filehandle,&GAST,1);
          Write(filehandle,&KIND,1);
          Write(filehandle,&VERSCHL,1);
          Write(filehandle,&SNAKE,1);
          Write(filehandle,&BOMBE,1);
          Write(filehandle,&DANACH,1);
         
          for(i=0;i<RAN;i++)
            k=Write(filehandle,&Raum[i].Gegenstaende,sizeof(ULONG));  
          if(k>0) nprint("ok.");
          else nprint("Fehler beim Schreiben !");
          MenuAn();
          Close(filehandle);
          MoveScreen(Screen,0,40);
          return(1);
       }
       else
       {  nprint("Daten konnten nicht geschrieben werden !");
          MenuAn();
          MoveScreen(Screen,0,40);
          return(0);
       }
     }
  }
  else
  {  FileReq.FR_Hail="Spielstand laden :";
     MoveScreen(Screen,0,-40);
     if(FileRequest(&FileReq))
     { buildname(path,filename,Name);
       filehandle=Open(Name,MODE_OLDFILE);
       if(filehandle)
       {  Read(filehandle,&code,1);
          if(code!='§') 
          { nprint("Die Datei hat ein unbekanntes Format.");
            Close(filehandle); MenuAn();
            MoveScreen(Screen,0,40);
            return(0);
          }
          Read(filehandle,&POS,sizeof(int));
          Read(filehandle,&DABEI,sizeof(int));
          Read(filehandle,&STRA,sizeof(int));
          Read(filehandle,&SUMPF,sizeof(int));
          Read(filehandle,&TIME,sizeof(int));
          Read(filehandle,&KALTT,sizeof(int));
          Read(filehandle,&LUFT,sizeof(int));
          Read(filehandle,&GAS,sizeof(int));
          
          Read(filehandle,&ENDE,1);
          Read(filehandle,&OMA,1);
          Read(filehandle,&WASSER,1);
          Read(filehandle,&KALT,1);
          Read(filehandle,&LAMPE,1);
          Read(filehandle,&EINSTURZ,1);
          Read(filehandle,&GAST,1);
          Read(filehandle,&KIND,1);
          Read(filehandle,&VERSCHL,1);
          Read(filehandle,&SNAKE,1);
          Read(filehandle,&BOMBE,1);
          Read(filehandle,&DANACH,1);
         
          for(i=0;i<RAN;i++)
            k=Read(filehandle,&Raum[i].Gegenstaende,sizeof(ULONG));  
          if(k>0) { malen(-1,POS); if(EINSTURZ==3) Raum[32].Nachbarn[5]=31;
                                   else Raum[32].Nachbarn[5]=-1; }
          else { nprint("Fehler beim Lesen !"); 
                 Close(filehandle); MenuAn(); MoveScreen(Screen,0,40); reset(); return(1);
               }   
      
          Close(filehandle);
          MenuAn();
          MoveScreen(Screen,0,40);
          nprint("ok.");
          return(1);
       }
       else
       {  nprint("Daten konnten nicht gelesen werden !");
          MenuAn();
          MoveScreen(Screen,0,40);
          return(0);
       } 
     }
  }
  MenuAn();
  MoveScreen(Screen,0,40);
  return(1);
}
         
BYTE QCheck() /*wirklich verlassen ?*/
{  char antw[5];
   antw[0]=0;
   SZ=0;
   MenuAus();
   iText.FrontPen=15;
   iText.IText="Möchtest Du das Spiel beenden (j/n) ?";
   PrintIText(Display->RPort,&iText,4,111);
   iText.FrontPen=1;
   input(antw,1,308,111,0);
   ScrollRaster(Display->RPort,0,8,4,15,635,118);
   MenuAn();
   if((antw[0]!='j')&&(antw[0]!='J')) return(1);
   else return(0);
}

int multiple_choise(a,b,c,d)
char *a,*b,*c,*d;
{  int i=0;
   char ein;
   MenuAus(); SZ=0;
   nprint(" ");
   nprint(a); 
   if(SZ>6) warten(); else SZ=0;
   nprint(" ");
   nprint("Bitte wähle zwischen diesen Alternativen :"); nprint(b); nprint(c); nprint(d);
   SetDrMd(Display->RPort,JAM2|COMPLEMENT);
   SetAPen(Display->RPort,3); 
   RectFill(Display->RPort,4,87,635,94);
   do
   { ein=einlesen();
     if((ein==28)&&(i>0))
     { RectFill(Display->RPort,4,87+i*8,635,94+i*8);
       i--;
       RectFill(Display->RPort,4,87+i*8,635,94+i*8);
     }  
     if((ein==29)&&(i<2))
     { RectFill(Display->RPort,4,87+i*8,635,94+i*8);
       i++;
       RectFill(Display->RPort,4,87+i*8,635,94+i*8);
     }
   }while(ein!=10);
   SZ=0;  
   MenuAn();
   return(i);
}

int HowMuch()
{  char antw[5];
   int i;
   antw[0]=0;
   MenuAus();SZ=0;  
   iText.IText="Möchtest Du eine oder zwei Stangen TNT benutzen (1/2) ?";
   PrintIText(Display->RPort,&iText,4,111);
   iText.FrontPen=1;
   i=input(antw,1,452,111,1);
   ScrollRaster(Display->RPort,0,8,4,15,635,118);
   MenuAn();
   return(i);
}
void reset() /*setzt alle Daten zurück*/
{  extern int GAS,POS,DABEI,STRA,SUMPF,TIME,KALTT,LUFT;
   extern BYTE DANACH,SNAKE,VERSCHL,ENDE,OMA,WASSER,KALT,LAMPE,EINSTURZ,GAST,KIND,BOMBE;
   GAS=POS=DABEI=STRA=SUMPF=TIME=0;
   DANACH=SNAKE=ENDE=OMA=WASSER=KALT=LAMPE=GAST=KIND=VERSCHL=BOMBE=0;
   Raum[32].Nachbarn[5]=-1;
   GVert();
   load(0);
   nprint(" ");
   nprint("    Das Fest");    
   nprint("    oder: die Abenteuer eines Gestrandeten");
   nprint(" ");
   nprint(" ");
   nprint(" ");
   
   nprint(Texte);
}
   
void Neubeginn()
{  char antw[5];
   antw[0]=0;
   MenuAus();
   iText.FrontPen=15;SZ=0;
   iText.IText="Möchtest Du das Spiel ganz sicher neu beginnen (j/n) ?";
   PrintIText(Display->RPort,&iText,4,111);
   iText.FrontPen=1;
   input(antw,1,444,111,0);
   ScrollRaster(Display->RPort,0,8,4,15,635,118);
   MenuAn();
   if((antw[0]=='j')||(antw[0]=='J'))
   {  nprint("Wir sind wieder am Anfang unserer Geschichte.");
      reset();
   }   
}

void about()
{  nprint(" ");
   nprint("Das Fest:");
   nprint("programmiert von Steffen Goebbels");
   nprint("Anschrift : Alte Heerstr. 25, 47652 Weeze");
   nprint(" ");
   nprint("Dieses Spiel ist PD und darf nicht kommerziell vermarktet werden.");
   nprint("Eine Kopiergebühr sollte unter 5 DM liegen.");
   nprint("Für ev. Programmfehler übernehme ich keine Haftung.");
   nprint(" ");
}

void main()
{ oeffnen();
  reset();
  do   
  { nread();
    switch(CFlag)
    { case 16 : newliesdata(1); break;
      case 17 : newliesdata(0); break;
      case 18 : Neubeginn(); break;
      case 19 : zeigRicht(); break;
      case 20 : inventur(); break;
      case 21 : help(); break;
      case 22 : about(); break;
      case 1  : if(QCheck()) CFlag=0; else CFlag=1; break;
      case 0  : separieren(nzeile); analysis(); 
                if(!ENDE) Zeit();
                break; /*Hier Parser aufrufen*/
    }
    if(ENDE)
    {  if(QCheck()) { CFlag=0; reset(); }
       else CFlag=1;
    }  
  }while(CFlag!=1);  
  schliessen();
}   
