/* This file is part of the origami distribution. (Amiga Port)
 *
 * Source code written by Thomas Hadig in September 1991
 * Version : 1.6.42 alpha, June 1992
 * (C) 1992 by Thomas Hadig
 * may be distributed unchanged ! (see copyright notes)
 */

/*{{{  #includes*/
#include <exec/types.h>
/*{{{  standard includes*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <signal.h>
/*}}}  */
#undef TRUE
#undef FALSE
#include <local/bool.h>
/*{{{  amiga system includes*/
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <exec/io.h>
#include <devices/timer.h>
#include <workbench/workbench.h>
#include <workbench/startup.h>
#ifdef LATTICE
#include <dos.h>
#endif
/*}}}  */
/*{{{  amiga prototype includes*/
#ifdef LATTICE
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/console.h>
#include <proto/icon.h>
#include <proto/dos.h>
#include <proto/graphics.h>
#else
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/console_protos.h>
#include <clib/icon_protos.h>
#include <clib/dos_protos.h>
#include <clib/graphics_protos.h>
#endif
/*}}}  */

#define KEYBOARD_C
#define I_SIGNALS_C
#define I_PROMPT_C
#define I_GETTK_C
#define I_KEYTAB_C
#define I_MAIN_C
#define I_FOLDING_C
#define I_VIRTUAL_C
#define I_SCREEN_C
#define I_GETMSG_C
#define I_INIT_C

#include "origami.h"
#include "origami:amiga/h/arexx.h"

#undef PAL

#include <graphics/gfxbase.h>
/*}}}  */

/*{{{  variables*/
/*{{{  menu variables*/
#ifdef MENU
bool   menu_on = FALSE;
struct Menu   *menu_root=NULL;
#endif
/*}}}  */
/*{{{  arexx variables*/
#ifdef AREXX
  struct FORKENV       forkenv = { 5L, 10000L, NULL, NULL, NULL, NULL};
  struct ProcID        arexx_pid;
  struct MsgPort       *arexxport=NULL,*arexxtaskport = NULL;
  struct My_ArexxMessage  arexxmsg,*arexx_tag_msg=NULL;
  char   arexxtaskarg1[15], portname[] = "O12345678",
           oas[]="Origami_Arexx";
  bool   arexx_p = FALSE, arexx = FALSE, arexx_tag = FALSE;
  long   arexx_signal = NULL;
  extern TOKEN *arexx_fix_macro_req,*arexx_fix_macro_ocl;
#endif
/*}}}  */
char **arg_ptr;
/*{{{  window & screen global variables*/
struct Screen        *screen;
struct Window        *wind;
struct TextFont      *tf;
struct RastPort      *rp;
struct IOStdReq      isr;
struct InputEvent    iev /*= {NULL,0x01,0,0,0,0,0,0}*/ ;
bool   screen_yes = FALSE, lace_yes = FALSE, PAL_or_NTSC = PAL_NTSC_DEFAULT;
short  x=0,y=11,width=640,height=DEFAULT_SCREEN_HEIGHT-12,screen_height,
       mul_x=1,mul_y=1,off_y=1;
/*}}}  */
/*{{{  get key global variables*/
struct MsgPort  *mpp;
struct timerequest   tr;
bool   port = FALSE, timer = FALSE;
extern bool cursor_on,aborted;
ULONG  my_signal;
TOKEN  buffer_keys[buffer_keys_max];
int    key_buffer_max = 0;
extern bool num_key_pad;
/*}}}  */
/*{{{  Libraries*/
struct IntuitionBase *IntuitionBase;
struct GfxBase       *GfxBase;
struct Library       *ConsoleDevice;
#ifdef OS13
bool   os20q=FALSE;  /* determined by version of intuition-library >= 36 */
#else
bool   os20q=TRUE;
#endif
/*}}}  */
/*{{{  startup-variables*/
struct WBStartup     *old_argv = NULL,**old_argv_addr;
char   *_procname = "Origami-Editor";
long   _stack = 10000, _priority = 0, _BackGroundIO = 0;
/*}}}  */
/*{{{  ARG_TAB*/
typedef struct
 { char arg,type;
   void *variable;
 } ARG;
#define BOOL_ARG 1
/*}}}  */
/*{{{  MOUSY*/
#ifdef MOUSY
mouse_typ use_mouse=amiga;
public int mouse_b_count[mouse_supports]=
 { 0
      ,AMIGA_MOUSE_COUNT
 };
#ifdef AMIGA_MOUSE_TAG
  char *a_m_n[]=AMIGA_MOUSE_NAMES;
#  define A_M_N   ,a_m_n
#endif
public char **mouse_b_names[mouse_supports]=
 { 0
   A_M_N   /* Amiga-names */
 };
#endif
/*}}}  */
char   command[LINELEN+1];
public bool echo, echo_disabled=FALSE;
public int  knb_mac = 0;
private FILE *kbd_p=NULL;
extern int msflag;
struct IconBase *IconBase;
/*}}}  */

