ftp.nice.ch/pub/next/unix/games/nethack.3.0.N.bs.tar.gz#/PubDomain/Games/HACK/amiga/amiwbench.c

This is amiwbench.c in view mode; [Download] [Up]

/*    SCCS Id: @(#)amiwbench.c - Amiga Workbench interface  3.0   */
/* Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1990	  */
/* NetHack may be freely redistributed.  See license for details. */

#include "hack.h"

#undef TRUE
#undef FALSE
#undef COUNT
#undef NULL

#ifdef LATTICE
#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 LATTICE
#include <string.h>
#undef strlen			/* grrr */
#endif

#define ALLOC_SIZE		((long)sizeof(struct FileInfoBlock))

#ifdef AZTEC_C
/*
 * Change when manx becomes ANSI complient
 */
BPTR FDECL(CurrentDir,(BPTR));
BPTR FDECL(ParentDir, (BPTR));
BPTR FDECL(Lock, (char *, long));
void *FDECL(AllocMem, (long, long));
void FDECL(FreeMem, (void *, long));
unsigned short FDECL(Examine, (BPTR, struct FileInfoBlock *));
struct Library *FDECL(OpenLibrary,(char *, long));
struct DiskObject *FDECL(GetDiskObject, (char *));

extern struct Library *IconBase;
#endif

#ifdef AMIGA_WBENCH
static void FDECL(ami_wb_findme,(char *,char *,struct WBArg *));
static int FDECL(buildPath,(LONG,struct FileInfoBlock *,char *));
static void FDECL(insert,(char *,char *));

BOOL FromWBench=0;		/* if FALSE, this file is a big NOP */
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 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(argc,argv)
int argc;
char *argv[];
{
	struct WBStartup *wbs=(struct WBStartup *)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;
	char	tmp_ramdisk[PATHLEN];
	char	tmp_levels[PATHLEN];

	FromWBench=(argc==0);
	if(!FromWBench)return;			/* nothing if from CLI */

	/*
	 * "NULL" out arrays
	 */
	tmp_ramdisk[0] = '\0';
	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;
	strcpy(savefname,wa[ia].wa_Name);
	if(!strncmp(index(savefname,'.'),".sav",4)){
		*index(savefname,'.')='\0';
	} else {
		savefname[0]='\0';	/* don't override if not save file */
	}

	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);

	ami_wb_findme(SAVEF,SAVEP,&wa[ia]);
	strcpy(origicon,SAVEF);
	strcat(origicon,".info");

	argline[0]='\0';
	for(x=0;p=dobj->do_ToolTypes[x];x++){
		lp=index(p,'=');
		if(!lp++){
			if((strncmp(p,"SCORES",6)==0) ||
			   (strncmp(p,"SCORE",5)==0)){
				doscore=1;
				scorearg=malloc(strlen(p)+1);
				strcpy(scorearg,p);
			} else {
				TTparse=TRUE;
				parseoptions(p,(boolean)TRUE);
				TTparse=FALSE;
			}
		} else {
			while(*lp && isspace(*lp))lp++;
				/* vars and lengths below match amidos.c,
				 * but there is no SAVE - you put the
				 * icon where you want it, and GRAPHICS
				 * just doesn't belong		*/
			if(!strncmp(p,"OPTIONS",4)){
				TTparse=TRUE;
				parseoptions(lp,(boolean)TRUE);
				TTparse=FALSE;
			} else
			if(lp[0]=='#'){
				/* for perversity's sake, a comment */
			} else
			if(!strncmp(p,"HACKDIR",4)){
				strncpy(hackdir,lp,PATHLEN);
			} else
			if(!strncmp(p,"RAMDISK",3)){
				strncpy(tmp_ramdisk,lp,PATHLEN);
			} else
			if(!strncmp(p,"LEVELS",4)){
				strncpy(tmp_levels,lp,PATHLEN);
			} else
			if(!strncmp(p,"PATH",4)){
				strncpy(PATH,lp,PATHLEN);
			} else
				/* new things */
			if((strncmp(p,"CMDLINE",7)==0)||
			   (strncmp(p,"COMMANDLINE",11)==0)){
				strncpy(argline,lp,79);
			} else
			{
				msmsg("Bad ToolTypes line: '%s'\n",p);
				getreturn("to continue");
			}
		}
	}
		/* cleanup - from amidos.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 amidos.c */
	if(tmp_levels[0])strcpy(permbones,tmp_levels);
	if(tmp_ramdisk[0]){
		strcpy(levels,tmp_ramdisk);
		strcpy(bones,levels);
		if(strcmp(permbones,levels))
			ramdisk=TRUE;
	} else {
		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? */
		for(ac=1,p=scorearg;*p;ac++){
			av[ac]=p;
			while(*p && !isspace(*p))p++;
			if(!*p)break;
			*p++='\0';
			while(*p && isspace(*p))p++;
			if(ac==1)sprintf(av[ac],"-s");	/* overwrite SCORES */
		}
		prscore(ac+1,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){
		strcat(SAVEF,plname);
		strcat(SAVEP,plname);
	}
}

