home *** CD-ROM | disk | FTP | other *** search
- /* SCCS Id: @(#)amiwbench.c 3.1 93/01/08
- /* Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1990, 1992, 1993 */
- /* NetHack may be freely redistributed. See license for details. */
-
- /* Amiga Workbench interface */
-
- #include "hack.h"
-
- /* Have to #undef CLOSE, because it's used in display.h and intuition.h */
- #undef CLOSE
-
- #ifdef __SASC
- # undef COUNT
- # include <proto/exec.h>
- # include <proto/dos.h>
- # include <proto/icon.h>
- #endif
-
- #include <workbench/startup.h>
- #include <workbench/workbench.h>
- #include <exec/memory.h>
- #include <ctype.h>
-
- #ifdef __SASC
- # include <string.h>
- # undef strlen /* grrr */
- #endif
-
- #define ALLOC_SIZE ((long)sizeof(struct FileInfoBlock))
-
- #ifdef AZTEC_C
- # include <functions.h>
- extern struct Library *IconBase;
- #endif
-
- extern int FDECL(parse_config_line, (FILE *, char *, char *, char *));
-
- int ami_argc; /* global argc */
- char **ami_argv; /* global argv */
- boolean FromWBench=0; /* how did we get started? */
- boolean FromCLI=0; /* via frontend and INTERNALCLI */
- static BOOL FromTool=0; /* or from Project (ergo nothing to restore) */
- static char argline[80]; /* fake command line from ToolTypes */
- static BOOL TTparse=0; /* parsing tooltypes? */
- static BOOL KillIcon=FALSE; /* delayed expunge of user's icon */
- static char iconname[PATHLEN+5];
- static char origicon[PATHLEN+5];
- static char savefname[PL_NSIZ]; /* name from name of save file */
-
- extern int bigscreen;
- extern const char *classes; /* liberated from pcmain */
- extern char PATH[];
-
- /* Called after NetHack.cnf (and maybe NETHACKOPTIONS) are read.
- * If this is a request to show the score file, do it here and quit.
- */
- void ami_wbench_init()
- {
- struct WBStartup *wbs=(struct WBStartup *)ami_argv;
- struct WBArg *wa;
- int ia; /* arg of active icon */
- int x,doscore=0;
- char *p,*lp;
- BPTR olddir; /* starting directory */
- struct DiskObject *dobj;
- char *scorearg, *t;
- char tmp_levels[PATHLEN];
-
- FromWBench=(ami_argc==0);
- if(!FromWBench)return; /* nothing if from CLI */
-
- /*
- * "NULL" out arrays
- */
- tmp_levels[0] = '\0';
-
- IconBase=OpenLibrary("icon.library",33L);
- if(!IconBase)error("icon.library missing!");
-
- wa=wbs->sm_ArgList;
- if(wbs->sm_NumArgs>2)error("You can only play one game at a time!");
- ia=wbs->sm_NumArgs-1;
-
- if(strcmp("NewGame",wa[ia].wa_Name)){
- strcpy(savefname,wa[ia].wa_Name);
- strcpy(plname,wa[ia].wa_Name);
- }
-
- if( ( t = strrchr( plname, '.' ) ) && strcmp( t, ".sav" ) == 0 )
- *t = 0;
-
- olddir=CurrentDir(wa[ia].wa_Lock); /* where the icon is */
-
- dobj=GetDiskObject(wa[ia].wa_Name);
- (void)CurrentDir(olddir); /* and back */
- if(!dobj){
- error("Sorry, I can't find your icon!");
- }
-
- FromTool=(dobj->do_Type==WBTOOL)?1:
- (dobj->do_Type==WBPROJECT)?0:
- (error("Sorry, I don't recognize this icon type!"),1);
-
- if(index(savefname,'.') && !strncmp(index(savefname,'.'),".sav",4)){
- *index(savefname,'.')='\0';
- } else {
- savefname[0]='\0'; /* don't override if not save file */
- FromTool = 1;
- }
-
- argline[0]='\0';
- if( p = FindToolType( dobj->do_ToolTypes, "SCREEN" ) )
- {
- extern int bigscreen;
- if( MatchToolValue( p, "NOLACE" ) )
- bigscreen = -1;
- else if( MatchToolValue( p, "LACE" ) )
- bigscreen = 1;
- }
- if(dobj->do_ToolTypes)for(x=0;p=dobj->do_ToolTypes[x];x++){
- lp=index(p,'=');
- if( !lp++ || strncmp(p, "SCORE", 5 ) == 0 ){
- if((strncmp(p,"SCORES",6)==0) || (strncmp(p,"SCORE",5)==0)){
- if( !lp ) lp = "";
- doscore=1;
- scorearg=(char *)alloc(strlen(lp)+1);
- strcpy(scorearg,lp);
- } else {
- TTparse=TRUE;
- parseoptions(p,(boolean)TRUE,(boolean)FALSE);
- TTparse=FALSE;
- }
- } else {
- TTparse=TRUE;
- /* new things */
- if((strncmp(p,"CMDLINE",7)==0)||
- (strncmp(p,"COMMANDLINE",11)==0)||
- (strncmp(p,"INTERNALCLI",11)==0)){
- strncpy(argline,lp,79);
- if(*p=='I'){
- FromTool=0; /* ugly hack bugfix */
- FromCLI=1; /* frontend ICLI only */
- }
- }
- else if( strncmp( p, "SCREEN",6 ) )
- {
- if (!parse_config_line((FILE *)0, p, 0, tmp_levels)){
- raw_printf("Bad ToolTypes line: '%s'\n",p);
- getreturn("to continue");
- }
- }
- TTparse=FALSE;
- }
- }
- /* cleanup - from files.c, except we only change things
- * that are explicitly changed, since we already
- * did this once to get the defaults (in amidos.c) */
- if(plname[0]){
- plnamesuffix(); /* from files.c */
- set_savefile_name();
- }
- if(tmp_levels[0])strcpy(permbones,tmp_levels);
- if(tmp_levels[0]){
- strcpy(levels,tmp_levels);
- strcpy(bones,levels);
- }
- FreeDiskObject(dobj); /* we'll get it again later if we need it */
-
- if(doscore){
- long ac;
- char *p;
- char **av=calloc(1,50*sizeof(char *));
- #ifdef CHDIR
- chdirx(hackdir,0);
- #endif
- av[0]="NetHack"; /* why not? */
- av[1]="-s"; /* why not? */
- for(ac=2,p=scorearg;*p;ac++){
- av[ac]=p;
- while(*p && !isspace(*p))p++;
- if(!*p)break;
- *p++='\0';
- while(*p && isspace(*p))p++;
- }
- prscore(ac+1,av);
- free( av );
- exit(0); /* overloaded */
- }
-
- /* if the user started us from the tool icon,
- * we can't save the game in the same place
- * we started from, so pick up the plname
- * and hope for the best.
- */
- if(FromTool){
- set_savefile_name();
- }
- }
-
- /* Simulate the command line (-s is already done, although this is
- * not exactly the way it should be). Note that we do not handle the
- * entire range of standard NetHack flags.
- */
- void ami_wbench_args(){
- char *p=argline;
-
- if(!FromWBench) return;
-
- while(*p){
- switch(*p++){
- case ' ':
- case '-': break;
- #ifdef NEWS
- case 'n': flags.news = FALSE;
- #endif
- #if defined(WIZARD) || defined(EXPLORE_MODE)
- # ifndef EXPLORE_MODE
- case 'X':
- # endif
- case 'D':
- # ifdef WIZARD
- # ifdef KR1ED
- if(!strcmp(plname,WIZARD_NAME))
- # else
- if(!strcmp(plname,WIZARD))
- # endif
- {
- wizard=TRUE;break;
- }
- /* else fall through */
- # endif
- # ifdef EXPLORE_MODE
- case 'X': discover=TRUE;
- # endif
- break;
- #endif
- case 'L': /* interlaced screen */
- bigscreen = 1;
- break;
- case 'l': /* No interlaced screen */
- bigscreen = -1;
- break;
- case 'u':
- {
- char *c,*dest;
- while(*p && isascii(*p) && isspace(*p))p++;
- c=p;
- dest=plname;
- for(;*p && isascii(*p) && !isspace(*p);){
- if(dest-plname>=(sizeof(plname)-1))break;
- *dest++=*p++;
- }
- *dest='\0';
- if(c==dest)
- raw_print("Player name expected after -u");
- }
- strcpy(savefname,plname);
- set_savefile_name();
- break;
- default:
- p--;
- if(index(classes,toupper(*p))){
- char *t=pl_character;
- int cnt=sizeof(pl_character)-1;
- while(cnt && *p && !isspace(*p))*t++=*p++,cnt--;
- *t=0;
- break;
- }
- raw_printf("Unknown switch: %s\n",p);
- /* FALL THROUGH */
- case '?':
- {
- char buf[77];
-
- raw_printf("Usage: %s -s [-[%s]] [maxrank] [name]...",
- hname, classes);
- raw_print(" or");
- sprintf(buf," %s [-u name] [-[%s]]", hname, classes);
- #if defined(WIZARD) || defined(EXPLORE_MODE)
- strcat(buf," [-[DX]]");
- #endif
- #ifdef NEWS
- strcat(buf," [-n]");
- #endif
- #ifdef MFLOPPY
- # ifndef AMIGA
- strcat(" [-r]");
- # endif
- #endif
- raw_print(buf);
- exit(0);
- }
- }
- }
- }
-
-
- /* IF (from workbench) && (currently parsing ToolTypes)
- * THEN print error message and return 0
- * ELSE return 1
- */
- ami_wbench_badopt(oopsline)
- const char *oopsline;
- {
- if(!FromWBench)return 1;
- if(!TTparse)return 1;
-
- raw_printf("Bad Syntax in OPTIONS in ToolTypes: %s.",oopsline);
- return 0;
- }
-
- /* Construct (if necessary) and fill in icon for given save file */
- void ami_wbench_iconwrite(base)
- char *base;
- {
- BPTR lock;
- char tmp[PATHLEN+5];
- struct DiskObject *dobj;
- char **savtp, *ourtools[ 21 ];
- #define CHARACTER 0
- #define PENS 1
- char types[ 4 ][ 80 ]; /* Buffer space for tooltypes until written */
- int i, j;
-
- if(!FromWBench)return;
- if(FromCLI)return;
-
- strcpy(tmp,base);
- strcat(tmp,".info");
- if(FromTool){ /* user clicked on main icon */
- (void)CopyFile(DEFAULT_ICON,tmp);
- } else { /* from project */
- lock=Lock(tmp,ACCESS_READ);
- if(lock==0){ /* maybe our name changed - try to get
- * original icon */
- if(!Rename(origicon,tmp)){
- /* nope, build a new icon */
- lock=Lock(DEFAULT_ICON,ACCESS_READ);
- if(lock==0)return; /* no icon today */
- UnLock(lock);
- (void)CopyFile(DEFAULT_ICON,tmp);
- }
- } else UnLock(lock);
- }
- KillIcon=FALSE;
-
- dobj=GetDiskObject(base);
-
- /* Save the current pointer */
-
- savtp = (char **)dobj->do_ToolTypes;
-
- /* Copy the old and set new entries for the WorkBench. */
-
- for( i = 0; savtp[i]; ++i )
- {
- /* Ignore any current settings of these values */
-
- if( strncmpi( savtp[ i ], "CHARACTER=", 10 ) == 0 ||
- strncmpi( savtp[ i ], "PENS=", 5 ) == 0 )
- {
- continue;
- }
-
- ourtools[ i ] = savtp[ i ];
- }
-
- /* Fill in the needed values. */
-
- ourtools[ i++ ] = types[ CHARACTER ];
- sprintf( types[ CHARACTER ], "CHARACTER=%c", *pl_character );
-
- ourtools[ i++ ] = types[ PENS ];
- strcpy( types[ PENS ], "PENS=" );
-
- /* Put in the pen colors... */
- for( j = 0; j < (1L << DEPTH); ++j )
- {
- extern unsigned short amii_curmap[];
- sprintf( types[ PENS ] + strlen( types[ PENS ] ),
- "%03x,", amii_curmap[ j ] );
- }
-
- /* Remove trailing comma */
- types[ PENS ][ strlen( types[ PENS ] ) - 1 ] = 0;
-
- ourtools[ i ] = NULL;
-
- /* Set the tools pointer to the temporary copy */
-
- dobj->do_ToolTypes = (void *)ourtools;
- PutDiskObject(base,dobj);
-
- /* Restore the pointer and free the structures */
-
- dobj->do_ToolTypes = (void *)savtp;
- FreeDiskObject(dobj);
- }
-
- /* How much disk space will we need for the icon? */
- int ami_wbench_iconsize(base)
- char *base;
- {
- struct FileInfoBlock *fib;
- BPTR lock;
- int rv;
- char tmp[PATHLEN+5];
-
- if(!FromWBench)return(0);
- if(FromCLI)return(0);
-
- strcpy(tmp,base);
- strcat(tmp,".info");
- lock=Lock(tmp,ACCESS_READ);
- if(lock==0){ /* check the default */
- lock=Lock(DEFAULT_ICON,ACCESS_READ);
- if(lock==0)return(0);
- }
- fib = (struct FileInfoBlock *)AllocMem(ALLOC_SIZE, MEMF_CLEAR);
- if(!Examine(lock,fib)){
- UnLock(lock);
- FreeMem(fib, ALLOC_SIZE);
- return(0); /* if no icon, there never will be one */
- }
- rv=fib->fib_Size+strlen(plname); /* guessing */
- UnLock(lock);
- FreeMem(fib, ALLOC_SIZE);
- return(rv);
- }
-
- /* Delete the icon associated with the given file (NOT the file itself! */
- /* (Don't worry if the icon doesn't exist */
- void ami_wbench_unlink(base)
- char *base;
- {
- if(!FromWBench)return;
- if(FromCLI)return;
-
- strcpy(iconname,base);
- strcat(iconname,".info");
- KillIcon=TRUE; /* don't do it now - this way the user
- * gets back whatever picture we had
- * when we started if the game is
- * saved again */
- }
-
- static int preserved=0; /* wizard mode && saved save file */
-
- preserve_icon(){
- preserved=1;
- }
- clear_icon(){
- if(!FromWBench)return;
- if(FromCLI)return;
- if(preserved)return;
- if(!KillIcon)return;
-
- DeleteFile(iconname);
- }
-
- /* Check for a saved game.
- IF not a saved game -> -1
- IF can't open SAVEF -> -1
- ELSE -> fd for reading SAVEF */
- int ami_wbench_getsave(mode)
- int mode;
- {
- BPTR lock;
- struct FileInfoBlock *fib;
-
- if(!FromWBench)return(open(SAVEF,mode));
- /* if the file will be created anyway, skip the
- * checks and just do it */
- if(mode & O_CREAT)return(open(SAVEF,mode));
- if(FromTool)return(-1); /* otherwise, by definition, there
- * isn't a save file (even if a
- * file of the right name exists) */
- if(savefname[0])
- strncpy(plname,savefname,PL_NSIZ-1); /* restore poly'd name */
- lock=Lock(SAVEF,ACCESS_READ);
- fib = (struct FileInfoBlock *)AllocMem(ALLOC_SIZE, MEMF_CLEAR);
- if(lock && Examine(lock,fib)){
- if(fib->fib_Size>100){ /* random number << save file size */
- UnLock(lock);
- FreeMem(fib,ALLOC_SIZE);
- return(open(SAVEF,mode));
- } else {
- /* this is a dummy file we need because
- * workbench won't duplicate an icon with no
- * "real" data attached - try to get rid of it.
- */
- UnLock(lock);
- unlink(SAVEF);
- FreeMem(fib,ALLOC_SIZE);
- return(-1);
- }
- }
- FreeMem(fib,ALLOC_SIZE);
- return(-1); /* give up */
- }
-