/*{{{  enable and switch echo*/
/*{{{  enable_echo*/
public void enable_echo(bool yes)
{
  echo=(!echo_disabled && yes);
}
/*}}}  */
/*{{{  switch_echo*/
public void switch_echo(bool on)
{
  echo_disabled=!(echo=on);
}
/*}}}  */
/*}}}  */
/*{{{  enable, disable and set abort*/
/*{{{  enable_abort*/
public void enable_abort(void)
{}
/*}}}  */
/*{{{  disable_abort*/
public void disable_abort(void)
{
  signal(SIGINT, SIG_IGN);
}
/*}}}  */
/*{{{  set_abort*/
public void set_abort(char key)
{
  general_abort_key=key;
}
/*}}}  */
/*}}}  */
/*{{{  init and reset keyboard*/
/*{{{  init_keyboard*/
public void init_keyboard(void)
{
  disable_abort();
  enable_echo(!echo_disabled);
}
/*}}}  */
/*{{{  reset_keyboard*/
public void reset_keyboard(void)
{}
/*}}}  */
/*}}}  */
/*{{{  kbd_pipe*/
public bool kbd_pipe(FILE *p)
{
  bool closed;

  if ((closed=(kbd_p!=NULL)) && (pclose(kbd_p)<0))
    err_message(get_msg(M_CLOSE_FAILED),"pipe",TRUE);
  kbd_p=p;
  if ((kbd_p==NULL) && !executing_macro)
    disable_abort();
  else
    enable_abort();
  return(closed);
}
/*}}}  */
/*{{{  get_key procedures*/
/*{{{  MakeRawKey*/
TOKEN MakeRawKey (USHORT code, USHORT quali, char init)

 {
  char b = 65;

  buffer_keys[key_buffer_max++] = init;
  if (quali & 0x0003) b++; /* SHIFT */
  if (quali & 0x0008) b+=2; /* Control */
  if (quali & 0x0030) b+=4; /* ALT */
  if (quali & 0x0040) b+=8; /* left Amiga */
  if (quali & 0x0080) b+=16; /* right Amiga */
  buffer_keys[key_buffer_max++] = b;
  buffer_keys[key_buffer_max++] = code;
  return (TOKEN)CSI;
 }
/*}}}  */
/*{{{  copy_tokens*/
TOKEN copy_tokens(int o,char *buf1)

 {
  int i;

  for (i=0; i<o;buffer_keys[key_buffer_max+i]=(TOKEN)buf1[++i]);
  key_buffer_max += o-1;
  return (TOKEN)buf1[0];
 }
/*}}}  */
/*{{{  inconify*/
void iconify (SHORT ileft,SHORT itop,SHORT iwidth,SHORT iheight)

{
  char fn[_POSIX_PATH_MAX+1] = "Origami";
  struct IntuiMessage *mg;
  bool stop = FALSE;

  if (real_head!=real_tail)
    strcpy(fn,get_data(real_tail));
#  ifdef MENU
  if (menu_on) ClearMenuStrip (wind);
#  endif
  /*{{{  make small*/
  SizeWindow (wind,400-wind->Width,2+off_y-wind->Height);
  MoveWindow (wind,-1*wind->LeftEdge,-1*wind->TopEdge);
  SetWindowTitles (wind,fn,(char *)-1);
  /*}}}  */
  /*{{{  wait for re-activation*/
  do
   {
    Wait (1L << wind->UserPort->mp_SigBit);
    while ((mg = (struct IntuiMessage *)GetMsg (wind->UserPort)))
     {
      if (mg->Class==MENUPICK) stop = TRUE;
      ReplyMsg ((struct Message *) mg);
     }
   } while (!stop);
  /*}}}  */
  /*{{{  make large*/
  MoveWindow (wind,ileft-wind->LeftEdge,itop-wind->TopEdge);
  SizeWindow (wind,iwidth-400,iheight-2-off_y);
  SetWindowTitles (wind,"Origami",(char *)-1);
  /*}}}  */
#  ifdef MENU
  if (menu_on) SetMenuStrip (wind,menu_root);
#  endif
}
/*}}}  */

