/*********************************************************************/
/*                                                                   */
/*                              Cul de sac                           */
/*                                                                   */
/*                                Editor                             */
/*                                                                   */
/*       (C) 1991 Miky Wenngatz, Jägerweg 31, 8031 Gilching          */
/*                                                                   */
/*                    Geschrieben von Michael Kaiser                 */
/*                                                                   */
/*      ----------------------------------------------------         */
/*                                                                   */
/*      Unter Angabe dieses Copyrightvermerkes können Teile          */
/*      Programmes in eigenen Programmen verwandt werden,            */
/*      welche jedoch nicht kommerziell vertrieben werden            */
/*      dürfen. Die Verwendung von Code für PD-Programme ist         */
/*      bei vorhandener CDS-Lizenz uneingeschränkt gestattet.        */
/*                                                                   */
/*********************************************************************/

#include <stdio.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuitionbase.h>
#include <intuition/screens.h>
#include <graphics/gfxbase.h>
#include <graphics/gfxmacros.h>

#include "cdsconst.h"
#include "cdseditprefs.h"

#define  max(a,b)   ((a) > (b) ? (a) : (b))
#define  min(a,b)   ((a) > (b) ? (b) : (a))

#define  COMMONFLAG ITEMTEXT|ITEMENABLED|HIGHCOMP
#define  SUBFLAG    ITEMTEXT|ITEMENABLED|HIGHNONE
#define  GFXFLAG    HIGHIMAGE|ITEMENABLED|HIGHBOX

#define  NumItems_1 4
#define  NumItems_3 11
#define  NumItems_2 4
#define  NumItems_5 5

#define  ALLOFF     0xFFFFFFFF

#define  NumSubItems_12  14
#define  NumSubItems_311 5
#define  NumSubItems_14  2

#define  MAUER    0
#define  KISTE    1
#define  PLATZ    2
#define  MANN     3
#define  CLEAR    4

#define  UNCHECKED (0xFFFF^CHECKED)

#define  GADFLAGS  GADGETDOWN

extern   USHORT    Mann1[],Kiste1[],Brick1[],Place1[],Clear1[];

VOID *AllocMem();
VOID *OpenLibrary();
VOID *OpenWindow();
VOID *OpenDiskFont();
VOID *OpenScreen();
VOID *ViewPortAddress();
VOID *CreateDir();

 UBYTE Undo0[PATHLEN]; 
 struct IntuiText Newdirtext = {1,3,JAM2,-1,-11,0L,
    (UBYTE*) " Neues Verzeichnis ( vollst. Pfad )",0L};
 char FullName[2*PATHLEN]  = "DF0:CDS_Levels/Level_00";
 char FullToName[2*PATHLEN]= "DF0:CDS_Levels/Level_00";
 
 LONG  Level_Pos = 22L;
 LONG  To_Level_Pos = 22L;
  
 UBYTE NewDString[PATHLEN]= "";
 struct StringInfo NewdirString =
                   {NewDString,Undo0,0,PATHLEN,0,0,0,0,0,0,0L,0L,0L};

SHORT Pairs[] = { -1,-1,240,-1,240,10,-1,10,-1,-1};
struct Border StrBorder = { -1,-1,1,0,JAM1,5,Pairs,0L};

SHORT Pairs2[] = { -1,-1,360,-1,360,10,-1,10,-1,-1};
struct Border Str2Border = { -1,-1,1,0,JAM1,5,Pairs2,0L};

struct Gadget Newdir_gad = {
     0L,20,30,320,11,GADGHCOMP, STRINGCENTER | RELVERIFY,
     STRGADGET,(APTR)&Str2Border,0L,
     &Newdirtext,0xFFFFFFFFL,(APTR)&NewdirString, 3,0L};

struct NewWindow NewDirWindow = { 120,40,400,70,0,1,
                                CLOSEWINDOW|REFRESHWINDOW|MOUSEBUTTONS
                               |GADGETUP|GADGETDOWN,
                                REPORTMOUSE|WINDOWCLOSE|SIMPLE_REFRESH
                               |ACTIVATE,
                                &Newdir_gad,0L,
                                (UBYTE*)"    Erstelle neues Verzeichnis",
                                0L,0L,0,0,0,0,CUSTOMSCREEN};


struct IntuiMsg  *GetMsg();