/* Simulate the command line (-s is already done, although this is
 * not exactly the way it should be). Note that we only handle flags
 * that are not otherwise available in NetHack.cnf		*/
void ami_wbench_args(){
	char *p=argline;
	if(!FromWBench)return;
	if(!argline)return;

	while(*p){
		switch(*p++){
		case '-':	break;
#ifdef NEWS
		case 'n':	flags.nonews = TRUE;
#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
#ifdef DGK
		case 'r':	/* no ram disk */
			ramdisk=FALSE;
			break;
#endif
		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;
			} else {
				Printf("Unknown switch: %s\n",p);
				return;
			}
		}
	}
}


/* IF (from workbench) && (currently parsing ToolTypes)
 * THEN print error message and return 0
 * ELSE return 1
 */
ami_wbench_badopt(oopsline)
char *oopsline;
{
	if(!FromWBench)return 1;
	if(!TTparse)return 1;
	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];

	if(!FromWBench)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);
	anything we need to change?  I don't think so.
	PutDiskObject(base,dobj);
	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);
	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;

	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			 */
/*	unlink(tmp); */
}

/* 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 */
}

#ifdef notdef
/* cleanup */
void ami_wbench_cleanup(){
	if(!FromWBench)return;
	if(KillIcon){
		unlink(iconname);
	} else {
		if(!FromTool){	/* game started and ended in one session */
			char buf[PATHLEN+5];
			strcpy(buf,SAVEF);
			strcat(buf,".info");
			unlink(buf);
		}
	}
}
#endif

/* get printable version of where we came from */
static void ami_wb_findme(bufp,dirp,wa)
	char *bufp,*dirp;
	struct WBArg *wa;
	{
	BPTR dir;
	struct FileInfoBlock *fib;
	char *p;
	int len;

	dir=wa->wa_Lock;

	fib = (struct FileInfoBlock *)AllocMem(ALLOC_SIZE,MEMF_CLEAR);
	buildPath(dir,fib,dirp);
	strcat(dirp,"/");
	strcpy(bufp,dirp);
	if(FromTool){
		/* do nothing - filename will be added later */
	} else {
		strcat(bufp,wa->wa_Name);
	};
	/* I know this looks redundent, but its not since we may add
	 * a slash after returning from buildPath
	 */
	p=index(bufp,':');
	if(!p){
		p=index(bufp,'/');
		if(p)*p=':';
	}
	p=index(dirp,':');
	if(!p){
		p=index(dirp,'/');
		if(p)*p=':';
	}
	/* We found the icon - but we need the main file. */
	len=strlen(bufp);
	if(len<5)return;			/* who knows? */
	if(strcmp(".info",&bufp[len-5]))return; /* who knows? */
	bufp[len-5]='\0';
        FreeMem(fib, ALLOC_SIZE);
}

/* Carolyn Scheppner - CATS, AmigaMail II-34 */
static int
buildPath(inlock,fib,buf)
LONG inlock;
struct FileInfoBlock *fib;       	/* ASSUMED LONGWORD BOUNDARY!! */
char *buf;
	{
	int i;
	LONG lock,oldlock;
	BOOL MyOldLock = FALSE;

	buf[0]='\0';
	lock=inlock;

	while(lock){
		if(Examine(lock,fib)){
			if(fib->fib_FileName[0]>' '){
				if(buf[0])insert(buf,"/");
				insert(buf,fib->fib_FileName);
			}
		}
		oldlock=lock;
		lock=ParentDir(lock);
		if(MyOldLock) UnLock(oldlock);
		else MyOldLock=TRUE;
	}
	if(fib->fib_FileName[0]>' '){
		for(i=0;i<(strlen(buf));i++){
			if(buf[i]=='/'){
				buf[i]=':';
				break;
			}
		}
	}
	else insert(buf,"RAM:");
	return((int)strlen(buf));
}
static void
insert(buf,s)
char *buf,*s;
{
	char tmp[256];
	strcpy(tmp,buf);
	strcpy(buf,s);
	strcpy(&buf[strlen(s)],tmp);
}

#if 0 /* CopyFile should be OK */
static void copyicon(from,to)
char *from,*to;
{
	int df,dt;
	char buf[512];
	int len=512;

	df=open(from,O_RDONLY);
	dt=open(to,O_WRONLY,0);
	while(len=512){
		len=read(df,buf,len);
		write(dt,buf,len);
	}
	close(df);
	close(dt);
}
#endif
#endif /* AMIGA_WBENCH */

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.