/*{{{  handle_message*/
TOKEN handle_message (struct IntuiMessage *msg)

 {
  TOKEN tok=0;
  struct IntuiMessage msp;

  msp = *msg;
  ReplyMsg ((struct Message *)msg);
  switch (msp.Class)
   {
    /*{{{  CloseWindow*/
    case CLOSEWINDOW:
      tok = O_QUIT;
      break;
    /*}}}  */
    /*{{{  RawKey*/
    case RAWKEY:
     {
      int o;
      char buf1[20];

      iev.ie_Code = msp.Code;
      iev.ie_Qualifier = msp.Qualifier;
      if ((!(msp.Code&0x80))&&((msp.Code&0x60)!=0x60))
       {
        if (o = RawKeyConvert(&iev,buf1,20,NULL))
         /*{{{  Vanilla key exists*/
         {
          if (msp.Qualifier&0x00F0) /* ALT or AMIGA */
           /*{{{  test if amiga/alt code is different to normal code*/
           {
            char buffer[20];

            iev.ie_Qualifier = 0;
            iev.ie_Code = msp.Code;
            if ((RawKeyConvert(&iev,buffer,20,NULL))==o)
             /*{{{  ALT or AMIGA handled ?*/
             {
              buffer[o]=buf1[o]=0x00;
              if (!strcmp (buffer,buf1))
                tok = MakeRawKey (msp.Code,msp.Qualifier,CSI_RAW_KEY);/*no*/
              else tok = copy_tokens(o,buf1);
             }
             /*}}}  */
            else tok = copy_tokens(o,buf1);
           }
           /*}}}  */
          else
           /*{{{  handle numberpad and keysequences*/
           {
            if (o>1) tok = copy_tokens(o,buf1);
            else if (msp.Qualifier & 0x0100 && num_key_pad) /* number pad */
              tok = MakeRawKey (msp.Code,msp.Qualifier,CSI_NUMBER_PAD);
            else tok = buf1[0];
           }
           /*}}}  */
         }
         /*}}}  */
        else tok = MakeRawKey (msp.Code,msp.Qualifier,CSI_RAW_KEY);
       }
      break;
     }
    /*}}}  */
    /*{{{  NewSize*/
    case NEWSIZE:
      win_changed = TRUE;
      tok = O_PROMPT;
      if ((wind->Width<100)||(wind->Height<40))
      {
        iconify (0,11,(short)639,DEFAULT_SCREEN_HEIGHT-12);
      }
      break;
    /*}}}  */
#    if defined(MENU) | defined(MOUSY)
    /*{{{  MenuPick*/
    case MENUPICK:
      if (msp.Code!=MENUNULL)
       {
#                ifdef MENU
        /*{{{  handling menu-events*/
        tok = CSI;
        buffer_keys[key_buffer_max++] = CSI_MENU_PICK;
        buffer_keys[key_buffer_max++] = 48 + MENUNUM(msp.Code);
        buffer_keys[key_buffer_max++] = 48 + ITEMNUM(msp.Code);
        /*}}}  */
#                endif
       }
#              ifdef MOUSY
      else
       /*{{{  handling mouse-events*/
       {
        int b=12;

        if (msp.Qualifier & 0x03) b++; /* Shift */
        else if (msp.Qualifier & 0x08) b+=2; /* Ctrl */
        else if (msp.Qualifier & 0x30) b+=3; /* Alt */
        else if (msp.Qualifier & 0x40) b+=4; /* left Amiga */
        else if (msp.Qualifier & 0x80) b+=5; /* right Amiga */
        tok = handle_click ((msp.MouseX-Off_X)/Mul_X,
          (msp.MouseY-Off_Y)/Mul_Y,b);
        break;
       }
       /*}}}  */
#              endif
      break;
    /*}}}  */
#    endif
#    if defined(MOUSY) | defined(ICONIFY)
    /*{{{  MouseButtons*/
    case MOUSEBUTTONS:
     {
      int b = 0;

      if ((msp.MouseY-Off_Y)/Mul_Y<screen_lines-1)
       /*{{{  mouse-handling*/
       {
#                      ifdef MOUSY
        if ((msp.Code & SELECTUP) == (SELECTDOWN)) b = 6;
        /* b = 12  will be used in MENU PICK for RIGHT button */
        if ((msp.Code & MIDDLEUP) == (MIDDLEUP)) b = 18;
        if ((msp.Code & MIDDLEUP) == (MIDDLEDOWN)) b = 24;
        if (msp.Qualifier & 0x03) b++; /* Shift */
        else if (msp.Qualifier & 0x08) b+=2; /* Ctrl */
        else if (msp.Qualifier & 0x30) b+=3; /* Alt */
        else if (msp.Qualifier & 0x40) b+=4; /* left Amiga */
        else if (msp.Qualifier & 0x80) b+=5; /* right Amiga */
        tok = handle_click ((msp.MouseX-Off_X)/Mul_X,
          (msp.MouseY-Off_Y)/Mul_Y,b);
        break;
#                      endif
       }
       /*}}}  */
      else
       /*{{{  inconify*/
       {
#                      ifdef ICONIFY
        if ((msp.MouseY-Off_Y)/Mul_Y>screen_lines-1)
          iconify (wind->LeftEdge,wind->TopEdge,wind->Width,wind->Height);
#                      endif
       }
       /*}}}  */
     }
    /*}}}  */
#    endif
#    ifdef PRIORITY
    /*{{{  ActiveWindow*/
    case ACTIVEWINDOW:
      if (mpp->mp_SigTask) SetTaskPri (mpp->mp_SigTask,3);
      break;
    /*}}}  */
    /*{{{  InActiveWindow*/
    case INACTIVEWINDOW:
      if (mpp->mp_SigTask) SetTaskPri (mpp->mp_SigTask,0);
      break;
    /*}}}  */
#    endif
   }
  return tok;
 }