struct IntuiText generic = { 4,1,JAM2,3,0,0L,0L,0L };

struct Menu      AMenu   = { 0L,0,0,100,0,MENUENABLED,(BYTE*)"CDS-Editor",
                             0L,0,0,0,0};

struct Menu      BMenu   = { 0L,100,0,150,0,MENUENABLED,(BYTE*)"Bild",
                             0L,0,0,0,0};

struct Menu      CMenu   = { 0L,250,0,65,0,MENUENABLED,(BYTE*)"Level",
                             0L,0,0,0,0};
                     
struct Menu      EMenu    = { 0L,320,0,60,0,MENUENABLED,(BYTE*)"Items",
                              0L,0,0,0,0};
                                
struct MenuItem  Menu1_Items[NumItems_1];
struct MenuItem  Menu2_Items[NumItems_2];
struct MenuItem  Menu3_Items[NumItems_3];
struct MenuItem  Menu5_Items[NumItems_5];

struct MenuItem  SubMenu12_Items[NumSubItems_12];
struct MenuItem  SubMenu311_Items[NumSubItems_311];
struct MenuItem  SubMenu14_Items[NumSubItems_14];

struct IntuiText Menu1_Text[NumItems_1];
struct IntuiText Menu2_Text[NumItems_2];
struct IntuiText Menu3_Text[NumItems_3];

struct IntuiText SubMenu12_Text[NumSubItems_12];
struct IntuiText SubMenu311_Text[NumSubItems_311];
struct IntuiText SubMenu14_Text[NumSubItems_14];

struct Image     Menu5_Images[NumItems_5];

char  *Menu1_Names[NumItems_1] = {"Quit","C.D.S.","Hilfe","Extras"};

char  *Menu3_Names[NumItems_3] = {"    0","    1","    2","    3","    4","    5",
                                  "    6","    7","    8","    9","    »"};

                                  
char  *SubMenu311_Names[NumSubItems_311] = {"   + 0","   +10","   +20",
                                            "   +30","   +40"};
                                  
char  *SubMenu12_Names[NumSubItems_12] = {" ",
                                          "        Cul-de-sac:       ",
                                      " ",
                                          "        CDS-Editor        ",
                                      " ","       geschrieben        ",
                                      " ","    von Michael Kaiser    ",
                                      " ",
                                      " ","    Copyright (c) 1991    ",        
                                      " "," Miky Wenngatz, Gilching  ",
                                      " "};

char  *SubMenu14_Names[NumSubItems_14] = {"Verzeichnis erstellen",
                                          "Einstellungen"};

char  *Menu2_Names[NumItems_2] = {"Lade  Bild",
                                  "Aktuelles Bild speichern",
                                  "Aktuelles Bild überprüfen",
                                  "Bild löschen" };
                                   
					  
struct NewScreen NewS = { 0,0,640,255,3,1,3,(USHORT)(CUSTOMBITMAP|HIRES),
                          (USHORT)CUSTOMSCREEN,0L,
                          (UBYTE *)"CDS-Editor, Version 1.2 vom Januar 1991",
                          0L,0L };

struct NewWindow NewW = {0,12,640,230,4,1,
                         REFRESHWINDOW|CLOSEWINDOW|MENUPICK|
                         ACTIVEWINDOW,
                         ACTIVATE|WINDOWCLOSE,0L,0L,
                         (UBYTE *)"»» Spielfeld ««",0L,0L,0,0,0,0,CUSTOMSCREEN};

struct TextAttr  NewF = { (STRPTR)"topaz.font",FONTHEIGHT,0L,0L};
                        

struct IntuitionBase *IntuitionBase;
struct GfxBase       *GfxBase;
struct DiskfontBase  *DiskfontBase;
struct TextFont      *Font;
struct Screen        *S;
struct Window        *W,*FWindow;
struct ViewPort      *Vp;

struct IntuiMessage  *IntuiMsg;


USHORT *ImageData[NumItems_5];

UBYTE  ImageMask[NumItems_5] = { 0x07,0x07,0x07,0x07,0x07 };

UBYTE  ShortKeys[NumItems_5] = {'W','K','P','M','C'};

BOOL   Last_Edits_Saved,Level_Yet_Checked,Level_Ok,Start_Point_Set;

UBYTE  Bild[BildBreite][BildHoehe];

