home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / nethack-3.1 / sys / amiga / amiwbench.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-25  |  12.3 KB  |  501 lines

  1. /*    SCCS Id: @(#)amiwbench.c      3.1   93/01/08
  2. /*    Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1990, 1992, 1993 */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. /*  Amiga Workbench interface  */
  6.  
  7. #include "hack.h"
  8.  
  9. /* Have to #undef CLOSE, because it's used in display.h and intuition.h */
  10. #undef CLOSE
  11.  
  12. #ifdef __SASC
  13. # undef COUNT
  14. # include <proto/exec.h>
  15. # include <proto/dos.h>
  16. # include <proto/icon.h>
  17. #endif
  18.  
  19. #include <workbench/startup.h>
  20. #include <workbench/workbench.h>
  21. #include <exec/memory.h>
  22. #include <ctype.h>
  23.  
  24. #ifdef __SASC
  25. # include <string.h>
  26. # undef strlen          /* grrr */
  27. #endif
  28.  
  29. #define ALLOC_SIZE      ((long)sizeof(struct FileInfoBlock))
  30.  
  31. #ifdef AZTEC_C
  32. # include <functions.h>
  33. extern struct Library *IconBase;
  34. #endif
  35.  
  36. extern int FDECL(parse_config_line, (FILE *, char *, char *, char *));
  37.  
  38. int ami_argc;           /* global argc */
  39. char **ami_argv;        /* global argv */
  40. boolean FromWBench=0;       /* how did we get started? */
  41. boolean FromCLI=0;      /* via frontend and INTERNALCLI */
  42. static BOOL FromTool=0;     /* or from Project (ergo nothing to restore) */
  43. static char argline[80];    /* fake command line from ToolTypes */
  44. static BOOL TTparse=0;      /* parsing tooltypes? */
  45. static BOOL KillIcon=FALSE; /* delayed expunge of user's icon */
  46. static char iconname[PATHLEN+5];
  47. static char origicon[PATHLEN+5];
  48. static char savefname[PL_NSIZ];     /* name from name of save file */
  49.  
  50. extern int bigscreen;
  51. extern const char *classes; /* liberated from pcmain */
  52. extern char PATH[];
  53.  
  54. /* Called after NetHack.cnf (and maybe NETHACKOPTIONS) are read.
  55.  * If this is a request to show the score file, do it here and quit.
  56.  */
  57. void ami_wbench_init()
  58. {
  59.     struct WBStartup *wbs=(struct WBStartup *)ami_argv;
  60.     struct WBArg *wa;
  61.     int ia;         /* arg of active icon */
  62.     int x,doscore=0;
  63.     char    *p,*lp;
  64.     BPTR    olddir;         /* starting directory */
  65.     struct DiskObject *dobj;
  66.     char    *scorearg, *t;
  67.     char    tmp_levels[PATHLEN];
  68.  
  69.     FromWBench=(ami_argc==0);
  70.     if(!FromWBench)return;          /* nothing if from CLI */
  71.  
  72.     /*
  73.      * "NULL" out arrays
  74.      */
  75.     tmp_levels[0]  = '\0';
  76.  
  77.     IconBase=OpenLibrary("icon.library",33L);
  78.     if(!IconBase)error("icon.library missing!");
  79.  
  80.     wa=wbs->sm_ArgList;
  81.     if(wbs->sm_NumArgs>2)error("You can only play one game at a time!");
  82.     ia=wbs->sm_NumArgs-1;
  83.  
  84.     if(strcmp("NewGame",wa[ia].wa_Name)){
  85.     strcpy(savefname,wa[ia].wa_Name);
  86.     strcpy(plname,wa[ia].wa_Name);
  87.     }
  88.  
  89.     if( ( t = strrchr( plname, '.' ) ) && strcmp( t, ".sav" ) == 0 )
  90.     *t = 0;
  91.  
  92.     olddir=CurrentDir(wa[ia].wa_Lock);   /* where the icon is */
  93.  
  94.     dobj=GetDiskObject(wa[ia].wa_Name);
  95.     (void)CurrentDir(olddir);       /* and back */
  96.     if(!dobj){
  97.     error("Sorry, I can't find your icon!");
  98.     }
  99.  
  100.     FromTool=(dobj->do_Type==WBTOOL)?1:
  101.     (dobj->do_Type==WBPROJECT)?0:
  102.     (error("Sorry, I don't recognize this icon type!"),1);
  103.  
  104.     if(index(savefname,'.') && !strncmp(index(savefname,'.'),".sav",4)){
  105.     *index(savefname,'.')='\0';
  106.     } else {
  107.     savefname[0]='\0';  /* don't override if not save file */
  108.     FromTool = 1;
  109.     }
  110.  
  111.     argline[0]='\0';
  112.     if( p = FindToolType( dobj->do_ToolTypes, "SCREEN" ) )
  113.     {
  114.     extern int bigscreen;
  115.     if( MatchToolValue( p, "NOLACE" ) )
  116.         bigscreen = -1;
  117.     else if( MatchToolValue( p, "LACE" ) )
  118.         bigscreen = 1;
  119.     }
  120.     if(dobj->do_ToolTypes)for(x=0;p=dobj->do_ToolTypes[x];x++){
  121.     lp=index(p,'=');
  122.     if( !lp++ || strncmp(p, "SCORE", 5 ) == 0 ){
  123.         if((strncmp(p,"SCORES",6)==0) || (strncmp(p,"SCORE",5)==0)){
  124.         if( !lp ) lp = "";
  125.         doscore=1;
  126.         scorearg=(char *)alloc(strlen(lp)+1);
  127.         strcpy(scorearg,lp);
  128.         } else {
  129.         TTparse=TRUE;
  130.         parseoptions(p,(boolean)TRUE,(boolean)FALSE);
  131.         TTparse=FALSE;
  132.         }
  133.     } else {
  134.         TTparse=TRUE;
  135.         /* new things */
  136.         if((strncmp(p,"CMDLINE",7)==0)||
  137.           (strncmp(p,"COMMANDLINE",11)==0)||
  138.           (strncmp(p,"INTERNALCLI",11)==0)){
  139.             strncpy(argline,lp,79);
  140.         if(*p=='I'){
  141.             FromTool=0; /* ugly hack bugfix */
  142.             FromCLI=1;  /* frontend ICLI only */
  143.         }
  144.         }
  145.         else if( strncmp( p, "SCREEN",6 ) )
  146.         {
  147.         if (!parse_config_line((FILE *)0, p, 0, tmp_levels)){
  148.             raw_printf("Bad ToolTypes line: '%s'\n",p);
  149.             getreturn("to continue");
  150.         }
  151.         }
  152.     TTparse=FALSE;
  153.     }
  154.     }
  155.     /* cleanup - from files.c, except we only change things
  156.      * that are explicitly changed, since we already
  157.      * did this once to get the defaults (in amidos.c)  */
  158.     if(plname[0]){
  159.     plnamesuffix(); /* from files.c */
  160.     set_savefile_name();
  161.     }
  162.     if(tmp_levels[0])strcpy(permbones,tmp_levels);
  163.     if(tmp_levels[0]){
  164.     strcpy(levels,tmp_levels);
  165.     strcpy(bones,levels);
  166.     }
  167.     FreeDiskObject(dobj);   /* we'll get it again later if we need it */
  168.  
  169.     if(doscore){
  170.     long ac;
  171.     char *p;
  172.     char **av=calloc(1,50*sizeof(char *));
  173. #ifdef CHDIR
  174.     chdirx(hackdir,0);
  175. #endif
  176.     av[0]="NetHack";            /* why not? */
  177.     av[1]="-s";             /* why not? */
  178.     for(ac=2,p=scorearg;*p;ac++){
  179.         av[ac]=p;
  180.         while(*p && !isspace(*p))p++;
  181.         if(!*p)break;
  182.         *p++='\0';
  183.         while(*p && isspace(*p))p++;
  184.     }
  185.     prscore(ac+1,av);
  186.     free( av );
  187.     exit(0);        /* overloaded */
  188.     }
  189.  
  190.         /* if the user started us from the tool icon,
  191.          * we can't save the game in the same place
  192.          * we started from, so pick up the plname
  193.          * and hope for the best.
  194.          */
  195.     if(FromTool){
  196.     set_savefile_name();
  197.     }
  198. }
  199.  
  200. /* Simulate the command line (-s is already done, although this is
  201.  * not exactly the way it should be). Note that we do not handle the
  202.  * entire range of standard NetHack flags.
  203.  */
  204. void ami_wbench_args(){
  205.     char *p=argline;
  206.  
  207.     if(!FromWBench) return;
  208.  
  209.     while(*p){
  210.     switch(*p++){
  211.     case ' ':
  212.     case '-':   break;
  213. #ifdef NEWS
  214.     case 'n':   flags.news = FALSE;
  215. #endif
  216. #if defined(WIZARD) || defined(EXPLORE_MODE)
  217. # ifndef EXPLORE_MODE
  218.     case 'X':
  219. # endif
  220.     case 'D':
  221. # ifdef WIZARD
  222. #  ifdef KR1ED
  223.         if(!strcmp(plname,WIZARD_NAME))
  224. #  else
  225.         if(!strcmp(plname,WIZARD))
  226. #  endif
  227.         {
  228.         wizard=TRUE;break;
  229.         }
  230.         /* else fall through */
  231. # endif
  232. # ifdef EXPLORE_MODE
  233.     case 'X':   discover=TRUE;
  234. # endif
  235.         break;
  236. #endif
  237.     case 'L':   /* interlaced screen */
  238.         bigscreen = 1;
  239.         break;
  240.     case 'l':   /* No interlaced screen */
  241.         bigscreen = -1;
  242.         break;
  243.     case 'u':
  244.         {
  245.         char *c,*dest;
  246.         while(*p && isascii(*p) && isspace(*p))p++;
  247.         c=p;
  248.         dest=plname;
  249.         for(;*p && isascii(*p) && !isspace(*p);){
  250.         if(dest-plname>=(sizeof(plname)-1))break;
  251.         *dest++=*p++;
  252.         }
  253.         *dest='\0';
  254.         if(c==dest)
  255.         raw_print("Player name expected after -u");
  256.         }
  257.         strcpy(savefname,plname);
  258.         set_savefile_name();
  259.         break;
  260.     default:
  261.         p--;
  262.         if(index(classes,toupper(*p))){
  263.         char *t=pl_character;
  264.         int cnt=sizeof(pl_character)-1;
  265.         while(cnt && *p && !isspace(*p))*t++=*p++,cnt--;
  266.         *t=0;
  267.         break;
  268.         }
  269.         raw_printf("Unknown switch: %s\n",p);
  270.         /* FALL THROUGH */
  271.     case '?':
  272.         {
  273.         char buf[77];
  274.  
  275.         raw_printf("Usage: %s -s [-[%s]] [maxrank] [name]...",
  276.           hname, classes);
  277.         raw_print("       or");
  278.         sprintf(buf,"       %s [-u name] [-[%s]]", hname, classes);
  279. #if defined(WIZARD) || defined(EXPLORE_MODE)
  280.         strcat(buf," [-[DX]]");
  281. #endif
  282. #ifdef NEWS
  283.         strcat(buf," [-n]");
  284. #endif
  285. #ifdef MFLOPPY
  286. # ifndef AMIGA
  287.         strcat(" [-r]");
  288. # endif
  289. #endif
  290.         raw_print(buf);
  291.         exit(0);
  292.         }
  293.     }
  294.     }
  295. }
  296.  
  297.  
  298. /* IF (from workbench) && (currently parsing ToolTypes)
  299.  * THEN print error message and return 0
  300.  * ELSE return 1
  301.  */
  302. ami_wbench_badopt(oopsline)
  303. const char *oopsline;
  304. {
  305.     if(!FromWBench)return 1;
  306.     if(!TTparse)return 1;
  307.  
  308.     raw_printf("Bad Syntax in OPTIONS in ToolTypes: %s.",oopsline);
  309.     return 0;
  310. }
  311.  
  312. /* Construct (if necessary) and fill in icon for given save file */
  313. void ami_wbench_iconwrite(base)
  314. char *base;
  315. {
  316.     BPTR lock;
  317.     char tmp[PATHLEN+5];
  318.     struct DiskObject *dobj;
  319.     char **savtp, *ourtools[ 21 ];
  320. #define CHARACTER   0
  321. #define PENS        1
  322.     char types[ 4 ][ 80 ];  /* Buffer space for tooltypes until written */
  323.     int i, j;
  324.  
  325.     if(!FromWBench)return;
  326.     if(FromCLI)return;
  327.  
  328.     strcpy(tmp,base);
  329.     strcat(tmp,".info");
  330.     if(FromTool){               /* user clicked on main icon */
  331.     (void)CopyFile(DEFAULT_ICON,tmp);
  332.     } else {                /* from project */
  333.     lock=Lock(tmp,ACCESS_READ);
  334.     if(lock==0){    /* maybe our name changed - try to get
  335.          * original icon */
  336.         if(!Rename(origicon,tmp)){
  337.         /* nope, build a new icon */
  338.         lock=Lock(DEFAULT_ICON,ACCESS_READ);
  339.         if(lock==0)return;      /* no icon today */
  340.         UnLock(lock);
  341.         (void)CopyFile(DEFAULT_ICON,tmp);
  342.         }
  343.     } else UnLock(lock);
  344.     }
  345.     KillIcon=FALSE;
  346.  
  347.     dobj=GetDiskObject(base);
  348.  
  349.     /* Save the current pointer */
  350.  
  351.     savtp = (char **)dobj->do_ToolTypes;
  352.  
  353.     /* Copy the old and set new entries for the WorkBench. */
  354.  
  355.     for( i = 0; savtp[i]; ++i )
  356.     {
  357.     /* Ignore any current settings of these values */
  358.  
  359.     if( strncmpi( savtp[ i ], "CHARACTER=", 10 ) == 0 ||
  360.         strncmpi( savtp[ i ], "PENS=", 5 ) == 0 )
  361.     {
  362.         continue;
  363.     }
  364.  
  365.     ourtools[ i ] = savtp[ i ];
  366.     }
  367.  
  368.     /* Fill in the needed values. */
  369.  
  370.     ourtools[ i++ ] = types[ CHARACTER ];
  371.     sprintf( types[ CHARACTER ], "CHARACTER=%c", *pl_character );
  372.  
  373.     ourtools[ i++ ] = types[ PENS ];
  374.     strcpy( types[ PENS ], "PENS=" );
  375.  
  376.     /* Put in the pen colors... */
  377.     for( j = 0; j < (1L << DEPTH); ++j )
  378.     {
  379.     extern unsigned short amii_curmap[];
  380.     sprintf( types[ PENS ] + strlen( types[ PENS ] ),
  381.       "%03x,", amii_curmap[ j ] );
  382.     }
  383.  
  384.     /* Remove trailing comma */
  385.     types[ PENS ][ strlen( types[ PENS ] ) - 1 ] = 0;
  386.  
  387.     ourtools[ i ] = NULL;
  388.  
  389.     /* Set the tools pointer to the temporary copy */
  390.  
  391.     dobj->do_ToolTypes = (void *)ourtools;
  392.     PutDiskObject(base,dobj);
  393.  
  394.     /* Restore the pointer and free the structures */
  395.  
  396.     dobj->do_ToolTypes = (void *)savtp;
  397.     FreeDiskObject(dobj);
  398. }
  399.  
  400. /* How much disk space will we need for the icon? */
  401. int ami_wbench_iconsize(base)
  402. char *base;
  403. {
  404.     struct FileInfoBlock *fib;
  405.     BPTR lock;
  406.     int rv;
  407.     char tmp[PATHLEN+5];
  408.  
  409.     if(!FromWBench)return(0);
  410.     if(FromCLI)return(0);
  411.  
  412.     strcpy(tmp,base);
  413.     strcat(tmp,".info");
  414.     lock=Lock(tmp,ACCESS_READ);
  415.     if(lock==0){    /* check the default */
  416.     lock=Lock(DEFAULT_ICON,ACCESS_READ);
  417.     if(lock==0)return(0);
  418.     }
  419.     fib = (struct FileInfoBlock *)AllocMem(ALLOC_SIZE, MEMF_CLEAR);
  420.     if(!Examine(lock,fib)){
  421.     UnLock(lock);
  422.     FreeMem(fib, ALLOC_SIZE);
  423.     return(0);          /* if no icon, there never will be one */
  424.     }
  425.     rv=fib->fib_Size+strlen(plname);    /* guessing */
  426.     UnLock(lock);
  427.     FreeMem(fib, ALLOC_SIZE);
  428.     return(rv);
  429. }
  430.  
  431. /* Delete the icon associated with the given file (NOT the file itself! */
  432. /* (Don't worry if the icon doesn't exist */
  433. void ami_wbench_unlink(base)
  434. char *base;
  435. {
  436.     if(!FromWBench)return;
  437.     if(FromCLI)return;
  438.  
  439.     strcpy(iconname,base);
  440.     strcat(iconname,".info");
  441.     KillIcon=TRUE;          /* don't do it now - this way the user
  442.                  * gets back whatever picture we had
  443.                  * when we started if the game is
  444.                  * saved again           */
  445. }
  446.  
  447. static int preserved=0;        /* wizard mode && saved save file */
  448.  
  449. preserve_icon(){
  450.     preserved=1;
  451. }
  452. clear_icon(){
  453.     if(!FromWBench)return;
  454.     if(FromCLI)return;
  455.     if(preserved)return;
  456.     if(!KillIcon)return;
  457.  
  458.     DeleteFile(iconname);
  459. }
  460.  
  461. /* Check for a saved game.
  462. IF not a saved game -> -1
  463. IF can't open SAVEF -> -1
  464. ELSE -> fd for reading SAVEF */
  465. int ami_wbench_getsave(mode)
  466. int mode;
  467. {
  468.     BPTR lock;
  469.     struct FileInfoBlock *fib;
  470.  
  471.     if(!FromWBench)return(open(SAVEF,mode));
  472.         /* if the file will be created anyway, skip the
  473.          * checks and just do it            */
  474.     if(mode & O_CREAT)return(open(SAVEF,mode));
  475.     if(FromTool)return(-1);    /* otherwise, by definition, there
  476.                  * isn't a save file (even if a
  477.                  * file of the right name exists) */
  478.     if(savefname[0])
  479.     strncpy(plname,savefname,PL_NSIZ-1); /* restore poly'd name */
  480.     lock=Lock(SAVEF,ACCESS_READ);
  481.     fib = (struct FileInfoBlock *)AllocMem(ALLOC_SIZE, MEMF_CLEAR);
  482.     if(lock && Examine(lock,fib)){
  483.     if(fib->fib_Size>100){  /* random number << save file size */
  484.         UnLock(lock);
  485.         FreeMem(fib,ALLOC_SIZE);
  486.         return(open(SAVEF,mode));
  487.     } else {
  488.         /* this is a dummy file we need because
  489.          * workbench won't duplicate an icon with no
  490.          * "real" data attached - try to get rid of it.
  491.          */
  492.         UnLock(lock);
  493.         unlink(SAVEF);
  494.         FreeMem(fib,ALLOC_SIZE);
  495.         return(-1);
  496.     }
  497.     }
  498.     FreeMem(fib,ALLOC_SIZE);
  499.     return(-1);     /* give up */
  500. }
  501.