/*}}}  */
/*{{{  TOKEN get_code (void)*/
TOKEN get_code (void)

 {
  TOKEN tok = 0;
  struct IntuiMessage *msg;
  int i;

  /*{{{  keys there, that aren't used till now*/
  if (key_buffer_max)
   {
    tok = buffer_keys[0];
    for (i=0; i<key_buffer_max; buffer_keys[i]=buffer_keys[++i]);
    key_buffer_max--;
   }
  /*}}}  */
  else
   {
    while (!tok)
     {
#      ifdef AREXX
      /*{{{  got signal from arexx ?*/
      if ((!arexx_tag_msg)&&(arexxport))
       {
        if (arexx_tag_msg = (struct My_ArexxMessage *)GetMsg (arexxport))
         {
          if (arexx_tag_msg->ExecMessage.mn_Node.ln_Type!=NT_REPLYMSG)
            arexx_tag = TRUE;
          else
            arexx_tag_msg=NULL;
         }
       }
      /*}}}  */
#      endif
      /*{{{  got signal from timer.device ?*/
      if (msg = (struct IntuiMessage *)GetMsg (mpp))
       {
        if (msg->ExecMessage.mn_Node.ln_Type!= NT_REPLYMSG)
          ReplyMsg((struct Message *)msg);
        got_alarm(0);
       }
      /*}}}  */
      /*{{{  got signal from intuition ?*/
      if ((msg = (struct IntuiMessage *)GetMsg (wind->UserPort)))
        tok = handle_message (msg);
      /*}}}  */
      else Wait ((1L << wind->UserPort->mp_SigBit)|(my_signal)
#      ifdef AREXX
      |(arexx_signal)
#      endif
      );
     }
   }
  return tok;
 }
/*}}}  */
/*{{{  get_key*/
public TOKEN get_key (void)
{
  /*{{{  variables*/
  int result= keytabcont;
  unsigned int ch=general_abort_key;
  int lg=0;
  int cp=0;
  char pread;
  /*}}}  */

  if (!cursor_on) Set_Cursor();
  /*{{{  scan a keyboard-sequence 'til token is complete*/
  while (result==keytabcont && !aborted) {
    /*{{{  maybe read from pipe*/
    if (kbd_p!=NULL) {
      pread=getc(kbd_p);
      if (pread==EOF)
        kbd_pipe(NULL);
      else
        ch=pread;
    }
    /*}}}  */
    if (kbd_p==NULL)
      ch = get_code();
    lg++;
    if (ch<256)
     {
      result=find_key(ch);
      /*{{{  echo-handling*/
      if (echo && result==keytabcont) {
        /*{{{  append code to string*/
        if (ch>=' ') {
          /*{{{  x*/
          command[cp++]=ch;
          command[cp++]=' ';
          /*}}}  */
        } else if (ch=='\033') {
          /*{{{  M-*/
          command[cp++]='M';
          command[cp++]='-';
          /*}}}  */
        } else if (ch>=0 && ch<' ') {
          /*{{{  C-x*/
          command[cp++]='C';
          command[cp++]='-';
          command[cp++]='@'+ch;
          command[cp++]=' ';
          /*}}}  */
        } else if (ch==CSI) {
          /*{{{  S-*/
          command[cp++]='S';
          command[cp++]='-';
          /*}}}  */
        } else {
          /*{{{  ?*/
          command[cp++]='?';
          command[cp++]=' ';
          /*}}}  */
        }
        command[cp]='\0';
        /*}}}  */
        message(command,FALSE);
      }
      /*}}}  */
     }
    else result = ch;
  }
  /*}}}  */
  if (aborted) return(O_BREAK);
  if (result!=keytabend)
    return (result);
  else if (ch==general_abort_key) {
    aborted=TRUE;
    return(O_BREAK);
  } else if (lg==1)
    return((TOKEN)ch);
  if (knb_mac)
     call_number_macro(knb_mac);
  else if (echo) message(get_msg(M_NOT_BOUND), TRUE);
  return(O_NOP);
}
/*}}}  */
/*{{{  scan_abort_key*/
void scan_abort_key (void)

 {
  struct IntuiMessage *msg;
  bool stop = FALSE;
  TOKEN tok;
  int old_key_buf;

  if (key_buffer_max>=buffer_keys_max-5) /* There are no keysequencese */
    return;                              /* longer than five codes */
  while ((!aborted)&&(!stop)&&(key_buffer_max<buffer_keys_max-5))
   {
    tok =0;
    if (msg = (struct IntuiMessage *)GetMsg (wind->UserPort))
     {
      old_key_buf = key_buffer_max;  /* one place for tok */
      key_buffer_max++;
      tok = handle_message (msg);
      if ((tok == general_abort_key)||(!tok))
       {
        key_buffer_max--; /* don't need one place for tok */
        if (tok) ori_abort(0);     /* no codes after abort_key */
       }
      else buffer_keys[old_key_buf]=tok;
     }
    else stop = TRUE;
   }
 }
/*}}}  */
/*}}}  */
/*{{{  init and reset amiga*/
/*{{{  getascnum*/
char *getascnum (char *cptr,short *sptr)

 {
  if (!isdigit(cptr[0])) return NULL;
  *sptr = atoi (cptr);
  while (isdigit(cptr[0])) cptr++;
  return cptr;
 }