int    Pattern;

struct CDSEditPrefs Prefs;

main()

{  /* Interne (lokale) Variable */

   int    F0,F1,F2,i,j,Run,Loop;
   int    SprNum,MNum,INum,SNum;
   int    Level,LowLevel,HighLevel,Time;
   int    ManXPos,ManYPos;
   ULONG  Class;
   USHORT Code;
   BOOL   StartGame,ExitPlayer,ExitGame,ExitLoop,Answer;
   USHORT *TargetPointer,*SourcePointer;
   
   struct MenuItem *Pointer,*SubPointer;
   
   /* Initialwerte */

   Level = 0; LowLevel = 0; HighLevel = 0;
   
   Pattern = MAUER;
   
   /* Libraries öffnen */

   IntuitionBase = (struct IntuitionBase*) OpenLibrary("intuition.library",0L);
   GfxBase       = (struct GfxBase*)       OpenLibrary("graphics.library",0L);
   DiskfontBase  = (struct DiskfontBase*)  OpenLibrary("diskfont.library",0L);
      
   /* Bildschirmaufbau */

   Font          = (struct TextFont*) OpenDiskFont(&NewF);
   NewS.Font     = &NewF;
   
   DoIntro();
   
   OFF_DISPLAY();

   S = (struct Screen*) OpenScreen(&NewS);

   Vp = &(S->ViewPort);

   ScreenToFront(S);
   
   NewW.Screen         = S;
   NewDirWindow.Screen = S;
   
   SetReqColors(0,1,1,0,4,0,1,3);

   W = (struct Window*) OpenWindow(&NewW);

   OFF_DISPLAY();

   ReadPrefs(&Prefs);
   SetCDSEditPrefs(&Prefs,Vp);
   MakeFullName(&Prefs);
   MakeFullToName(&Prefs);

   OFF_DISPLAY();

   for (i=0;i<NumItems_5;i++)
       { 
        ImageData[i] = (USHORT*) AllocMem(100L,MEMF_CHIP|MEMF_CLEAR);
        TargetPointer = ImageData[i];
        if (i==0) SourcePointer = Brick1;
           else if (i==1) SourcePointer = Kiste1;
                else if (i==2) SourcePointer = Place1;
                     else if (i==4) SourcePointer = Clear1;
                          else SourcePointer = Mann1;
        for (j=0;j<36;j++)
            *TargetPointer++ = *SourcePointer++;
        }
            

   InitImages();

   NewMenu(&AMenu,Menu1_Names,Menu1_Items,Menu1_Text,NumItems_1,120,COMMONFLAG,0L);
   NewMenu(&BMenu,Menu2_Names,Menu2_Items,Menu2_Text,NumItems_2,230,COMMONFLAG,0L);
   NewMenu(&CMenu,Menu3_Names,Menu3_Items,Menu3_Text,NumItems_3,65,COMMONFLAG|CHECKIT,ALLOFF);
   NewGfxMenu(&EMenu,Menu5_Items,Menu5_Images,ShortKeys,NumItems_5,80,GFXFLAG|CHECKIT,ALLOFF);

   NewSubMenu(&AMenu,1,SubMenu12_Names,SubMenu12_Items,SubMenu12_Text,NumSubItems_12,200,SUBFLAG,0L);
   NewSubMenu(&AMenu,3,SubMenu14_Names,SubMenu14_Items,SubMenu14_Text,NumSubItems_14,230,COMMONFLAG,0L);
   NewSubMenu(&CMenu,10,SubMenu311_Names,SubMenu311_Items,SubMenu311_Text,NumSubItems_311,60,COMMONFLAG|CHECKIT,ALLOFF);

   CMenu.NextMenu = &EMenu;
   BMenu.NextMenu = &CMenu;
   AMenu.NextMenu = &BMenu;

   CMenu.FirstItem->Flags |= CHECKED;
   EMenu.FirstItem->Flags |= CHECKED;

   SetMenuStrip(W,&AMenu);

   ClearLevel(W,Bild);

   ON_DISPLAY();

   /* Initialisierung beendet -- Hauptprogramm folgt */

   ExitGame = FALSE;
   
   while (! ExitGame)
   {
      ExitLoop = FALSE;
          
      while (! ExitLoop)
      {
         if (!GetIntuiMessage(S,W,Vp,&ExitLoop,&ExitGame,&Level,
                              &LowLevel,&HighLevel,&ManXPos,&ManYPos)) 
         if (Do_Editor(W,Bild) && Last_Edits_Saved)
            Last_Edits_Saved = FALSE;
                 
       }  /* Innere while-Schleife */
            
   } /* Äußere While-Schleife */

   /* Programmende : IntuiObjekte schliessen, Speicher freigeben. */

         
   ClearMenuStrip(W);
   CloseWindow(W);
   CloseScreen(S);

   for (i=0;i<NumItems_5;i++)
       FreeMem(ImageData[i],100L);

   CloseLibrary(IntuitionBase);
   CloseLibrary(DiskfontBase);
   CloseLibrary(GfxBase);
}

BOOL Do_Editor(W,Bild)

struct Window *W;
UBYTE  Bild[BildBreite][BildHoehe];

{ int x,y,Field_X,Field_Y;

  UBYTE *CIAAPRA = (UBYTE*) 0xBFE001;

  if ((*CIAAPRA & 0x40) != 0) return(FALSE);

  WaitForLeftMouseButton();
  x = W->MouseX;
  y = W->MouseY;
  Field_X = (x-LeftOffset)/(MFaktor*16);
  Field_Y = (y-18)/12;
  if ((Field_X < 0) || (Field_X >= BildBreite) ||
      (Field_Y < 0) || (Field_Y >= BildHoehe)) return(FALSE);
 
  DrawEmpty(W,(LeftOffset+16*Field_X),(18+12*Field_Y));
  if (Bild[Field_X][Field_Y]==(UBYTE)4) 
     Start_Point_Set = FALSE;

  switch (Pattern) {
         case MAUER : DrawBrick(W,(LeftOffset+16*Field_X),(18+12*Field_Y));
                      Bild[Field_X][Field_Y] = (UBYTE)1;
                      break;
         case KISTE : if (Bild[Field_X][Field_Y] == 2)
                      {    
                      Bild[Field_X][Field_Y] = (UBYTE)5;
                      DrawFixedChest(W,(LeftOffset+16*Field_X),(18+12*Field_Y));
                      }   
                      else
                      {
                      Bild[Field_X][Field_Y] = (UBYTE)3;
                      DrawChest(W,(LeftOffset+16*Field_X),(18+12*Field_Y));
                      }
                      break;
         case PLATZ : DrawDPlace(W,(LeftOffset+16*Field_X),(18+12*Field_Y));
                      Bild[Field_X][Field_Y] = (UBYTE)2;
                      break;
         case CLEAR : DrawEmpty(W,(LeftOffset+16*Field_X),(18+12*Field_Y));
                      Bild[Field_X][Field_Y] = (UBYTE)0;
                      break;
         case MANN  : if (!Start_Point_Set) 
                      { 
                      Bild[Field_X][Field_Y] = (UBYTE)4; 
                      DrawStartPoint(W,(LeftOffset+16*Field_X),(18+12*Field_Y));
                      Start_Point_Set = TRUE;
                      }
                      break;
                    }
    return(TRUE);
}
  
MakeFullName(p)

struct CDSEditPrefs *p;

{ char *D,*F,*Full;
 
  Level_Pos = 0L;
  D = p->path;
  F = p->lvxt;
  Full = FullName;
  while ((*Full = *D) != 0)
        {
         Full++;
         D++;
         Level_Pos++;
        }
  *Full++ = '/';
  
  Level_Pos++;
  while ((*Full = *F) != 0)
        {
         Full++;
         F++;
         Level_Pos++;
        }
   Full++;
   *Full = 0;
   Level_Pos++;
   Full = FullName;
   Full--;
   Full += Level_Pos;
   *Full++ = 57;
   *Full++ = 56;
   *Full++ = 0;
}
  
MakeFullToName(p)

struct CDSEditPrefs *p;

{ char *D,*F,*Full;
 
  To_Level_Pos = 0L;
  D = p->topath;
  F = p->lvxt;
  Full = FullToName;
  while ((*Full = *D) != 0)
        {
         Full++;
         D++;
         To_Level_Pos++;
        }
  *Full++ = '/';
  