/*}}}  */
/*{{{  int reset_amiga (void)*/
int reset_amiga (void)

 {
  if (wind) ClrScr();
  if (ConsoleDevice) { CloseDevice (&isr); ConsoleDevice = NULL; }
  if (timer) { CloseDevice ((struct IORequest *)&tr); timer = FALSE; }
  if (port) { RemPort (mpp); port = FALSE; }
  if (mpp->mp_SigBit!=-1) FreeSignal (mpp->mp_SigBit);
#  ifdef AREXX
  if ((arexx)&&(arexx_p))
    /*{{{  wait till arexx-task has ended*/
    {
     int stop = 0;

     arexxmsg.ExecMessage.mn_Node.ln_Type = NT_MESSAGE;
     arexxmsg.class = AREXX_COME_DOWN;
     if (arexxtaskport)
      {
       PutMsg (arexxtaskport,(struct Message *)&arexxmsg);
       do
        {
         struct My_ArexxMessage *msg;

         WaitPort (arexxport);
         while ((msg = (struct My_ArexxMessage *)GetMsg (arexxport))&&(!stop))
          {
           if (msg->class == AREXX_CAME_DOWN)
            {
             PutMsg (arexxport,(struct Message *)msg);
             wait (&arexx_pid);
             stop = 1;
            }
           else if (msg->ExecMessage.mn_Node.ln_Type != NT_REPLYMSG)
             ReplyMsg ((struct Message *)msg);
          }
        } while (!stop);
      }
     arexx = FALSE;
    }
    /*}}}  */
  if (arexx_p) { RemPort (arexxport); arexx_p = FALSE; }
#  endif
#  ifdef MENU
  if (menu_on) { ClearMenuStrip(wind); menu_on = FALSE; }
#  endif
  if (wind) { CloseWindow (wind); wind = NULL; }
  if (screen)
   {
    if (!(screen->FirstWindow)) CloseScreen (screen);
    screen = NULL;
   }
  if (GfxBase) { CloseLibrary (GfxBase); GfxBase = NULL; }
  if (IntuitionBase)
   {
    CloseLibrary ((struct Library *)IntuitionBase);
    IntuitionBase = NULL;
   }
  return 0;
 }
/*}}}  */
/*{{{  char **init_amiga (argc,argv)*/
char **init_amiga (int *argc, struct WBStartup *argv)

 {
  /*{{{  variables*/
  /*{{{  structures*/
  struct NewWindow nw = {0,0,0,0,-1,-1,
         MENUPICK | CLOSEWINDOW | NEWSIZE | RAWKEY | ACTIVEWINDOW |
           INACTIVEWINDOW | MOUSEBUTTONS,
         WINDOWSIZING | WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE | ACTIVATE,
         NULL, NULL, "Origami", NULL, NULL, 150, 10, 631, 200,
         WBENCHSCREEN };
  struct Menu *menu=NULL,*last_menu;
  struct MenuItem *item=NULL,*last_item;
  struct IntuiText *text;
  struct FileInfoBlock fib;
  struct FileLock *fl;
  struct DiskObject    *dis = NULL;
  /*}}}  */
  char   name[_POSIX_PATH_MAX],*dev,*ptr,f2[_POSIX_PATH_MAX],*dptr;
#      ifndef LATTICE
  char   store[_POSIX_PATH_MAX];
#      endif
  FILE   *fp;
  int i,j;
  short x2=0,y2=0,w2=0,h2=0;

#      ifdef AREXX
#      define argmax 1
  ARG amiga_arg_tab[argmax] =
   {
    'R', BOOL_ARG, &arexx
   };
#      endif
  /*}}}  */

  /*{{{  open libraries*/
  /*{{{  determine if intuition version 2_0 or 1_3*/
#      ifdef OS20
  if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary (
       "intuition.library",36L)))
   {
#      endif
#        ifdef OS13
    if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary (
         "intuition.library",0L)))
#        endif
      exit (1);
#        ifdef OS13
    else os20q=FALSE;
#        endif
#      ifdef OS20
   }
  else os20q=TRUE;