  To_Level_Pos++;
  while ((*Full = *F) != 0)
        {
         Full++;
         F++;
         To_Level_Pos++;
        }
   Full++;
   *Full = 0;
   To_Level_Pos++;
   Full = FullToName;
   Full--;
   Full += To_Level_Pos;
   *Full++ = 57;
   *Full++ = 56;
   *Full++ = 0;
}
  
 
SetPensAndMask(w,wm,a,b)

struct Window *w;

int wm,a,b;

{
 w->RPort->FgPen = (BYTE) a;
 w->RPort->BgPen = (BYTE) b;
 SetWrMsk(w->RPort,(UBYTE)wm);
}


BOOL MakeNewDir()

 {
    ULONG MessageClass;
    USHORT code;
    BOOL   Result,GotString;
    struct FileLock *Lock;
    
    FWindow = (struct Window *)OpenWindow(&NewDirWindow);
    WindowToFront(FWindow);
    RefreshGadgets(&Newdir_gad,FWindow,0L);
    
    GotString = FALSE;
    
    while (!GotString)
    {    
      
       if (IntuiMsg = (struct IntuiMessage *)GetMsg(FWindow->UserPort))  {
         MessageClass = IntuiMsg->Class;
         code = IntuiMsg->Code;
         ReplyMsg(IntuiMsg);
         switch (MessageClass) {
  
            case CLOSEWINDOW : GotString = TRUE;
                               CloseWindow(FWindow);
                               break;
                               
            case MOUSEBUTTONS: break;
            
            default          : break;
            
         }   /* Case */
       }  /* if */
    }  /* while */
    if (NewDString[0]==0) return(FALSE);
    Result = (BOOL)((Lock = (struct FileLock*) CreateDir(NewDString)) != 0L);
    if (Lock) UnLock(Lock);
    return(Result); 
} /* MakeNewDir */
          
BOOL LoadLevel(Lv,Bild)

int   Lv;
UBYTE Bild[BildBreite][BildHoehe];

{ FILE *f;
  int   x,y;
  char *Full;
  BOOL  Fehler;
   
   Full = FullName;
   Full--;
   Full += Level_Pos;
   *Full++ = 48+(Lv/10);
   *Full++ = 48+(Lv%10);
  
  if ((f = fopen(FullName,"r")) == 0L) return(TRUE);;
  
  Start_Point_Set = FALSE;
  
  for (y=BildHoehe-1;y>-1;y--)
      for (x=0; x<BildBreite; x++)
          {
            Bild[x][y]=getc(f);
            if (Bild[x][y]==(UBYTE)4) Start_Point_Set = TRUE;
          }
  Fehler = (BOOL)ferror(f);
  fclose(f);
  return(Fehler);
}
  
          
BOOL SaveLevel(Lv,Bild)

int   Lv;
UBYTE Bild[BildBreite][BildHoehe];

{ FILE *f;
  int x,y;
  char *Full;
  BOOL  Fehler;
   
   Full = FullToName;
   Full--;
   Full += To_Level_Pos;
   *Full++ = 48+(Lv/10);
   *Full++ = 48+(Lv%10);
  
  if (!(f = fopen(FullToName,"w"))) 
     return(FALSE);;
  
  for (y=BildHoehe-1;y>-1;y--)
      for (x=0; x<BildBreite; x++)
          putc(Bild[x][y],f);
  Fehler = (BOOL)ferror(f);
  fclose(f);
  return(Fehler);
}
  
  
  
PaintScreen(W,Bild,Mx,My)

struct Window *W;
UBYTE  Bild[BildBreite][BildHoehe];
int    *Mx,*My;

{ int i,j,x,y;
  BYTE *Current;
  BYTE k;
  
  OFF_DISPLAY();
  Move(W->RPort,0L,0L);  
  for (y=0; y<BildHoehe; y++)
      {       
       for (x=0;x<BildBreite;x++)
           {
           Move(W->RPort,(LONG)(LeftOffset+1+16*x),(LONG)(18+12*y));    
           k = Bild[x][y];
           if (k==0) 
              { 
                Current++; continue;
              }
           if (k==1)    
              { DrawBrick(W,(LeftOffset+16*x),(18+12*y)); 
                Current++; continue;
              }
           if (k==2)
              { DrawDPlace(W,(LeftOffset+16*x),(18+12*y));
                Current++; continue;
               }
           if (k==3)
              { DrawChest(W,(LeftOffset+16*x),(18+12*y));
                Current++; continue; 
               } /* Kiste */
           if (k==4)
              { *Mx = x; *My = y;
                DrawStartPoint(W,(LeftOffset+16*x),(18+12*y));
                Start_Point_Set = TRUE;
                Current++; continue; } /* Startpos. Spieler */
           if (k==5)
              { DrawFixedChest(W,(LeftOffset+16*x),(18+12*y));
                Current++; continue;
              } /* Fixierte Kiste */          
           }
       }
  ON_DISPLAY();
}
   

InitImages()

{ int i,j;

  for (i=0;i<NumItems_5;i++)
      {
       Menu5_Images[i].LeftEdge  = 20;
       Menu5_Images[i].TopEdge   = 0;
       Menu5_Images[i].Width     = 16; 
       Menu5_Images[i].Height    = 12;
       Menu5_Images[i].Depth     = 3;
       Menu5_Images[i].ImageData = ImageData[i];        
       Menu5_Images[i].PlanePick = ImageMask[i];
       Menu5_Images[i].PlaneOnOff= 0x07 ^ ImageMask[i];
       Menu5_Images[i].NextImage = 0L;
      }
}

ClearLevel(W,Bild)

struct Window *W;
UBYTE  Bild[BildBreite][BildHoehe];

{ int i,j;

  Move(W->RPort,0L,0L);
  ClearScreen(W->RPort);
  RefreshWindowFrame(W);
  
  for (i=0;i<BildBreite;i++)
      for (j=0;j<BildHoehe;j++)
          Bild[i][j] = (UBYTE)0;

  Start_Point_Set    = FALSE;
  Last_Edits_Saved   = TRUE;
  Level_Yet_Checked  = FALSE;
  Level_Ok           = FALSE;

}


BOOL CheckLevel(Bild)

UBYTE Bild[BildBreite][BildHoehe];

{ int i,j,NumP,NumC,NumM;
  BOOL Result;
  
  NumP = 0;
  NumC = 0;
  NumM = 0;
  for (i=0;i<BildBreite;i++)
      for (j=0;j<BildHoehe;j++)
          {
          if (Bild[i][j] == (UBYTE)2) NumP++;
          if (Bild[i][j] == (UBYTE)3) NumC++;
          if (Bild[i][j] == (UBYTE)4) NumM++;
          }
  Result = (NumP==NumC);
  Result = (Result && (NumM==1));
  return(Result); 
}
    
GetIntuiMessage(S,W,Vp,ExitLoop,ExitGame,Level,LowLevel,HighLevel,Mx,My)

struct Screen *S;
struct Window *W;
struct ViewPort *Vp;
BOOL   *ExitLoop,*ExitGame;
int    *Level,*LowLevel,*HighLevel,*Mx,*My;