#      endif
  /*}}}  */
  if (!(GfxBase = (struct GfxBase *)OpenLibrary ("graphics.library",0L)))
   {
    reset_amiga();
    exit (1);
   }
  /*}}}  */
  /*{{{  open terminal window*/
  if (dev = getenv ("ORITERM"))
   {
    /*{{{  get special window datas*/
    ptr = dev;
    while (ptr[0])
     {
      char *pptr;

      pptr = ptr;
      while (ptr[0]&&(ptr[0]!=0x3A)&&(ptr[0]!=0x2C)) ptr++;
      switch (ptr-pptr)
       {
        /*{{{  3 chars*/
        case 3:
          if (!(strnicmp (pptr,"PAL",3))) PAL_or_NTSC = PAL_TYPE;
          break;
        /*}}}  */
        /*{{{  4 chars*/
        case 4:
          if (!(strnicmp (pptr,"NTSC",4))) PAL_or_NTSC = NTSC_TYPE;
          else if (!(strnicmp (pptr,"LACE",4))) lace_yes = TRUE;
          break;
        /*}}}  */
        /*{{{  6 chars*/
        case 6:
          if (!(strnicmp (pptr,"WINDOW",6)))
           /*{{{  Get window size*/
           {
            if (*ptr==0x3A) /* : */
             {
              if (!(ptr = getascnum (++ptr,&x2))) break;
              if (ptr[0]!=0x2F) break;   /* / */
              if (!(ptr = getascnum (ptr+1,&y2))) break;
              if (ptr[0]!=0x2F) break;   /* / */
              if (!(ptr = getascnum (ptr+1,&w2))) break;
              if (ptr[0]!=0x2F) break;   /* / */
              if (!(ptr = getascnum (ptr+1,&h2))) break;
             }
           }
           /*}}}  */
          else
           {
            if (strnicmp (pptr,"SCREEN",6)) break;
            screen_yes = TRUE;
           }
          break;
        /*}}}  */
       }
      if (ptr[0]==0x3A) break;
      ptr++;
     }
    /*}}}  */
   }
  screen_height = (PAL_or_NTSC ? NTSC_SCREEN_HEIGHT : PAL_SCREEN_HEIGHT);
  if (x2 || y2 || w2 || h2)
  {
    x = x2; y=y2; width=w2; height=h2;
  }
  else
  {
    x=0; y=11; width=640; height=screen_height-12;
  }
  if (lace_yes) screen_height *= 2;
  if (screen_yes)
   /*{{{  Open screen and window*/
   {
    bool not_equal;

    /*{{{  Exists Screen ?*/
    screen = IntuitionBase->FirstScreen;
    do
     {
      if (not_equal = strcmp(screen->Title,"Origami"))
        screen = screen->NextScreen;
     } while ((not_equal)&&(screen));
    /*}}}  */
    if (!screen)
     /*{{{  Open Screen*/
     {
      struct NewScreen ns = {0,0,640,0,2,
               0,1,HIRES,CUSTOMSCREEN,NULL,"Origami",NULL,NULL};

      if (lace_yes) ns.ViewModes |= LACE;
      ns.Height = screen_height;
      if (!(screen = (struct Screen *) OpenScreen (&ns)))
       {
        reset_amiga();
        exit (1);
       }
     }
     /*}}}  */
    /*{{{  Get Font Size*/
    off_y=screen->Font->ta_YSize;
    /*}}}  */
    /*{{{  Open Window*/
    nw.Type = CUSTOMSCREEN;
    nw.MaxWidth = screen->Width;
    nw.MaxHeight = screen->Height;
    nw.Screen = screen;
    if (height+y>nw.MaxHeight) height = nw.MaxHeight-y-1;
    nw.Height = height;
    nw.Width = width;
    nw.TopEdge = y;
    nw.LeftEdge = x;
    if (!(wind = (struct Window *) OpenWindow (&nw)))
     {
      reset_amiga();
      exit (1);
     }
    /*}}}  */
   }
   /*}}}  */
  else
   /*{{{  Open window*/
   {
    /*{{{  Get Screen & Font Size*/
    struct Screen wbscreen, *wscreen;

    /*{{{  OS 13 & 20*/
#            ifdef OS13
#            ifdef OS20
    if (!os20q)
    {
#            endif /* OS13,20*/
    /*}}}  */
    /*{{{  OS 13*/
      if (GetScreenData ((APTR)&wbscreen,sizeof (struct Screen),
          WBENCHSCREEN,NULL))
      {
        off_y=wbscreen.Font->ta_YSize;
        nw.MaxHeight = wbscreen.Height;
        nw.MaxWidth  = wbscreen.Width;
        if (height+y>nw.MaxHeight) height = nw.MaxHeight-y-1;
      }
#            endif /* OS13*/
    /*}}}  */
    /*{{{  OS 13 & 20*/
#            ifdef OS20
#            ifdef OS13
    }
    else
    {
#            endif /* OS13,20 */
    /*}}}  */
    /*{{{  OS 20*/
    if (wscreen = LockPubScreen (NULL))
    {
      off_y=wscreen->Font->ta_YSize;
      nw.MaxHeight = wscreen->Height;
      nw.MaxWidth  = wscreen->Width;
      if (height+y>nw.MaxHeight) height = nw.MaxHeight-y-1;
      UnlockPubScreen (NULL,wscreen);
    }
    /*}}}  */
    /*{{{  OS 13 & 20*/
#            ifdef OS13
    }
#            endif /*OS13,20 */
#            endif /*OS20*/
    /*}}}  */
    /*}}}  */
    nw.LeftEdge = x;
    nw.TopEdge = y;
    nw.Width = width;
    nw.Height = height;

    if (!(wind = (struct Window *) OpenWindow (&nw)))
     {
      reset_amiga();
      exit (1);
     }
   }
   /*}}}  */
  get_terminal_capability();  /* setzt screen_lines */
  /*}}}  */
  /*{{{  sets font, rastport and cursor*/
  tf = GfxBase->DefaultFont;
  mul_x = tf->tf_XSize;
  mul_y = tf->tf_YSize;
  rp = wind->RPort;
  SetFont (rp,tf);
  move_to_pos();
  /*}}}  */
#  ifdef LATTICE
  /*{{{  close stderr*/
  if (stderr) fclose (stderr);
  /*}}}  */