{ ULONG  Class;
  USHORT Code;
  BOOL   Answer,Response,Goon;
  int    MNum,SNum,INum;
  
  Answer   = FALSE;
  IntuiMsg = (struct IntuiMessage*)GetMsg(W->UserPort);
         if (IntuiMsg != 0L)
            {
          Answer = TRUE;
          Class = IntuiMsg->Class;
          Code = IntuiMsg->Code;
          ReplyMsg(IntuiMsg);
          switch (Class) {
 
           case CLOSEWINDOW : if (!Last_Edits_Saved) 
                                 {
                                   Goon = Decision(S,
             (UBYTE*)"Letzte Änderungen nicht gesichert ! Weiter ?");
                                 }                                    
                                 else Goon = TRUE; 
                              if (Goon) {*ExitGame = TRUE;
                                         *ExitLoop = TRUE;
                                        }
                                 break;
           
           case MENUPICK    : MNum = MENUNUM(Code);
                              INum = ITEMNUM(Code);
                              SNum = SUBNUM(Code);
                              
                              /* HAUPTMENU */
                              
                              if ((MNum == 0) &&
                                  (INum == 0)) {
                                    if (!Last_Edits_Saved) { 
                                   Goon = Decision(S,
             (UBYTE*)"Letzte Änderungen nicht gesichert ! Weiter ?");
                                              }
                                    else Goon = TRUE;
                                    if (Goon) 
                                       {
                                        *ExitLoop = TRUE;
                                        *ExitGame = TRUE;
                                       }
                                 break;
                                }
        
                              if ((MNum == 0) &&
                                  (INum == 2)) 
                                  {
                                   DoHelp(S);
                                   break;
                                   }                                 
                              if ((MNum == 0) &&
                                  (INum == 4)) {
                                    if (!Last_Edits_Saved) { 
                                   Goon = Decision(S,
             (UBYTE*)"Letzte Änderungen nicht gesichert ! Weiter ?");
                                              }
                                    else Goon = TRUE;
                                    if (Goon) {*ExitLoop = TRUE;
                                               *ExitGame = TRUE;
                                               }
                                               }
                                         
                              if ((MNum == 0) &&
                                  (INum == 3) &&
                                  (SNum == 0)) 
                                  { 
                                   if (MakeNewDir())
                                   DispMessage(S,(UBYTE*)"Verzeichnis wurde erstellt");
                                   else
                                   DispMessage(S,(UBYTE*)"Fehler beim Erstellen !");
                                   break;
                                  }
                              if ((MNum == 0) &&
                                  (INum == 3) &&
                                  (SNum == 1)) 
                                  {
                                   EditCDSEditPrefs(S,&Prefs,Vp);
                                   MakeFullName(&Prefs);
                                   MakeFullToName(&Prefs);
                                   break;
                                  }
                                  
                              /* MODUS */
                                         
                              if ((MNum == 1) &&
                                  (INum == 0))  {
                                   if (!Last_Edits_Saved) {
                                       Goon = Decision(S,
                        (UBYTE*)"Letzte Änderungen nicht gesichert ! Weiter ?");
                                              }
                                                    else Goon = TRUE;
                              if (Goon) 
                                 {
                                  ClearLevel(W,Bild);
                                  LoadLevel(*Level,Bild);
                                  PaintScreen(W,Bild,Mx,My); 
                                 }
                               }
                              
                              if ((MNum == 1) &&
                                  (INum == 1)) 
                                  { 
                                   Last_Edits_Saved = !SaveLevel(*Level,Bild);
                                  }
                                                 
                              if ((MNum == 1) &&
                                  (INum == 2)) { Level_Ok =
                                                 CheckLevel(Bild);
                                                 Level_Yet_Checked = TRUE; 
                                                 if (Level_Ok) {
        DispMessage(S,(UBYTE*)"Das Bild ist - soweit getestet - in Ordnung.");
                                                 }
                                                 else {
         DispMessage(S,(UBYTE*)"Das Bild enthält Fehler !!");
                                                 }
                                               }
                                                 
                              if ((MNum == 1) &&
                                  (INum == 3)) { ClearLevel(W,Bild);
                                                 PaintScreen(W,Bild,Mx,My); }
                                                 
                              /* Hier : MenuAbfrage LEVEL  */

                              if ((MNum == 2) && 
                                  (INum != 10)) { *LowLevel = INum; }
                                  
                              if ((MNum == 2) &&
                                  (INum == 10)) { *HighLevel = 10 * SNum; } 
                                  
                              *Level = *LowLevel + *HighLevel;
                             
    			      /* Grafik */
    			      
    			      if (MNum == 3) { Pattern = INum; }
                                     
                              break;

            }   /* Case */

           } /* if */
 return(Answer);
} /* GetIntuiMessage */



WaitForLeftMouseButton()

{
  UBYTE *CIAAPRA = (UBYTE*) 0xBFE001;

  while ((*CIAAPRA & 0x40) != 0 ) {};
  while ((*CIAAPRA & 0x40) == 0 ) {};
}


NewGfxMenu ( menu,menu_items,menu_images,menu_keys,num_items, Mwidth, flag, mutex)

struct Menu      *menu;           /* Menu structure                       */
struct MenuItem  menu_items[];
struct Image     menu_images[];   /* Pointer to array of img. structures  */
UBYTE            menu_keys[];
int               num_items;      /* Number of items                      */
int               Mwidth;         /* Menu Width */
long                flag;         /* Special Item flag for ALL items */
long                mutex;        /* mutualexclude - mask */
{
    int i;
    int height = 0;
 
    for (i=0; i< num_items; i++) {
    
          menu_items[i].NextItem = &menu_items[i+1];  /* Lnk to nxt item */
          menu_items[i].TopEdge = height;
          menu_items[i].LeftEdge = 0;
          menu_items[i].Height = menu_images[i].Height+3;
          menu_items[i].ItemFill = (APTR)&menu_images[i];
          menu_items[i].SelectFill = (APTR)&menu_images[i];
          menu_items[i].Flags = flag | COMMSEQ;
          menu_items[i].Command = menu_keys[i];
          menu_items[i].Width = Mwidth;
          menu_items[i].MutualExclude = ((1 << i) ^ mutex);
          menu_items[i].SubItem = 0L;
          menu_items[i].NextSelect = 0L;
          height += menu_images[i].Height;
          height += 3;
    }
    menu_items[num_items-1].NextItem = 0L;
    menu->Height = height;
    menu->FirstItem = (struct MenuItem*) (&menu_items[0]);
}


NewMenu ( menu, item_names,  menu_items, menu_text, num_items, Mwidth, flag, mutex)

struct Menu      *menu;           /* Menu structure                       */
char             *item_names[];   /* Pointer to array of item names       */
struct MenuItem  menu_items[];    /* pointer to array of structures       */
struct IntuiText menu_text[];     /* Pointer to array of text structures  */
int               num_items;      /* Number of items                      */
int               Mwidth;         /* Menu Width */
long                flag;         /* Special Item flag for ALL items */
long                mutex;        /* mutualexclude - mask */
{
    int i;
    int height = 0;
 
    for (i=0; i< num_items; i++) {
 
          menu_text[i] = generic;
          menu_text[i].IText = (UBYTE *)(item_names[i]);          /* mv string ptrs */
          menu_items[i].NextItem = &menu_items[i+1];  /* Lnk to nxt item */
          menu_items[i].TopEdge = 10 * i;            /* Top rect of item */
          menu_items[i].LeftEdge = 0;
          menu_items[i].Height = FONTHEIGHT;
          menu_items[i].ItemFill = (APTR)&menu_text[i];
          menu_items[i].Flags = flag;
          menu_items[i].Width = Mwidth;
          menu_items[i].MutualExclude = ((1 << i) ^ mutex);
          menu_items[i].Command = 0;
          menu_items[i].SubItem = 0L;
          menu_items[i].NextSelect = 0L;
          height += 10;
    }
    menu_items[num_items-1].NextItem = 0L;
    menu->Height = height;
    menu->FirstItem = (struct MenuItem*) (&menu_items[0]);
}
 
NewSubMenu ( menu,itemnum, item_names,  menu_items, menu_text, num_items, Mwidth, flag, mutex)

struct Menu      *menu;           /* Menu structure                       */
int              itemnum;         /* ItemNum <- SubItems                  */
char             *item_names[];   /* Pointer to array of item names       */
struct MenuItem  menu_items[];    /* pointer to array of structures       */
struct IntuiText menu_text[];     /* Pointer to array of text structures  */
int               num_items;      /* Number of items                      */
int               Mwidth;         /* Menu Width */
long                flag;         /* Special Item flag for ALL items */
long                mutex;        /* mutualexclude - mask */

{
    int i,j;
    int height = 0;
    struct MenuItem *ItemAdr;

    j = 0;
    ItemAdr = menu->FirstItem;
    while ((ItemAdr != 0L) && j<itemnum)
          {
           j++;
           ItemAdr = ItemAdr->NextItem;
          }
    if (ItemAdr == 0L) return;

    for (i=0; i< num_items; i++) {
 
          menu_text[i] = generic;
          menu_text[i].IText = (UBYTE *)(item_names[i]);          /* mv string ptrs */
          menu_items[i].NextItem = &menu_items[i+1];  /* Lnk to nxt item */
          menu_items[i].TopEdge = 10 * i;            /* Top rect of item */
          menu_items[i].LeftEdge = ItemAdr->LeftEdge+ItemAdr->Width;
          menu_items[i].Height = FONTHEIGHT;
          menu_items[i].ItemFill = (APTR)&menu_text[i];
          menu_items[i].Flags = flag;
          menu_items[i].Width = Mwidth;
          menu_items[i].MutualExclude = ((1 << i) ^ mutex);
          menu_items[i].Command = 0;
          menu_items[i].SubItem = 0L;
          menu_items[i].NextSelect = 0L;
          height += 10;
    }
    menu_items[num_items-1].NextItem = 0L;
    ItemAdr->SubItem = (struct MenuItem*) (&menu_items[0]);
}