#  endif
  /*{{{  started form Workbench ?*/
  if (!*argc)
   {
    /*{{{  malloc pointer list*/
    if (!(arg_ptr = (char **)malloc (20*sizeof (char *))))
     {
      reset_amiga();
      exit (11);
     }
    /*}}}  */
    arg_ptr[0] = argv->sm_ArgList[0].wa_Name;
    j=1;
    /*{{{  look for arguments in .info file*/
    if (IconBase = (struct IconBase *)OpenLibrary ("icon.library",NULL))
     {
      if (dis = GetDiskObject (arg_ptr[0]))
       {
        i = 0;

        while (ptr = dis->do_ToolTypes[i])
         {
          if ((j<19)&&(*(stpblk (ptr))!=0x00))
            if (!(arg_ptr[j++]=strdup (dis->do_ToolTypes[i]))) exit (12);
          i++;
         }
        FreeDiskObject (dis);
       }
     }
    /*}}}  */
    i=1;
    /*{{{  get additonal filenames as arguments*/
    while ((i<argv->sm_NumArgs)&&(j<19))
     {
      strcpy (name,argv->sm_ArgList[i].wa_Name);
      fl = (struct FileLock *)argv->sm_ArgList[i].wa_Lock;
      if (arg_ptr[j] = malloc (_POSIX_PATH_MAX))
       {
        do
         {
          if (Examine ((BPTR)fl, &fib))
           {
            strcpy (f2, name);
            strcpy (name, fib.fib_FileName);
            if ((strlen (name))&&(name[strlen (name)-1]!='/')&&
                (name[strlen (name)-1]!=':'))
              strncat (name, "/",_POSIX_PATH_MAX-strlen(name));
            strncat (name, f2, _POSIX_PATH_MAX - strlen(name));
           }
         } while (fl = (struct FileLock *)ParentDir ((BPTR)fl));
        if (ptr = strchr (name,'/')) ptr[0]=':';
        strcpy (arg_ptr[j++], name);
       }
      i++;
     }
    /*}}}  */
    arg_ptr[j] = NULL;
    *argc = j;
    old_argv = argv;
    old_argv_addr = &argv;
    argv = (struct WBStartup *)arg_ptr;
   }
  /*}}}  */
  /*{{{  look for ms-dos wildcards*/
  msflag = 1;
  i=1;
  j=0;
  dev = ptr = NULL;
  while (i<*argc)
   {
    if (strpbrk(((char **)argv)[i],"?*"))
     {
      int n;

      if (!dev)
       {
        dev = malloc (300*sizeof(char *));
        for (j=0; j<i; ((char **)dev)[j]=((char **)argv)[j++]);
        j=i;
       }
      ptr = calloc (1,1000);
      if (ptr)
       {
#            ifndef LATTICE
        /*{{{  exchange * to #? for dice*/
         {
          int j=0;
          char *cptr = ((char **)argv)[i];

          while ((*cptr)&&(j<_POSIX_PATH_MAX-1))
           {
            if (*cptr=='*')
             {
              store[j++]='#';
              store[j++]='?';
             }
            else store[j++]=cptr[0];
            cptr++;
           }
          store[j]=0;
          dptr = store;
         }
        /*}}}  */
#            else
        dptr = ((char **)argv)[i];
#            endif
        n = getfnl (dptr,ptr,3000,0);
        if (n>0)
         {
          j += strbpl (&(((char **)dev)[j]),300-j-1,ptr);
         }
        else ((char **)dev)[j++]=dptr;
       }
      else ((char **)dev)[j++]=((char **)argv)[i];
     }
    i++;
   }
  ((char **)dev)[j]=NULL;
  if (dev)
   {
    argv=(struct WBStartUp *)dev;
    *argc=j;
   }
  /*}}}  */
  /*{{{  reset argv[0], argparse Amiga options*/
  stcgfn (f2,((char **)argv)[0]);  /* skip leeding path (e.g. c:origami -> origami ) */
  strcpy (((char **)argv)[0],f2);
#      ifdef AREXX
  *argc = argparse (*argc,(char **)argv,amiga_arg_tab,argmax);
#      endif
  /*}}}  */
#  ifdef MENU
  /*{{{  use argv[0] to generate the namebase*/
  {
    char *s=((char **)argv)[0];
    char *x=s;

    /*{{{  cut the leading path*/
    while (*x) if (*(x++) == PATH_C) s=x;
    /*}}}  */
    rc_name = malloc (strlen(s)+1);
    strcpy (rc_name,".");
    strcat (rc_name,s);
  }
  /*}}}  */
  /*{{{  initialise menustrip, if .origamimenu files exists*/
  if (fp = fopen (open_sysfile ("menu"),"r"))
   {
    int menu_y = 1,mx=10,fileend=0,my=0,stop=0;

    while ((!feof (fp))&&(!fileend)&&(!stop))
     {
      /*{{{  Menu-Daten laden und vorbereiten*/
      fgets (name,20,fp);
      if (name[0]=='#')
       /*{{{  neues Menue oder File-Ende*/
       {
        if (menu_y) fileend = 1;
        else menu_y = 1;
       }
       /*}}}  */
      else
       /*{{{  Name neu eintragen*/
       {
        char  *ptr;

        if (ptr = strchr (name,'\n')) *ptr=0x00;
        if (menu_y)
         {
          /*{{{  Menu-Struktur initialisieren*/
          last_menu = menu;
          if (!(menu=(struct Menu *)malloc (sizeof (struct Menu))))
           {
            /*{{{  no mem for menus*/
            exit3: menu = menu_root;
            while (menu)
             {
              item = menu->FirstItem;
              while (item)
               {
                last_item = item;
                item = item->NextItem;
                free (((struct IntuiText*)(last_item->ItemFill))->IText);
                free (last_item->ItemFill);
                free (last_item);
               }
              last_menu = menu;
              menu = menu->NextMenu;
              free(last_menu->MenuName);
              free(last_menu);
             }
            stop=1;
            /*}}}  */
           }
          if (!stop)
           {
            menu->NextMenu = NULL;
            menu->LeftEdge = mx;
            menu->TopEdge = 0;
            menu->Width = strlen (name)*off_y + 16;
            menu->Height = off_y +2;
            menu->Flags = MENUENABLED;
            if (!(menu->MenuName = strdup (name)))
             {
              free (menu);
              goto exit3;
             }
            menu->FirstItem = NULL;
            if (!(menu_root)) menu_root = menu;
            else last_menu->NextMenu = menu;
            menu_y = 0;
            my = 0;
            mx += menu->Width + 5;
           }
          /*}}}  */
         }
        else
         {
          /*{{{  Item-Struktur initialisieren*/
          last_item = item;
          if (!(text=(struct IntuiText *)malloc (sizeof (struct
            IntuiText))))
           {
            goto exit3;
           }
          if (!(item=(struct MenuItem *)malloc (sizeof (struct
            MenuItem))))
           {
            free (text);
            goto exit3;
           }
          text->FrontPen = 0;
          text->BackPen = 1;
          text->DrawMode = JAM1;
          text->LeftEdge = 8;
          text->TopEdge = 2;
          text->ITextFont = NULL;
          if (!(text->IText = strdup (name)))
           {
            free (text);
            free (item);
            goto exit3;
           }
          text->NextText = NULL;
          item->NextItem = NULL;
          item->LeftEdge = -5;
          item->TopEdge = my * (2+off_y);
          item->Width = (strlen (name)+2) * off_y;
          item->Height = 2+off_y;
          item->Flags = ITEMENABLED | ITEMTEXT | HIGHCOMP;
          item->MutualExclude = 0;
          item->ItemFill = (APTR)text;
          item->SelectFill = 0;
          item->Command = 0;
          item->SubItem = NULL;
          item->NextSelect = 0;
          my++;
          if (menu->FirstItem) last_item->NextItem = item;
          else menu->FirstItem = item;
          /*}}}  */
         }
       }
       /*}}}  */
      /*}}}  */
     }
    fclose (fp);
    if (!stop)
     {
      SetMenuStrip (wind,menu_root);
      menu_on =1;
     }
   }
  /*}}}  */
  if (rc_name) free(rc_name);
  rc_name=NULL;
#  endif
#  if 0
  /*{{{  Open Font*/
   {
    struct TextAttr ta = {"topaz.font",TOPAZ_EIGHTY,0,FPF_ROMFONT};

    tf = OpenFont (&ta);
    SetFont (rp,tf);
    move_to_pos();
   }
  /*}}}  */
#  endif
  /*{{{  Set exit trap to reset_amiga*/
#      ifdef LATTICE
  if (!atexit (&reset_amiga))
#      else
  if (atexit (&reset_amiga)!=0)
#      endif
   {
    reset_amiga();
    exit (10);
   }
  /*}}}  */
  /*{{{  Prepare auto-save*/
  if ((mpp =CreatePort ("Origami-Timer",0L))!=NULL)
   {
    my_signal = 1<<mpp->mp_SigBit;
    port = TRUE;
    tr.tr_node.io_Command = TR_GETSYSTIME;
    tr.tr_node.io_Message.mn_ReplyPort = mpp;
    if (!OpenDevice ("timer.device",0,(struct IORequest *)&tr,0))
      timer = TRUE;
   }
  /*}}}  */
  /*{{{  init inputevent*/
  iev.ie_NextEvent = NULL;
  iev.ie_Class = 0x01;
  iev.ie_SubClass = 0;
  iev.ie_Code = 0;
  iev.ie_Qualifier = 0;
  iev.ie_position.ie_addr = NULL;
  iev.ie_TimeStamp.tv_secs = 0;
  iev.ie_TimeStamp.tv_micro = 0;
  /*}}}  */
#  ifdef AREXX
  /*{{{  Create Arexx Port*/
  if (arexx)
   {
    arexx = FALSE;
    sprintf (portname,"O%x",FindTask(NULL));
    if (arexxport  = CreatePort (portname,0))
     {
      arexx_p = TRUE;
      arexx_signal = 1 << arexxport->mp_SigBit;
      forkenv.msgport = arexxport;
      if (!(forkl (oas,oas,portname,NULL,&forkenv,&arexx_pid)))
       {
        struct My_ArexxMessage *mam;
        int stop = 0;

        arexx = TRUE;
        do
         {
          WaitPort (arexxport);
          while (mam = (struct My_ArexxMessage *)GetMsg (arexxport))
           {
            if (mam->class==AREXX_CAME_UP)
             {
              arexxtaskport = mam->ExecMessage.mn_ReplyPort;
              stop=1;
             }
            else if (mam->ExecMessage.mn_Node.ln_Type!=NT_REPLYMSG)
              ReplyMsg ((struct Message *)mam);
           }
         } while (!stop);
        arexxmsg.ExecMessage.mn_Node.ln_Type = NT_REPLYMSG;
       }
     }
   }
  /*}}}  */
#  endif
  /*{{{  Open Console Device*/
  if (OpenDevice ("console.device",CONU_LIBRARY,&isr,0)) exit (5);
  ConsoleDevice = (struct Library *)isr.io_Device;
  /*}}}  */
  return (char **)argv;
 }
/*}}}  */
/*}}}  */
