Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

v17i103: nethack31 - display oriented dungeons & dragons (Ver. 3.1), Patch2bb/33

1 view
Skip to first unread message

Bill Randle

unread,
Jun 10, 1993, 8:18:31 PM6/10/93
to
Submitted-by: izc...@linc.cis.upenn.edu (Izchak Miller)
Posting-number: Volume 17, Issue 103
Archive-name: nethack31/Patch2bb
Patch-To: nethack31: Volume 16, Issue 1-116
Environment: Amiga, Atari, Mac, MS-DOS, Windows-NT, OS2, Unix, VMS, X11

#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 28 (of 33)."
# Contents: sys/amiga/splitter/splitter.c sys/amiga/winami.c
# sys/share/pcsys.c
# Wrapped by billr@saab on Thu Jun 10 16:55:07 1993
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'sys/amiga/splitter/splitter.c' -a "${1}" != "-c" ; then
echo shar: Renaming existing file \"'sys/amiga/splitter/splitter.c'\" to \"'sys/amiga/splitter/splitter.c.orig'\"
mv -f 'sys/amiga/splitter/splitter.c' 'sys/amiga/splitter/splitter.c.orig'
fi
echo shar: Extracting \"'sys/amiga/splitter/splitter.c'\" \(15390 characters\)
sed "s/^X//" >'sys/amiga/splitter/splitter.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)splitter.c 3.1 93/01/08
X/* Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1992, 1993 */
X/* NetHack may be freely redistributed. See license for details. */
X
X#define SOUT /* split output files */
X#define SPLITSIZE (800 * 1024) /* somewhat < one floppy */
X
X#include <stdio.h>
X#include <stdlib.h>
X#include <string.h>
X#include <fcntl.h>
X
X#include <proto/exec.h>
X#include <exec/types.h>
X#include <exec/nodes.h>
X#include <exec/lists.h>
X
X#include "split.h"
X#include "amiout.h"
X#include "arg.h"
X
Xint main(int,char **);
X
Xchar *code_proto="%n.c%C";
Xchar *data_proto="%n.d%D";
Xchar *dir_proto="%n.dir";
X
Xchar trace[MAXTRACEVAR]; /* debugging info */
Xchar *basename;
Xint datacount; /* for ssubst - should be replaced */
Xint codecount;
Xint data_file_count=0; /* actual maxima */
Xint code_file_count=0;
Xstruct hheader hheader;
Xstruct shunk (*hlist)[];
Xchar buf[80];
Xint wsf_count;
X
Xmain(argc,argv)
X int argc;
X char **argv;
X{
X int cur_arg;
X
X arg_init("C:D:d:t:T",argc,argv);
X while((cur_arg=arg_next())!=ARG_DONE){
X switch(cur_arg){
X case 'C': /* code prototype */
X code_proto=strdup(argarg);break;
X case 'D': /* data prototype */
X data_proto=strdup(argarg);break;
X case 'd': /* directions prototype */
X dir_proto=strdup(argarg);break;
X case 't': /* trace (debug) */
X {
X int dtype=0,dlevel=0; /* rude defaults */
X sscanf(argarg,"%d=%d",&dtype,&dlevel);
X if(dtype<0 || dtype>=MAXTRACEVAR){
X fprintf(stderr,"-t: bad trace num ignored\n");
X }else{
X trace[dtype]=dlevel?dlevel:1;
X }
X break;
X }
X case 'T': /* trace everything */
X {
X int dtype;
X for(dtype=0;dtype<MAXTRACEVAR;dtype++)trace[dtype]=255;
X }
X break;
X default:
X fprintf(stderr,"Unrecognized option.\n");
X /* FALLTHROUGH */
X case ARG_ERROR:
X panic("Error processing arguments.");
X case ARG_FREE:
X basename=strdup(argarg);
X read_load_file(basename);break;
X }
X }
X renumber();
X out_start(code_proto);
X write_header();
X write_code_file();
X out_stop();
X out_start(data_proto);
X write_data_file();
X out_stop();
X write_dir_file();
X exit(0);
X}
X
Xchar *
Xssubst(buf,pat)
X char *buf;
X const char *pat;
X{
X char *buf1=buf;
X
X while(*pat){
X if(*pat!='%'){
X *buf++=*pat++;
X } else {
X pat++;
X switch(*pat++){
X case '%': *buf++='%';break;
X case 'n': strcpy(buf,basename);buf=eos(buf);break;
X case 'D': sprintf(buf,"%02d",datacount);buf=eos(buf);break;
X case 'C': sprintf(buf,"%02d",codecount);buf=eos(buf);break;
X default: panic("pattern substitution error");
X }
X }
X }
X *buf='\0';
X return buf1;
X}
X
Xvoid
Xpanic(s)
X char *s;
X{
X fprintf(stderr,"\npanic: %s\n",s);
X exit(1);
X}
X
Xchar *
Xeos(s)
X char *s;
X{
X while(*s)s++;
X return s;
X}
X
X/* input routines */
X
X /* macro for reading the next long. If e==EOF_OK, caller MUST check
X * for EOF condition via hreadval or assure it can't occur */
Xstatic int hreadval=0; /* macro internal temporary */
X#define EOF_OK 1
X#define EOF_BAD 0
X#define READLONG(e) \
X ((4!=(hreadval=read(f->fd,&(READLONGx),4))) \
X ?((0==hreadval && (e) \
X ?0 \
X :rderror())) \
X :READLONGx)
Xstatic long READLONGx;
X#define READSHORT(e) \
X ((2!=(hreadval=read(f->fd,&(READSHORTx),2))) \
X ?((0==hreadval && (e) \
X ?0 \
X :rderror())) \
X :READSHORTx)
Xstatic short READSHORTx;
X
X#define LONGLEN(x) (strlen(x)+3 >>2) /* # longs for a string */
X
Xvoid
Xread_load_file(name)
X char *name;
X{
X int t;
X int hc;
X file *f=NewFile(name);
X
X /* read HUNK_HEADER */
X t=READLONG(EOF_BAD);if(t!=HUNK_HEADER)panic("no HUNK_HEADER");
X t=READLONG(EOF_BAD);if(t)while(t--)READLONG(EOF_BAD); /* eat any name */
X hheader.hcount=READLONG(EOF_BAD);
X hheader.first=READLONG(EOF_BAD);
X hheader.last=READLONG(EOF_BAD);
X if(hheader.hcount !=(hheader.last-hheader.first+1))panic("can't count");
X hheader.sizes=calloc(hheader.hcount,sizeof(int*));
X for(t=0;t<hheader.hcount;t++)
X (*hheader.sizes)[t]=READLONG(EOF_BAD);
X
X hlist=calloc(hheader.hcount,sizeof(struct shunk));
X for(hc=0;hc<hheader.hcount;hc++){
X struct shunk *th = &(*hlist)[hc];
X /* read each hunk */
X th->h=ReadHunk(f);
X }
X close(f->fd);
X}
X
X/* write routines */
X#define S_CODE 0
X#define S_DATA 1
X
Xvoid
Xwrite_header(){
X int x;
X int target=0;
X
X owrite_long(HUNK_HEADER);
X owrite_long(0);
X owrite_long(hheader.hcount);
X owrite_long(hheader.first);
X owrite_long(hheader.last);
X
X for(x=0;x<hheader.hcount;x++){
X hunk *hp = (*hlist)[x].h;
X if(hp->hunknum==target){
X owrite_long((*hheader.sizes)[x]);
X target++;
X }
X }
X for(x=0;x<hheader.hcount;x++){
X hunk *hp = (*hlist)[x].h;
X if(hp->hunknum==target){
X owrite_long((*hheader.sizes)[x]);
X target++;
X }
X }
X if(target!=hheader.hcount)panic("lost hunks?");
X}
X
Xvoid
Xwrite_code_file(){
X code_file_count=write_split_file(S_CODE)-1;
X}
X
Xvoid
Xwrite_data_file(){
X data_file_count=write_split_file(S_DATA)-1;
X}
X
Xvoid
Xwrite_dir_file(){
X int x;
X FILE *fp=fopen(ssubst(buf,dir_proto),"w");
X
X fprintf(fp,"# split binary direction file\n");
X fprintf(fp,"# Each line consists of:\n");
X fprintf(fp,"# A single C or D for the type of the file (Code or Data)\n");
X fprintf(fp,"# The full path of the file.\n");
X
X for(x=0;x<=code_file_count;x++){
X codecount=x;
X fprintf(fp,"C%s\n",ssubst(buf,code_proto));
X }
X for(x=0;x<=data_file_count;x++){
X datacount=x;
X fprintf(fp,"D%s\n",ssubst(buf,data_proto));
X }
X fclose(fp);
X}
X
X/* BUGFIX: 9/23/92: see HT() above */
X#define HT(x) ((x) & ~MEM_OBJ_EXTEND)
X
Xint
Xwrite_split_file(fl)
X int fl;
X{
X int hc;
X for(hc=0;hc<hheader.hcount;hc++){
X hunk *hp = (*hlist)[hc].h;
X if(fl==S_CODE && HT(hp->rb->id)==HUNK_CODE){
X wsf_hunk(hp);
X } else if(fl==S_DATA && HT(hp->rb->id)==HUNK_DATA){
X wsf_hunk(hp);
X } else if(fl==S_DATA && HT(hp->rb->id)==HUNK_BSS){
X wsf_hunk(hp);
X }
X }
X return wsf_count;
X}
X
X/* BUGFIX: 9/23/92: see HT() below */
Xvoid
Xwsf_hunk(hp)
X hunk *hp;
X{
X listlist *el;
X
X switch(HT(hp->rb->id)){
X case HUNK_CODE:
X case HUNK_DATA:
X owrite(hp->rb->b,(2+hp->rb->b[1])*sizeof(long));
X break;
X case HUNK_BSS:
X owrite(hp->rb->b,2*sizeof(long));
X break;
X default:panic("wsf_hunk: bad type");
X }
X foreach(el,&(hp->reloc),(listlist*)){
X write_lreloc(hp,el);
X }
X owrite_long(HUNK_END);
X}
X
Xvoid
Xwrite_lreloc(hp,ll)
X hunk *hp;listlist *ll;
X {
X block *bp;
X
X#ifdef EMIT_32s
X int x;
X ULONG *p;
X
X /* can we write the entire block with a HUNK_RELOC32s? */
X foreach(bp,&(ll->list),(block*)){
X if((((*hlist)[bp->b[1]]).h->hunknum)>0xffff)goto no_32s; /* no */
X for(p= &(bp->b[2]), x=bp->b[0];x;x--,p++){
X if(*p>0xffff)goto no_32s; /* no, offset too big */
X }
X }
X /* yes */
X owrite_long(HUNK_RELOC32s);
X foreach(bp,&(ll->list),(block*)){
X owrite_long(bp->b[0]);
X owrite_short(((*hlist)[bp->b[1]]).h->hunknum);
X for(p= &(bp->b[2]), x=bp->b[0];x;x--,p++){
X owrite_short(*p);
X }
X /* force long alignment. Not documented, but makes
X * reading dumps easier */
X if((bp->b[0] & 1) == 0){ /* note hunknum also short */
X owrite_short(0);
X }
X }
X owrite_long(0);
X return;
Xno_32s:
X#endif
X owrite_long(HUNK_RELOC32);
X foreach(bp,&(ll->list),(block*)){
X owrite_long(bp->b[0]);
X owrite_long(((*hlist)[bp->b[1]]).h->hunknum);
X owrite(&(bp->b[2]),bp->b[0]*sizeof(long));
X }
X owrite_long(0);
X}
X
Xvoid
Xrenumber()
X{
X int n;
X n=renumber2(S_CODE,0);
X renumber2(S_DATA,n);
X}
X
X/* BUGFIX 9/23/92: hp->rb->id must be wrapped with a bit stripper to ignore
X * memory type bits still in that longword.
X */
X
Xrenumber2(fl,n)
X int fl;
X int n;
X{
X int hc;
X for(hc=0;hc<hheader.hcount;hc++){
X hunk *hp = (*hlist)[hc].h;
X if(fl==S_CODE && HT(hp->rb->id)==HUNK_CODE){
X hp->hunknum=n++;
X } else if(fl==S_DATA && HT(hp->rb->id)==HUNK_DATA){
X hp->hunknum=n++;
X } else if(fl==S_DATA && HT(hp->rb->id)==HUNK_BSS){
X hp->hunknum=n++;
X }
X }
X return n;
X}
X
X/* output package */
X#ifndef SOUT
X/* NB - this version does NOT cope with multiple output files per type */
Xint ofile;
X
Xvoid
Xout_start(prot)
X char *prot;
X{
X datacount=codecount=0;
X file=open(ssubst(buf,prot),O_WRONLY|O_CREAT|O_TRUNC);
X if(ofile<0)panic("can't open output file");
X}
X
Xvoid
Xout_stop(){
X close(ofile);
X}
X
Xvoid
Xowrite_long(literal)
X long literal;
X{
X long x=literal;
X owrite(&x,sizeof(x));
X}
X
Xvoid
Xowrite_short(literal)
X short literal;
X{
X short x=literal;
X owrite(&x,sizeof(x));
X}
X
Xvoid
Xowrite(where,len)
X void *where;
X long len;
X{
X write(ofile,where,len);
X}
X#else /* SOUT */
Xint ofile=0;
Xint osize;
Xchar *oprot;
Xvoid
Xout_start(prot)
X char *prot;
X{
X datacount=codecount=wsf_count=0;
X oprot=prot;
X new_file();
X}
X
Xvoid
Xout_stop(){
X close(ofile);
X ofile=0;
X}
X
Xvoid
Xowrite_long(literal)
X long literal;
X{
X long x=literal;
X if((osize+sizeof(x))>SPLITSIZE)new_file();
X owrite(&x,sizeof(x));
X osize += sizeof(x);
X}
X
Xvoid
Xowrite_short(literal)
X short literal;
X{
X short x=literal;
X if((osize+sizeof(x))>SPLITSIZE)new_file();
X owrite(&x,sizeof(x));
X osize += sizeof(x);
X}
X
Xvoid
Xowrite(where,len)
X void *where;
X long len;
X{
X if((osize+len)>SPLITSIZE)new_file();
X write(ofile,where,len);
X osize += len;
X}
X
Xvoid
Xnew_file(){
X if(ofile)close(ofile);
X ofile=open(ssubst(buf,oprot),O_WRONLY|O_CREAT|O_TRUNC);
X if(ofile<0)panic("can't open output file");
X wsf_count++,datacount++,codecount++;
X osize=0;
X}
X#endif /* SOUT */
X
Xstruct Node *Head(l)
X struct List *l;
X{
X if(!l)panic("Head(NULL)\n");
X return l->lh_Head->ln_Succ?l->lh_Head:0;
X}
Xstruct Node *Tail(l)
X struct List *l;
X{
X if(!l)panic("Tail(NULL)\n");
X return (l->lh_TailPred==(NODE_P)l)?0:l->lh_TailPred;
X}
Xstruct Node *Next(n)
X struct Node *n;
X{
X if(!n)printf("Warning: Next(NULL)\n");
X return n?(n->ln_Succ->ln_Succ?n->ln_Succ:0):0;
X}
Xstruct Node *Prev(n)
X struct Node *n;
X{
X if(!n)printf("Warning: Prev(NULL)\n");
X return n?(n->ln_Pred->ln_Pred?n->ln_Pred:0):0;
X}
X
Xstruct List *_fortemp; /* scratch for foreach macro */
X
Xvoid
Xdump_after_read(struct List *root){
X file *f;
X foreach(f,root,(file *)){
X punit *p;
X printf("FILE '%s'\n",f->name);
X foreach(p,&(f->punits),(punit *)){
X hunk *h;
X print_text_block("\tPUNIT %.*s\n",p->unit_header);
X if(p->libsize){
X printf("\tlibsize=%08x\n",p->libsize);
X } else {
X /* */
X }
X foreach(h,&(p->hunks),(hunk *)){
X print_text_block("\t\tHUNK %.*s",h->name);
X printf(" @%08x\n",h);
X print_bin_block(h->rb);
X printf("\t\t\tCode Reloc\n");
X printf("\t\t\tData Reloc\n");
X if(h->merge)printf("\t\t\tmerge(%08x)\n",h->merge);
X if(h->hunkstart)printf("\t\t\thunkstart\n");
X if(h->hunkchain)printf("\t\t\thunkchain\n");
X if(h->hunkgone)printf("\t\t\thunkgone\n");
X printf("\t\t\toverlay(%08x) hunknum(%08x) offset(%08x)\n",
X h->overlay,h->hunknum,h->hunkoffset);
X }
X }
X }
X}
X
Xvoid
Xprint_text_block(char *fmt,block *b){
X if(!b){
X printf(fmt,10,"(no block)");
X } else {
X if(b->sw){
X printf(fmt,13,"(swapped out)");
X } else {
X if(!(b->b[1]) || !*(char*)&(b->b[2])){
X printf(fmt,6,"(null)");
X } else {
X printf(fmt,b->b[1]*4,&(b->b[2]));
X }
X }
X }
X}
X
Xvoid
Xprint_bin_block(block *b){
X if(b->sw){
X printf("\t\t\t(swapped out)\n");
X } else {
X printf("\t\t\tid1=%08x id2=%08x len=%08x\n", b->id,b->b[0],b->b[1]);
X }
X}
X
X/*
X * read routines
X */
X
X/*
X * ReadSimpleBlock
X * If the given id is recognized as a simple block (id, length, data),
X * allocate and fill in a block structure. Include the id in the block.
X */
Xblock *ReadSimpleBlock(f,id)
X file *f;
X long id;
X{
X long len;
X long hid;
X block *b;
X
X hid=id & 0x0fffffff;
X if( hid !=HUNK_UNIT && hid != HUNK_NAME && hid != HUNK_CODE &&
X hid != HUNK_DATA && hid != HUNK_BSS && hid != HUNK_DEBUG
X ){
X printf("%08x\n",id);
X panic("ReadSImpleBlock");
X }
X
X len=READLONG(EOF_BAD);
X b=NewBlock();
X b->id=id;
X b->sw=0;
X b->b=NewData((hid==HUNK_BSS)?2:len+2);
X b->b[0]=id;
X b->b[1]=len;
X if(hid != HUNK_BSS)read(f->fd,&(b->b[2]),len*4);
X return(b);
X}
X
X/*
X * TossSimpleBlock
X * Skip past something we don't need.
X */
Xint TossSimpleBlock(f)
X file *f;
X{
X long len=READLONG(EOF_BAD);
X
X if(len)if( lseek(f->fd,len*4,1) == -1)panic("Toss failed\n");
X return(len);
X}
X
X/*
X * ReadHunk
X * Read an entire hunk, building lists of each block type in the given hunk
X * structure. If we are listing, do the listing as we read so we can see
X * where things die if we hit a type code we don't recognize.
X */
Xhunk *ReadHunk(f)
X file *f;
X{
X long id;
X hunk *h=NewHunk();
X
X while(1){
X id=READLONG(EOF_OK);
X switch(id & 0x0fffffff){ /* ignore memory type bits */
X case 0: return 0; /* EOF - not good test */
X case HUNK_RELOC32:
X LIST{printf("Reloc32:\n");}
X ReadReloc(f,id,&h->reloc);break;
X case HUNK_CODE:
X h->rb=ReadSimpleBlock(f,id);
X LIST{printf("Code size %d\n",block_size(h->rb)*4);};
X break;
X case HUNK_DATA:
X h->rb=ReadSimpleBlock(f,id);
X LIST{printf("Data size %d\n",block_size(h->rb)*4);};
X break;
X case HUNK_BSS:
X h->rb=ReadSimpleBlock(f,id);
X LIST{printf("Bss size %d\n",block_size(h->rb)*4);};
X break;
X case HUNK_SYMBOL:
X while(TossSimpleBlock(f))READLONG(EOF_BAD);
X LIST{printf("Symbols skipped\n");};
X break;
X case HUNK_DEBUG:
X (void)TossSimpleBlock(f);
X LIST{printf("Debug hunk skipped\n");};
X break;
X case HUNK_END: LIST{printf("End of hunk\n");};return h;
X case HUNK_BREAK:LIST{printf("End of overlay\n");};break;
X default:
X printf("Lost id=0x%x\n",id);exit(2);
X }
X }
X return 0;
X}
X
X/*
X * ReadReloc
X * Read a relocation block and build a linked list of the sections.
X * If we are listing, do that now.
X */
Xvoid ReadReloc(f,id,ls)
X file *f;
X long id;
X struct List *ls;
X{
X long len;
X block *cur;
X listlist *blist=NewListList();
X
X AddTail(ls,blist);
X blist->id=id;
X len=READLONG(EOF_BAD);
X while(len){
X cur=NewBlock();
X cur->b=NewData(len+2);
X read(f->fd,&(cur->b[1]),len*4+4);
X cur->b[0]=len;
X LIST{printf("\thunk #%d - %d items\n",cur->b[1],len);}
X AddTail(&blist->list,cur);
X len=READLONG(EOF_BAD);
X }
X}
X
Xint rderror(){
X panic("read error\n");
X return 0; /* just to make it quiet - NOTREACHED */
X}
X
Xlong block_size(blk)
X block *blk;
X{
X return(blk->b[1]);
X}
X
X/* Allocation routines - if this was C++ then this code would be buried in the
X * constructors. Doing it this way means we can re-write the allocation later
X * to allocate things we'll need lots of in larger blocks to avoid the time and
X * space penalties of malloc. */
Xfile *NewFile(fname)
X char *fname;
X {
X file *ret=calloc(sizeof(file),1);
X
X NewList(&ret->punits);
X ret->name=strdup(fname);
X ret->fd= open(fname,O_RDONLY);
X return(ret);
X}
X
Xpunit *NewPunit(){
X punit *ret=calloc(sizeof(punit),1);
X NewList(&ret->hunks);
X return(ret);
X}
X
Xhunk *NewHunk(){
X hunk *ret=calloc(sizeof(hunk),1);
X
X NewList(&ret->reloc);
X NewList(&ret->dreloc);
X NewList(&ret->extsym);
X ret->overlay=UNASSIGNED_HUNK;
X return(ret);
X}
X
Xblock *NewBlock(){
X return calloc(sizeof(block),1);
X}
X
Xlistlist *NewListList(){
X listlist *ret=calloc(sizeof(listlist),1);
X
X NewList(&ret->list);
X return(ret);
X}
X
Xlong *NewData(longs)
X long longs;
X {
X return(malloc(longs*4));
X}
END_OF_FILE
if test 15390 -ne `wc -c <'sys/amiga/splitter/splitter.c'`; then
echo shar: \"'sys/amiga/splitter/splitter.c'\" unpacked with wrong size!
fi
# end of 'sys/amiga/splitter/splitter.c'
if test -f 'sys/amiga/winami.c' -a "${1}" != "-c" ; then
echo shar: Renaming existing file \"'sys/amiga/winami.c'\" to \"'sys/amiga/winami.c.orig'\"
mv -f 'sys/amiga/winami.c' 'sys/amiga/winami.c.orig'
fi
echo shar: Extracting \"'sys/amiga/winami.c'\" \(31018 characters\)
sed "s/^X//" >'sys/amiga/winami.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)winami.c 3.1 93/04/02 */
X/* Copyright (c) Gregg Wonderly, Naperville, Illinois, 1991,1992,1993. */
X/* NetHack may be freely redistributed. See license for details. */
X
X#include "amiga:windefs.h"
X#include "amiga:winext.h"
X#include "amiga:winproto.h"
X
X#ifdef AMIGA_INTUITION
X
X#ifdef SHAREDLIB
Xstruct DosLibrary *DOSBase;
X#else
Xstruct amii_DisplayDesc *amiIDisplay; /* the Amiga Intuition descriptor */
X#endif
X
Xint clipping = 0;
Xint clipx=0;
Xint clipy=0;
Xint clipxmax=0;
Xint clipymax=0;
Xint scrollmsg = 1;
Xint alwaysinvent = 0;
X
X#ifndef SHAREDLIB
X
X/* Interface definition, for use by windows.c and winprocs.h to provide
X * the intuition interface for the amiga...
X */
Xstruct window_procs amii_procs =
X{
X "amii",
X amii_init_nhwindows,
X amii_player_selection,
X amii_askname,
X amii_get_nh_event,
X amii_exit_nhwindows,
X amii_suspend_nhwindows,
X amii_resume_nhwindows,
X amii_create_nhwindow,
X amii_clear_nhwindow,
X amii_display_nhwindow,
X amii_destroy_nhwindow,
X amii_curs,
X amii_putstr,
X amii_display_file,
X amii_start_menu,
X amii_add_menu,
X amii_end_menu,
X amii_select_menu,
X amii_update_inventory,
X amii_mark_synch,
X amii_wait_synch,
X#ifdef CLIPPING
X amii_cliparound,
X#endif
X amii_print_glyph,
X amii_raw_print,
X amii_raw_print_bold,
X amii_nhgetch,
X amii_nh_poskey,
X amii_bell,
X amii_doprev_message,
X amii_yn_function,
X amii_getlin,
X#ifdef COM_COMPL
X amii_get_ext_cmd,
X#endif /* COM_COMPL */
X amii_number_pad,
X amii_delay_output,
X#ifdef CHANGE_COLOR /* only a Mac option currently */
X amii_change_color,
X amii_get_color_string,
X#endif
X /* other defs that really should go away (they're tty specific) */
X amii_delay_output,
X amii_delay_output,
X amii_outrip,
X};
X
X/* The view window layout uses the same function names so we can use
X * a shared library to allow the executable to be smaller.
X */
Xstruct window_procs amiv_procs =
X{
X "amiv",
X amii_init_nhwindows,
X amii_player_selection,
X amii_askname,
X amii_get_nh_event,
X amii_exit_nhwindows,
X amii_suspend_nhwindows,
X amii_resume_nhwindows,
X amii_create_nhwindow,
X amii_clear_nhwindow,
X amii_display_nhwindow,
X amii_destroy_nhwindow,
X amii_curs,
X amii_putstr,
X amii_display_file,
X amii_start_menu,
X amii_add_menu,
X amii_end_menu,
X amii_select_menu,
X amii_update_inventory,
X amii_mark_synch,
X amii_wait_synch,
X#ifdef CLIPPING
X amii_cliparound,
X#endif
X amii_print_glyph,
X amii_raw_print,
X amii_raw_print_bold,
X amii_nhgetch,
X amii_nh_poskey,
X amii_bell,
X amii_doprev_message,
X amii_yn_function,
X amii_getlin,
X#ifdef COM_COMPL
X amii_get_ext_cmd,
X#endif /* COM_COMPL */
X amii_number_pad,
X amii_delay_output,
X#ifdef CHANGE_COLOR /* only a Mac option currently */
X amii_change_color,
X amii_get_color_string,
X#endif
X /* other defs that really should go away (they're tty specific) */
X amii_delay_output,
X amii_delay_output,
X amii_outrip,
X};
X#endif
X
X#ifndef SHAREDLIB
Xunsigned short amii_initmap[ 1L << DEPTH ] =
X{
X 0x0000, /* color #0 */
X 0x0FFF, /* color #1 */
X 0x0830, /* color #2 */
X 0x07ac, /* color #3 */
X 0x0181, /* color #4 */
X 0x0C06, /* color #5 */
X 0x023E, /* color #6 */
X 0x0c00 /* color #7 */
X#ifdef VIEWWINDOW
X 0x0AAA,
X 0x0fff,
X 0x0444,
X 0x0666,
X 0x0888,
X 0x0bbb,
X 0x0ddd,
X 0x0222,
X#endif
X};
X#endif
X
Xstruct Rectangle lastinvent, lastmsg;
X
X#ifdef SHAREDLIB
XWinamiBASE *WinamiBase;
X
Xint
X__UserLibInit( void )
X{
X WinamiBase = (WinamiBASE *)getreg( REG_A6 );
X if ( (DOSBase = (struct DosLibrary *)
X OpenLibrary("dos.library", 0)) == NULL)
X {
X Abort(AG_OpenLib | AO_DOSLib);
X }
X
X if ( (IntuitionBase = (struct IntuitionBase *)
X OpenLibrary("intuition.library", INTUITION_VERSION)) == NULL)
X {
X Abort(AG_OpenLib | AO_Intuition);
X }
X
X if ( (GfxBase = (struct GfxBase *)
X OpenLibrary("graphics.library", GRAPHICS_VERSION)) == NULL)
X {
X Abort(AG_OpenLib | AO_GraphicsLib);
X }
X
X#ifdef VIEWWINDOW
X if ( (LayersBase = (struct Library *)
X OpenLibrary("layers.library", 0)) == NULL)
X {
X Abort(AG_OpenLib | AO_LayersLib);
X }
X#endif
X
X return( 0 );
X}
X
Xvoid
X__UserLibCleanup( void )
X{
X amii_cleanup();
X}
X
Xchar _ProgramName[ 100 ] = "Nethack";
Xlong __curdir;
Xlong _WBenchMsg;
Xint _OSERR;
X#endif
X
X#ifndef TTY_GRAPHICS /* this should be shared better */
Xchar morc; /* the character typed in response to a --more-- prompt */
X#endif
Xchar spaces[ 76 ] =
X" ";
X
X#ifndef SHAREDLIB
Xwinid WIN_BASE = WIN_ERR;
Xwinid amii_rawprwin = WIN_ERR;
X#endif
X
X#ifdef VIEWWINDOW
Xwinid WIN_VIEW = WIN_ERR;
Xwinid WIN_VIEWBOX = WIN_ERR;
X#endif
X
X/* Changed later during window/screen opens... */
Xint txwidth = FONTWIDTH, txheight = FONTHEIGHT, txbaseline = FONTBASELINE;
X
X/* If a 240 or more row screen is in front when we start, this will be
X * set to 1, and the windows will be given borders to allow them to be
X * arranged differently. The Message window may eventually get a scroller...
X */
X#ifndef SHAREDLIB
Xint bigscreen = 0;
X#endif
X#ifdef VIEWWINDOW
Xstruct BitMap amii_vbm;
X#endif
X
X/* This gadget data is replicated for menu/text windows... */
Xstruct PropInfo PropScroll = { AUTOKNOB|FREEVERT,
X 0xffff,0xffff, 0xffff,0xffff, };
Xstruct Image Image1 = { 0,0, 7,102, 0, NULL, 0x0000,0x0000, NULL };
Xstruct Gadget MenuScroll = {
X NULL, -15,10, 15,-19, GRELRIGHT|GRELHEIGHT,
X RELVERIFY|FOLLOWMOUSE|RIGHTBORDER|GADGIMMEDIATE|RELVERIFY,
X PROPGADGET, (APTR)&Image1, NULL, NULL, NULL, (APTR)&PropScroll,
X 1, NULL
X};
X
X/* This gadget is for the message window... */
Xstruct PropInfo MsgPropScroll = { AUTOKNOB|FREEVERT,
X 0xffff,0xffff, 0xffff,0xffff, };
Xstruct Image MsgImage1 = { 0,0, 7,102, 0, NULL, 0x0000,0x0000, NULL };
Xstruct Gadget MsgScroll = {
X NULL, -14,10, 13,-19, GRELRIGHT|GRELHEIGHT,
X RELVERIFY|FOLLOWMOUSE|RIGHTBORDER|GADGIMMEDIATE|RELVERIFY,
X PROPGADGET, (APTR)&MsgImage1, NULL, NULL, NULL, (APTR)&MsgPropScroll,
X 1, NULL
X};
X
Xint wincnt=0; /* # of nh windows opened */
X
X/* We advertise a public screen to allow some people to do other things
X * while they are playing... like compiling...
X */
X
X#ifdef INTUI_NEW_LOOK
Xstruct TagItem tags[] =
X{
X { WA_PubScreenName, (ULONG)"NetHack", },
X { TAG_DONE, 0, },
X};
X#endif
X
X/*
X * The default dimensions and status values for each window type. The
X * data here is generally changed in create_nhwindow(), so beware that
X * what you see here may not be exactly what you get.
X */
Xstruct win_setup new_wins[] =
X{
X
X /* First entry not used, types are based at 1 */
X {{0}},
X
X /* NHW_MESSAGE */
X {{0,1,640,11,0xff,0xff,
X NEWSIZE|GADGETUP|GADGETDOWN|MOUSEMOVE|MOUSEBUTTONS|RAWKEY,
X BORDERLESS|ACTIVATE|SMART_REFRESH
X#ifdef INTUI_NEW_LOOK
X |WFLG_NW_EXTENDED
X#endif
X ,
X NULL,NULL,(UBYTE*)"Messages",NULL,NULL,640,40,0xffff,0xffff,CUSTOMSCREEN,
X#ifdef INTUI_NEW_LOOK
X tags,
X#endif
X },
X 0,0,1,1,80,80},
X
X /* NHW_STATUS */
X {{0,181,640,24,0xff,0xff, RAWKEY|MENUPICK|DISKINSERTED,
X BORDERLESS|ACTIVATE|SMART_REFRESH
X#ifdef INTUI_NEW_LOOK
X |WFLG_NW_EXTENDED
X#endif
X ,
X NULL,NULL,(UBYTE*)"Game Status",NULL,NULL,-1,-1,0xffff,0xffff,CUSTOMSCREEN,
X#ifdef INTUI_NEW_LOOK
X tags,
X#endif
X },
X 0,0,2,2,78,78},
X
X /* NHW_MAP */
X {{0,0,WIDTH,WINDOWHEIGHT,0xff,0xff,
X RAWKEY|MENUPICK|MOUSEBUTTONS|ACTIVEWINDOW|MOUSEMOVE,
X BORDERLESS|ACTIVATE|SMART_REFRESH|BACKDROP
X#ifdef INTUI_NEW_LOOK
X |WFLG_NW_EXTENDED
X#endif
X ,
X NULL,NULL,(UBYTE*)"Dungeon Map",NULL,NULL,-1,-1,0xffff,0xffff,CUSTOMSCREEN,
X#ifdef INTUI_NEW_LOOK
X tags,
X#endif
X },
X 0,0,22,22,80,80},
X
X /* NHW_MENU */
X {{400,10,10,10,80,30,
X RAWKEY|MENUPICK|DISKINSERTED|MOUSEMOVE|MOUSEBUTTONS|
X GADGETUP|GADGETDOWN|CLOSEWINDOW|VANILLAKEY|NEWSIZE|INACTIVEWINDOW,
X WINDOWSIZING|WINDOWCLOSE|WINDOWDRAG|ACTIVATE|SMART_REFRESH
X#ifdef INTUI_NEW_LOOK
X |WFLG_NW_EXTENDED
X#endif
X ,
X &MenuScroll,NULL,(UBYTE*)"Pick an Item",
X NULL,NULL,-1,-1,0xffff,0xffff,CUSTOMSCREEN,
X#ifdef INTUI_NEW_LOOK
X tags,
X#endif
X },
X 0,0,1,1,22,78},
X
X /* NHW_TEXT */
X {{0,0,640,200,0xff,0xff,
X RAWKEY|MENUPICK|DISKINSERTED|MOUSEMOVE|
X GADGETUP|CLOSEWINDOW|VANILLAKEY|NEWSIZE,
X WINDOWSIZING|WINDOWCLOSE|WINDOWDRAG|ACTIVATE|SMART_REFRESH
X#ifdef INTUI_NEW_LOOK
X |WFLG_NW_EXTENDED
X#endif
X ,
X &MenuScroll,NULL,(UBYTE*)NULL,NULL,NULL,-1,-1,0xffff,0xffff,CUSTOMSCREEN,
X#ifdef INTUI_NEW_LOOK
X tags,
X#endif
X },
X 0,0,1,1,22,78},
X
X /* NHW_BASE */
X {{0,0,WIDTH,WINDOWHEIGHT,0xff,0xff,
X RAWKEY|MENUPICK|MOUSEBUTTONS,
X BORDERLESS|ACTIVATE|SMART_REFRESH|BACKDROP
X#ifdef INTUI_NEW_LOOK
X |WFLG_NW_EXTENDED
X#endif
X ,
X NULL,NULL,(UBYTE*)NULL,NULL,NULL,-1,-1,0xffff,0xffff,CUSTOMSCREEN,
X#ifdef INTUI_NEW_LOOK
X tags,
X#endif
X },
X 0,0,22,22,80,80},
X
X#ifdef VIEWWINDOW
X /* NHW_VIEW */
X {{0,0,WIDTH,WINDOWHEIGHT,0xff,0xff,
X RAWKEY|MENUPICK|MOUSEBUTTONS,
X BORDERLESS|ACTIVATE|SMART_REFRESH
X#ifdef INTUI_NEW_LOOK
X |WFLG_NW_EXTENDED
X#endif
X ,
X NULL,NULL,(UBYTE*)NULL,NULL,NULL,-1,-1,0xffff,0xffff,CUSTOMSCREEN,
X#ifdef INTUI_NEW_LOOK
X tags,
X#endif
X },
X 0,0,VIEWCHARWIDTH,VIEWCHARHEIGHT,VIEWCHARWIDTH,VIEWCHARHEIGHT},
X
X /* NHW_VIEWBOX */
X {{0,0,WIDTH,WINDOWHEIGHT,0xff,0xff,
X RAWKEY|MENUPICK|MOUSEBUTTONS|REFRESHWINDOW,
X WINDOWSIZING|WINDOWDRAG|ACTIVATE|SIMPLE_REFRESH
X#ifdef INTUI_NEW_LOOK
X |WFLG_NW_EXTENDED
X#endif
X ,
X NULL,NULL,(UBYTE*)NULL,NULL,NULL,-1,-1,0xffff,0xffff,CUSTOMSCREEN,
X#ifdef INTUI_NEW_LOOK
X tags,
X#endif
X },
X 0,0,VIEWCHARWIDTH,VIEWCHARHEIGHT,VIEWCHARWIDTH,VIEWCHARHEIGHT},
X#endif
X};
X
Xconst char winpanicstr[] = "Bad winid %d in %s()";
X
X/* The opened windows information */
Xstruct amii_WinDesc *amii_wins[ MAXWIN + 1 ];
X
X#ifdef INTUI_NEW_LOOK
XUWORD scrnpens[] =
X{
X#ifndef VIEWWINDOW
X C_BLACK, /* DETAILPEN */
X C_BLUE, /* BLOCKPEN */
X C_BROWN, /* TEXTPEN */
X C_WHITE, /* SHINEPEN */
X C_BLUE, /* SHADOWPEN */
X C_CYAN, /* FILLPEN */
X C_WHITE, /* FILLTEXTPEN */
X C_CYAN, /* BACKGROUNDPEN */
X C_RED, /* HIGHLIGHTTEXTPEN */
X#else
X C_BLACK, /* DETAILPEN */
X C_BLUE, /* BLOCKPEN */
X C_BROWN, /* TEXTPEN */
X C_WHITE, /* SHINEPEN */
X C_BLUE, /* SHADOWPEN */
X C_CYAN, /* FILLPEN */
X C_WHITE, /* FILLTEXTPEN */
X C_CYAN, /* BACKGROUNDPEN */
X C_RED, /* HIGHLIGHTTEXTPEN */
X#endif
X};
X
Xstruct TagItem scrntags[] =
X{
X { SA_PubName, (ULONG)"NetHack" },
X { SA_Overscan, OSCAN_TEXT },
X { SA_Pens, (ULONG)scrnpens },
X { TAG_DONE, 0 },
X};
X#endif
X
Xstruct NewScreen NewHackScreen =
X{
X 0, 0, WIDTH, SCREENHEIGHT, DEPTH,
X C_BROWN, C_BLUE, /* DetailPen, BlockPen */
X HIRES,
X CUSTOMSCREEN
X#ifdef INTUI_NEW_LOOK
X |NS_EXTENDED
X#endif
X ,
X &Hack80, /* Font */
X NULL, /*(UBYTE *)" NetHack X.Y.Z" */
X NULL, /* Gadgets */
X NULL, /* CustomBitmap */
X#ifdef INTUI_NEW_LOOK
X scrntags,
X#endif
X};
X
X/*
X * plname is filled either by an option (-u Player or -uPlayer) or
X * explicitly (by being the wizard) or by askname.
X * It may still contain a suffix denoting pl_character.
X * Always called after init_nhwindows() and before display_gamewindows().
X */
Xvoid
Xamii_askname()
X{
X *plname = 0;
X do {
X getlin( "Who are you?", plname );
X } while( strlen( plname ) == 0 );
X
X if( *plname == '\33' )
X {
X clearlocks();
X exit_nhwindows(NULL);
X terminate(0);
X }
X}
X
X#include "Amiga:char.c"
X
X/* Get the player selection character */
X
Xvoid
Xamii_player_selection()
X{
X register struct Window *cwin;
X register struct IntuiMessage *imsg;
X register int aredone = 0;
X register struct Gadget *gd;
X static int once=0;
X long class, code;
X
X amii_clear_nhwindow( WIN_BASE );
X if( *pl_character ){
X pl_character[ 0 ] = toupper( pl_character[ 0 ] );
X if( index( pl_classes, pl_character[ 0 ] ) )
X return;
X }
X
X if( !once ){
X if( bigscreen ){
X Type_NewWindowStructure1.TopEdge =
X (HackScreen->Height/2) - (Type_NewWindowStructure1.Height/2);
X }
X for( gd = Type_NewWindowStructure1.FirstGadget; gd;
X gd = gd->NextGadget )
X {
X if( gd->GadgetID != 0 )
X SetBorder( gd );
X }
X once = 1;
X }
X
X Type_NewWindowStructure1.Screen = HackScreen;
X if( ( cwin = OpenShWindow( (void *)&Type_NewWindowStructure1 ) ) == NULL )
X {
X return;
X }
X WindowToFront( cwin );
X
X while( !aredone )
X {
X WaitPort( cwin->UserPort );
X while( ( imsg = (void *) GetMsg( cwin->UserPort ) ) != NULL )
X {
X class = imsg->Class;
X code = imsg->Code;
X gd = (struct Gadget *)imsg->IAddress;
X ReplyMsg( (struct Message *)imsg );
X
X switch( class )
X {
X case VANILLAKEY:
X if( index( pl_classes, toupper( code ) ) )
X {
X pl_character[0] = toupper( code );
X aredone = 1;
X }
X else if( code == ' ' || code == '\n' || code == '\r' )
X {
X#ifdef TOURIST
X strcpy( pl_character, roles[ rnd( 11 ) ] );
X#else
X strcpy( pl_character, roles[ rnd( 10 ) ] );
X#endif
X aredone = 1;
X amii_clear_nhwindow( WIN_BASE );
X CloseShWindow( cwin );
X RandomWindow( pl_character );
X return;
X }
X else if( code == 'q' || code == 'Q' )
X {
X CloseShWindow( cwin );
X clearlocks();
X exit_nhwindows(NULL);
X terminate(0);
X }
X else
X DisplayBeep( NULL );
X break;
X
X case GADGETUP:
X switch( gd->GadgetID )
X {
X case 1: /* Random Character */
X#ifdef TOURIST
X strcpy( pl_character, roles[ rnd( 11 ) ] );
X#else
X strcpy( pl_character, roles[ rnd( 10 ) ] );
X#endif
X amii_clear_nhwindow( WIN_BASE );
X CloseShWindow( cwin );
X RandomWindow( pl_character );
X return;
X
X default:
X pl_character[0] = gd->GadgetID;
X break;
X }
X aredone = 1;
X break;
X
X case CLOSEWINDOW:
X CloseShWindow( cwin );
X clearlocks();
X exit_nhwindows(NULL);
X terminate(0);
X break;
X }
X }
X }
X amii_clear_nhwindow( WIN_BASE );
X CloseShWindow( cwin );
X}
X
X#include "Amiga:randwin.c"
X
Xvoid
XRandomWindow( name )
X char *name;
X{
X struct MsgPort *tport;
X struct timerequest *trq;
X static int once = 0;
X struct Gadget *gd;
X struct Window *w;
X struct IntuiMessage *imsg;
X int ticks = 0, aredone = 0, timerdone = 0;
X long mask, got;
X
X tport = CreatePort( 0, 0 );
X trq = (struct timerequest *)CreateExtIO( tport, sizeof( *trq ) );
X if( tport == NULL || trq == NULL )
X {
Xallocerr:
X if( tport ) DeletePort( tport );
X if( trq ) DeleteExtIO( (struct IORequest *)trq );
X Delay( 8 * 50 );
X return;
X }
X
X if( OpenDevice( TIMERNAME, UNIT_VBLANK, (struct IORequest *)trq, 0L ) != 0 )
X goto allocerr;
X
X trq->tr_node.io_Command = TR_ADDREQUEST;
X trq->tr_time.tv_secs = 8;
X trq->tr_time.tv_micro = 0;
X
X SendIO( (struct IORequest *)trq );
X
X /* Place the name in the center of the screen */
X Rnd_IText5.IText = name;
X Rnd_IText6.LeftEdge = Rnd_IText4.LeftEdge +
X (strlen(Rnd_IText4.IText)+1)*8;
X Rnd_NewWindowStructure1.Width = (
X (strlen( Rnd_IText2.IText )+1) * 8 ) +
X HackScreen->WBorLeft + HackScreen->WBorRight;
X Rnd_IText5.LeftEdge = (Rnd_NewWindowStructure1.Width -
X (strlen(name)*8))/2;
X
X gd = Rnd_NewWindowStructure1.FirstGadget;
X gd->LeftEdge = (Rnd_NewWindowStructure1.Width - gd->Width)/2;
X /* Chose correct modifier */
X Rnd_IText6.IText = "a";
X switch( *name )
X {
X case 'a': case 'e': case 'i': case 'o':
X case 'u': case 'A': case 'E': case 'I':
X case 'O': case 'U':
X Rnd_IText6.IText = "an";
X break;
X }
X
X if( !once )
X {
X if( bigscreen )
X {
X Rnd_NewWindowStructure1.TopEdge =
X (HackScreen->Height/2) - (Rnd_NewWindowStructure1.Height/2);
X }
X for( gd = Rnd_NewWindowStructure1.FirstGadget; gd; gd = gd->NextGadget )
X {
X if( gd->GadgetID != 0 )
X SetBorder( gd );
X }
X Rnd_NewWindowStructure1.IDCMPFlags |= VANILLAKEY;
X
X once = 1;
X }
X
X Rnd_NewWindowStructure1.Screen = HackScreen;
X if( ( w = OpenShWindow( (void *)&Rnd_NewWindowStructure1 ) ) == NULL )
X {
X AbortIO( (struct IORequest *)trq );
X WaitIO( (struct IORequest *)trq );
X CloseDevice( (struct IORequest *)trq );
X DeleteExtIO( (struct IORequest *) trq );
X DeletePort( tport );
X Delay( 50 * 8 );
X return;
X }
X
X PrintIText( w->RPort, &Rnd_IntuiTextList1, 0, 0 );
X
X mask = (1L << tport->mp_SigBit)|(1L << w->UserPort->mp_SigBit);
X while( !aredone )
X {
X got = Wait( mask );
X if( got & (1L << tport->mp_SigBit ) )
X {
X aredone = 1;
X timerdone = 1;
X GetMsg( tport );
X }
X while( w && ( imsg = (struct IntuiMessage *) GetMsg( w->UserPort ) ) )
X {
X switch( imsg->Class )
X {
X /* Must be up for a little while... */
X case INACTIVEWINDOW:
X if( ticks >= 40 )
X aredone = 1;
X break;
X
X case INTUITICKS:
X ++ticks;
X break;
X
X case GADGETUP:
X aredone = 1;
X break;
X
X case VANILLAKEY:
X if(imsg->Code=='\n' || imsg->Code==' ' || imsg->Code=='\r')
X aredone = 1;
X break;
X }
X ReplyMsg( (struct Message *)imsg );
X }
X }
X
X if( !timerdone )
X {
X AbortIO( (struct IORequest *)trq );
X WaitIO( (struct IORequest *)trq );
X }
X
X CloseDevice( (struct IORequest *)trq );
X DeleteExtIO( (struct IORequest *) trq );
X DeletePort( tport );
X if(w) CloseShWindow( w );
X}
X
X/* this should probably not be needed (or be renamed)
Xvoid
Xflush_output(){} */
X
X#ifdef COM_COMPL
X/* Read in an extended command - doing command line completion for
X * when enough characters have been entered to make a unique command.
X */
Xvoid
Xamii_get_ext_cmd(bufp)
Xregister char *bufp;
X{
X register char *obufp = bufp;
X register int c;
X int com_index, oindex;
X struct amii_WinDesc *cw;
X struct Window *w;
X int colx;
X int did_comp=0; /* did successful completion? */
X int bottom = 0;
X
X if( WIN_MESSAGE == WIN_ERR || ( cw = amii_wins[ WIN_MESSAGE ] ) == NULL )
X panic(winpanicstr, WIN_MESSAGE, "get_ext_cmd");
X amii_clear_nhwindow( NHW_MESSAGE );
X pline("# ");
X colx = 3;
X w = cw->win;
X
X if( bigscreen )
X {
X bottom = w->Height - w->BorderTop - w->BorderBottom;
X bottom /= w->RPort->TxHeight;
X if( bottom > 0 )
X --bottom;
X }
X while((c = WindowGetchar()) != EOF)
X {
X amii_curs( WIN_MESSAGE, colx, bottom );
X if(c == '?' )
X {
X int win, i, sel;
X char buf[ 100 ];
X
X win = amii_create_nhwindow( NHW_MENU );
X amii_start_menu( win );
X
X for( i = 0; extcmdlist[ i ].ef_txt != NULL; ++i )
X {
X sprintf( buf, "%-10s - %s ",
X extcmdlist[ i ].ef_txt,
X extcmdlist[ i ].ef_desc );
X amii_add_menu( win, extcmdlist[i].ef_txt[0], 0, buf );
X }
X
X amii_end_menu( win, i, "\33", NULL );
X sel = amii_select_menu( win );
X amii_destroy_nhwindow( win );
X
X if( sel == '\33' || !sel )
X {
X *obufp = '\33';
X obufp[ 1 ] = 0;
X }
X else
X {
X for( i = 0; extcmdlist[ i ].ef_txt != NULL; ++i )
X {
X if( sel == extcmdlist[i].ef_txt[0] )
X break;
X }
X
X /* copy in the text */
X amii_clear_nhwindow( WIN_MESSAGE );
X strcpy( obufp, extcmdlist[ i ].ef_txt );
X colx = 0;
X pline( "# " );
X pline( obufp );
X bufp = obufp + 2;
X }
X return;
X }
X else if(c == '\033')
X {
X *obufp = c;
X obufp[1] = 0;
X return;
X }
X else if(c == '\b')
X {
X if(did_comp){
X while(bufp!=obufp){
X bufp--;
X amii_curs(WIN_MESSAGE, --colx, bottom);
X Text(w->RPort,spaces,1);
X amii_curs(WIN_MESSAGE,colx,bottom);
X did_comp=0;
X }
X }else
X if(bufp != obufp)
X {
X bufp--;
X amii_curs( WIN_MESSAGE, --colx, bottom);
X Text( w->RPort, spaces, 1 );
X amii_curs( WIN_MESSAGE, colx, bottom);
X }
X else
X DisplayBeep( NULL );
X }
X else if( c == '\n' || c == '\r' )
X {
X *bufp = 0;
X return;
X }
X else if(' ' <= c && c < '\177')
X {
X /* avoid isprint() - some people don't have it
X ' ' is not always a printing char */
X *bufp = c;
X bufp[1] = 0;
X oindex = 0;
X com_index = -1;
X
X while(extcmdlist[oindex].ef_txt != NULL)
X {
X if(!strnicmp(obufp, extcmdlist[oindex].ef_txt, strlen(obufp)))
X {
X if(com_index == -1) /* No matches yet*/
X com_index = oindex;
X else /* More than 1 match */
X com_index = -2;
X }
X oindex++;
X }
X
X if(com_index >= 0 && *obufp )
X {
X Strcpy(obufp, extcmdlist[com_index].ef_txt);
X /* finish printing our string */
X Text( w->RPort, bufp, strlen( bufp ) );
X amii_curs( WIN_MESSAGE, colx += strlen( bufp ), bottom);
X bufp = obufp; /* reset it */
X if(strlen(obufp) < BUFSZ-1 && strlen(obufp) < COLNO)
X bufp += strlen(obufp);
X did_comp=1;
X }
X else
X {
X Text( w->RPort, bufp, strlen( bufp ) );
X amii_curs( WIN_MESSAGE, colx += strlen( bufp ), bottom);
X if(bufp-obufp < BUFSZ-1 && bufp-obufp < COLNO)
X bufp++;
X }
X }
X else if(c == ('X'-64) || c == '\177')
X {
X colx = 0;
X amii_clear_nhwindow( WIN_MESSAGE );
X pline( "# " );
X bufp = obufp;
X } else
X DisplayBeep( NULL );
X }
X *bufp = 0;
X return;
X}
X#endif /* COM_COMPL */
X
X#ifdef WINDOW_YN
XSHORT Ask_BorderVectors1[] = { 0,0, 29,0, 29,11, 0,11, 0,0 };
Xstruct Border Ask_Border1 = { -1,-1, 3,0,JAM1, 5, Ask_BorderVectors1, NULL };
Xstruct IntuiText Ask_IText1 = { 3,0,JAM2, 2,1, NULL, "(?)", NULL };
X
Xstruct Gadget Ask_Gadget1 = {
X NULL, 9,4, 28,10, NULL, RELVERIFY, BOOLGADGET, (APTR)&Ask_Border1,
X NULL, &Ask_IText1, NULL, NULL, NULL, NULL
X};
X
X#define Ask_GadgetList1 Ask_Gadget1
X
Xstruct IntuiText Ask_IText2 = { 1,0,JAM2, 44,5, NULL, NULL, NULL };
X
X#define Ask_IntuiTextList1 Ask_IText2
X
Xstruct NewWindow Ask_Window = {
X 75,85, 524,18, 0,1, GADGETUP+VANILLAKEY, ACTIVATE+NOCAREREFRESH,
X &Ask_Gadget1, NULL, NULL, NULL, NULL, 5,5, -1,-1, CUSTOMSCREEN
X};
X#endif
X
X/* Ask a question and get a response */
X
X#ifdef OLDCODE
X
Xchar amii_yn_function( prompt, resp, def )
X const char *prompt,*resp;
X char def;
X{
X char ch;
X char buf[ 80 ];
X
X if( def && def!='q')
X {
X sprintf( buf, "%s [%c] ", prompt, def );
X amii_addtopl( buf );
X } else {
X amii_addtopl( prompt );
X }
X
X cursor_on( WIN_MESSAGE );
X do {
X ch = WindowGetchar();
X if( ch == '\33' )
X break;
X else if( def && ( ch == '\n' || ch == '\r' ) )
X {
X ch = def;
X break;
X }
X else if( isdigit(ch) && index(resp, '#')){
X
X }
X } while( resp && *resp && index( resp, ch ) == 0 );
X
X cursor_off( WIN_MESSAGE );
X if( ch == '\33' )
X {
X if(index(resp, 'q'))
X ch = 'q';
X else if(index(resp, 'n'))
X ch = 'n';
X else ch = def;
X }
X /* Try this to make topl behave more appropriately? */
X clear_nhwindow( WIN_MESSAGE );
X return( ch );
X}
X#else
Xchar amii_yn_function(query,resp, def)
Xconst char *query,*resp;
Xchar def;
X/*
X * Generic yes/no function. 'def' is the default (returned by space or
X * return; 'esc' returns 'q', or 'n', or the default, depending on
X * what's in the string. The 'query' string is printed before the user
X * is asked about the string.
X * If resp is NULL, any single character is accepted and returned.
X */
X{
X register char q;
X char rtmp[40];
X boolean digit_ok, allow_num;
X char prompt[QBUFSZ];
X register struct amii_WinDesc *cw;
X
X if( cw = amii_wins[ WIN_MESSAGE ] )
X cw->disprows = 0;
X if(resp) {
X allow_num = (index(resp, '#') != 0);
X if(def)
X Sprintf(prompt, "%s [%s] (%c) ", query, resp, def);
X else
X Sprintf(prompt, "%s [%s] ", query, resp);
X amii_addtopl(prompt);
X } else {
X amii_addtopl(query);
X cursor_on(WIN_MESSAGE);
X q = WindowGetchar();
X cursor_off(WIN_MESSAGE);
X#if 1
X TOPL_NOSPACE;
X *rtmp = q;
X rtmp[ 1 ] = 0;
X amii_putstr(WIN_MESSAGE,-1,rtmp);
X TOPL_SPACE;
X#endif
X goto clean_up;
X }
X
X do { /* loop until we get valid input */
X cursor_on(WIN_MESSAGE);
X q = lowc(WindowGetchar());
X cursor_off(WIN_MESSAGE);
X#if 0
X/* fix for PL2 */
X if (q == '\020') { /* ctrl-P */
X if(!doprev) (void) tty_doprev_message(); /* need two initially */
X (void) tty_doprev_message();
X q = (char)0;
X doprev = 1;
X continue;
X } else if(doprev) {
X tty_clear_nhwindow(WIN_MESSAGE);
X cw->maxcol = cw->maxrow;
X doprev = 0;
X amii_addtopl(prompt);
X continue;
X }
X#endif
X digit_ok = allow_num && isdigit(q);
X if (q == '\033') {
X if (index(resp, 'q'))
X q = 'q';
X else if (index(resp, 'n'))
X q = 'n';
X else
X q = def;
X break;
X } else if (index(quitchars, q)) {
X q = def;
X break;
X }
X if (!index(resp, q) && !digit_ok) {
X amii_bell();
X q = (char)0;
X } else if (q == '#' || digit_ok) {
X char z, digit_string[2];
X int n_len = 0;
X long value = 0;
X TOPL_NOSPACE;
X amii_addtopl("#"), n_len++;
X TOPL_SPACE;
X digit_string[1] = '\0';
X if (q != '#') {
X digit_string[0] = q;
X TOPL_NOSPACE;
X amii_addtopl(digit_string), n_len++;
X TOPL_SPACE;
X value = q - '0';
X q = '#';
X }
X do { /* loop until we get a non-digit */
X cursor_on(WIN_MESSAGE);
X z = lowc(WindowGetchar());
X cursor_off(WIN_MESSAGE);
X if (isdigit(z)) {
X value = (10 * value) + (z - '0');
X if (value < 0) break; /* overflow: try again */
X digit_string[0] = z;
X TOPL_NOSPACE;
X amii_addtopl(digit_string), n_len++;
X TOPL_SPACE;
X } else if (z == 'y' || index(quitchars, z)) {
X if (z == '\033') value = -1; /* abort */
X z = '\n'; /* break */
X } else if ( z == '\b') {
X if (n_len <= 1) { value = -1; break; }
X else { value /= 10; removetopl(1), n_len--; }
X } else {
X value = -1; /* abort */
X amii_bell();
X break;
X }
X } while (z != '\n');
X if (value > 0) yn_number = value;
X else if (value == 0) q = 'n'; /* 0 => "no" */
X else { /* remove number from top line, then try again */
X removetopl(n_len), n_len = 0;
X q = '\0';
X }
X }
X } while(!q);
X
X if (q != '#') {
X Sprintf(rtmp, "%c", q);
X#if 0
X amii_addtopl(rtmp);
X#else
X TOPL_NOSPACE;
X amii_putstr(WIN_MESSAGE,-1,rtmp);
X TOPL_SPACE;
X#endif
X }
X clean_up:
X cursor_off(WIN_MESSAGE);
X clear_nhwindow(WIN_MESSAGE);
X return q;
X}
X
X#endif
X
X
Xvoid
Xamii_display_file(fn, complain)
Xconst char *fn;
Xboolean complain;
X{
X register struct amii_WinDesc *cw;
X register int win;
X register FILE *fp;
X register char *t;
X register char buf[ 200 ];
X
X if( fn == NULL )
X panic("NULL file name in display_file()");
X
X if( ( fp = fopenp( fn, "r" ) ) == NULL )
X {
X if (complain) {
X sprintf( buf, "Can't display %s: %s", fn,
X#ifdef __SASC_60
X __sys_errlist[ errno ]
X#else
X sys_errlist[ errno ]
X#endif
X );
X amii_addtopl( buf );
X }
X return;
X }
X win = amii_create_nhwindow( NHW_TEXT );
X
X /* Set window title to file name */
X if( cw = amii_wins[ win ] )
X cw->morestr = fn;
X
X while( fgets( buf, sizeof( buf ), fp ) != NULL )
X {
X if( t = index( buf, '\n' ) )
X *t = 0;
X amii_putstr( win, 0, buf );
X }
X fclose( fp );
X
X /* If there were lines in the file, display those lines */
X
X if( amii_wins[ win ]->cury > 0 )
X amii_display_nhwindow( win, TRUE );
X
X amii_wins[win]->morestr = NULL; /* don't free title string */
X amii_destroy_nhwindow( win );
X}
X
X/* Put a 3-D motif border around the gadget. String gadgets or those
X * which do not have highlighting are rendered down. Boolean gadgets
X * are rendered in the up position by default.
X */
X
Xvoid
XSetBorder( gd )
X register struct Gadget *gd;
X{
X register struct Border *bp;
X register short *sp;
X register int i, inc = -1, dec = -1;
X int borders = 6;
X
X /* Allocate two border structures one for up image and one for down
X * image, plus vector arrays for the border lines.
X */
X
X if( gd->GadgetType == STRGADGET )
X borders = 12;
X
X if( ( bp = (struct Border *)alloc( ( ( sizeof( struct Border ) * 2 ) +
X ( sizeof( short ) * borders ) ) * 2 ) ) == NULL )
X {
X return;
X }
X
X /* For a string gadget, we expand the border beyond the area where
X * the text will be entered.
X */
X
X /* Remove any special rendering flags to avoid confusing intuition
X */
X
X gd->Flags &= ~(GADGHIGHBITS|GADGIMAGE);
X
X sp = (short *)(bp + 4);
X if( gd->GadgetType == STRGADGET || ( gd->GadgetType == BOOLGADGET &&
X ( gd->Flags & GADGHIGHBITS ) == GADGHNONE ) )
X {
X sp[0] = -1;
X sp[1] = gd->Height - 1;
X sp[2] = -1;
X sp[3] = -1;
X sp[4] = gd->Width - 1;
X sp[5] = -1;
X
X sp[6] = gd->Width + 1;
X sp[7] = -2;
X sp[8] = gd->Width + 1;
X sp[9] = gd->Height + 1;
X sp[10] = -2;
X sp[11] = gd->Height + 1;
X
X sp[12] = -2;
X sp[13] = gd->Height;
X sp[14] = -2;
X sp[15] = -2;
X sp[16] = gd->Width;
X sp[17] = -2;
X sp[18] = gd->Width;
X sp[19] = gd->Height;
X sp[20] = -2;
X sp[21] = gd->Height;
X
X for( i = 0; i < 3; ++i )
X {
X bp[ i ].LeftEdge = bp[ i ].TopEdge = -1;
X bp[ i ].FrontPen = ( i == 0 || i == 1 ) ? C_BLUE : C_WHITE;
X
X /* Have to use JAM2 so that the old colors disappear. */
X bp[ i ].BackPen = C_BLACK;
X bp[ i ].DrawMode = JAM2;
X bp[ i ].Count = ( i == 0 || i == 1 ) ? 3 : 5;
X bp[ i ].XY = &sp[ i*6 ];
X bp[ i ].NextBorder = ( i == 2 ) ? NULL : &bp[ i + 1 ];
X }
X
X /* bp[0] and bp[1] two pieces for the up image */
X gd->GadgetRender = (APTR) bp;
X
X /* No image change for select */
X gd->SelectRender = (APTR) bp;
X
X gd->LeftEdge++;
X gd->TopEdge++;
X gd->Flags |= GADGHCOMP;
X }
X else
X {
X /* Create the border vector values for up and left side, and
X * also the lower and right side.
X */
X
X sp[0] = dec;
X sp[1] = gd->Height + inc;
X sp[2] = dec;
X sp[3] = dec;
X sp[4] = gd->Width + inc;
X sp[5] = dec;
X
X sp[6] = gd->Width + inc;
X sp[7] = dec;
X sp[8] = gd->Width + inc;
X sp[9] = gd->Height + inc;
X sp[10] = dec;
X sp[11] = gd->Height + inc;
X
X /* We are creating 4 sets of borders, the two sides of the
X * rectangle share the border vectors with the opposite image,
X * but specify different colors.
X */
X
X for( i = 0; i < 4; ++i )
X {
X bp[ i ].TopEdge = bp[ i ].LeftEdge = 0;
X
X /* A GADGHNONE is always down */
X
X if( gd->GadgetType == BOOLGADGET &&
X ( gd->Flags & GADGHIGHBITS ) != GADGHNONE )
X {
X bp[ i ].FrontPen =
X ( i == 1 || i == 2 ) ? C_BLUE : C_WHITE;
X }
X else
X {
X bp[ i ].FrontPen =
X ( i == 1 || i == 3 ) ? C_WHITE : C_BLUE;
X }
X
X /* Have to use JAM2 so that the old colors disappear. */
X bp[ i ].BackPen = C_BLACK;
X bp[ i ].DrawMode = JAM2;
X bp[ i ].Count = 3;
X bp[ i ].XY = &sp[ 6 * ((i &1) != 0) ];
X bp[ i ].NextBorder =
X ( i == 1 || i == 3 ) ? NULL : &bp[ i + 1 ];
X }
X
X /* bp[0] and bp[1] two pieces for the up image */
X gd->GadgetRender = (APTR) bp;
X
X /* bp[2] and bp[3] two pieces for the down image */
X gd->SelectRender = (APTR) (bp + 2);
X gd->Flags |= GADGHIMAGE;
X }
X}
X
X#ifndef SHAREDLIB
X#if 0
Xvoid *
Xmalloc( register unsigned size )
X{
X register long *p;
X
X size += 4;
X p = AllocMem( size, MEMF_PUBLIC );
X if( p ) *p++ = size;
X else panic( "No memory left" );
X return( p );
X}
X
Xvoid
Xfree( void *q )
X{
X register long *p = q;
X
X if( !q )
X panic( "free of NULL pointer" );
X FreeMem( p-1, p[-1] );
X}
X#endif
X#endif
END_OF_FILE
if test 31018 -ne `wc -c <'sys/amiga/winami.c'`; then
echo shar: \"'sys/amiga/winami.c'\" unpacked with wrong size!
fi
# end of 'sys/amiga/winami.c'
if test -f 'sys/share/pcsys.c' -a "${1}" != "-c" ; then
echo shar: Renaming existing file \"'sys/share/pcsys.c'\" to \"'sys/share/pcsys.c.orig'\"
mv -f 'sys/share/pcsys.c' 'sys/share/pcsys.c.orig'
fi
echo shar: Extracting \"'sys/share/pcsys.c'\" \(9317 characters\)
sed "s/^X//" >'sys/share/pcsys.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)pcsys.c 3.1 93/05/24
X/* NetHack may be freely redistributed. See license for details. */
X
X/*
X * System related functions for MSDOS, OS/2, TOS, and Windows NT
X */
X
X#define NEED_VARARGS
X#include "hack.h"
X#include "wintty.h"
X
X#include <ctype.h>
X#include <fcntl.h>
X#ifndef __GO32__
X#include <process.h>
X#else
X#define P_WAIT 0
X#define P_NOWAIT 1
X#endif
X#ifdef TOS
X#include <osbind.h>
X#endif
X
X#ifdef MOVERLAY
Xextern void __far __cdecl _movepause( void );
Xextern void __far __cdecl _moveresume( void );
Xextern unsigned short __far __cdecl _movefpause;
Xextern unsigned short __far __cdecl _movefpaused;
X#define __MOVE_PAUSE_DISK 2 /* Represents the executable file */
X#define __MOVE_PAUSE_CACHE 4 /* Represents the cache memory */
X#endif /* MOVERLAY */
X
Xstatic boolean NDECL(record_exists);
X#ifndef TOS
Xstatic boolean NDECL(comspec_exists);
X#endif
X
X#ifdef WIN32CON
Xextern int ProgmanLaunched; /* from nttty.c */
X#endif
X
X#ifdef MICRO
X
Xvoid
Xflushout()
X{
X (void) fflush(stdout);
X return;
X}
X
Xstatic const char *COMSPEC =
X# ifdef TOS
X"SHELL";
X# else
X"COMSPEC";
X# endif
X
X#define getcomspec() getenv(COMSPEC)
X
X# ifdef SHELL
Xint
Xdosh()
X{
X extern char orgdir[];
X char *comspec;
X int spawnstat;
X
X if (comspec = getcomspec()) {
X# ifndef TOS /* TOS has a variety of shells */
X suspend_nhwindows("To return to NetHack, enter \"exit\" at the system prompt.\n");
X# else
X suspend_nhwindows((char *)0);
X# endif /* TOS */
X chdirx(orgdir, 0);
X# ifdef __GO32__
X if (system(comspec) < 0) { /* w...@eecs.umich.edu */
X# else
X# ifdef MOVERLAY
X /* Free the cache memory used by overlays, close .exe */
X _movefpause |= __MOVE_PAUSE_DISK;
X _movefpause |= __MOVE_PAUSE_CACHE;
X _movepause();
X# endif
X spawnstat = spawnl(P_WAIT, comspec, comspec, NULL);
X# ifdef MOVERLAY
X _moveresume();
X# endif
X
X if ( spawnstat < 0) {
X# endif
X raw_printf("Can't spawn \"%s\"!", comspec);
X getreturn("to continue");
X }
X# ifdef TOS
X/* Some shells (e.g. Gulam) turn the cursor off when they exit */
X if (flags.BIOS)
X (void)Cursconf(1, -1);
X# endif
X get_scr_size(); /* maybe the screen mode changed (TH) */
X resume_nhwindows();
X chdirx(hackdir, 0);
X } else
X pline("Can't find %s.",COMSPEC);
X return 0;
X}
X# endif /* SHELL */
X
X# ifdef MFLOPPY
X
Xvoid
Xeraseall(path, files)
Xconst char *path, *files;
X{
X char buf[PATHLEN];
X char *foundfile;
X
X foundfile = foundfile_buffer();
X Sprintf(buf, "%s%s", path, files);
X if (findfirst(buf))
X do {
X Sprintf(buf, "%s%s", path, foundfile);
X (void) unlink(buf);
X } while (findnext());
X return;
X}
X
X/*
X * Rewritten for version 3.3 to be faster
X */
Xvoid
Xcopybones(mode)
Xint mode;
X{
X char from[PATHLEN], to[PATHLEN], last[13];
X char *frompath, *topath;
X char *foundfile;
X# ifndef TOS
X int status;
X char copy[8], *comspec;
X# endif
X
X if (!ramdisk)
X return;
X
X /* Find the name of the last file to be transferred
X */
X frompath = (mode != TOPERM) ? permbones : levels;
X foundfile = foundfile_buffer();
X last[0] = '\0';
X Sprintf(from, "%s%s", frompath, allbones);
X topath = (mode == TOPERM) ? permbones : levels;
X# ifdef TOS
X eraseall(topath, allbones);
X# endif
X if (findfirst(from))
X do {
X# ifdef TOS
X Sprintf(from, "%s%s", frompath, foundfile);
X Sprintf(to, "%s%s", topath, foundfile);
X if (_copyfile(from, to))
X goto error_copying;
X# endif
X Strcpy(last, foundfile);
X } while (findnext());
X# ifdef TOS
X else
X return;
X# else
X if (last[0]) {
X Sprintf(copy, "%cC copy",switchar());
X
X /* Remove any bones files in `to' directory.
X */
X eraseall(topath, allbones);
X
X /* Copy `from' to `to' */
X Sprintf(to, "%s%s", topath, allbones);
X comspec = getcomspec();
X status =spawnl(P_WAIT, comspec, comspec, copy, from,
X to, "> nul", NULL);
X } else
X return;
X# endif /* TOS */
X
X /* See if the last file got there. If so, remove the ramdisk bones
X * files.
X */
X Sprintf(to, "%s%s", topath, last);
X if (findfirst(to)) {
X if (mode == TOPERM)
X eraseall(frompath, allbones);
X return;
X }
X
X# ifdef TOS
Xerror_copying:
X# endif
X /* Last file didn't get there.
X */
X Sprintf(to, "%s%s", topath, allbones);
X msmsg("Can't copy \"%s\" to \"%s\" -- ", from, to);
X# ifndef TOS
X if (status < 0)
X msmsg("can't spawn \"%s\"!", comspec);
X else
X# endif
X msmsg((freediskspace(topath) < filesize(from)) ?
X "insufficient disk space." : "bad path(s)?");
X if (mode == TOPERM) {
X msmsg("Bones will be left in \"%s\"\n",
X *levels ? levels : hackdir);
X } else {
X /* Remove all bones files on the RAMdisk */
X eraseall(levels, allbones);
X playwoRAMdisk();
X }
X return;
X}
X
Xvoid
XplaywoRAMdisk()
X{
X int c;
X
X msmsg("Do you wish to play without a RAMdisk? [yn] (n)");
X
X /* Set ramdisk false *before* exit-ing (because msexit calls
X * copybones)
X */
X ramdisk = FALSE;
X c = tgetch(); if (c == 'Y') c = 'y';
X if (c != 'y') {
X settty("Be seeing you...\n");
X exit(0);
X }
X set_lock_and_bones();
X return;
X}
X
Xint
XsaveDiskPrompt(start)
Xint start;
X{
X char buf[BUFSIZ], *bp;
X char qbuf[QBUFSZ];
X
X int fd;
X
X if (flags.asksavedisk) {
X /* Don't prompt if you can find the save file */
X if ((fd = open_savefile()) >= 0) {
X (void) close(fd);
X return 1;
X }
X clear_nhwindow(WIN_MESSAGE);
X pline("If save file is on a save disk, insert that disk now.");
X mark_synch();
X Sprintf(qbuf,"File name (default \"%s\"%s) ?", SAVEF,
X start ? "" : ", <Esc> cancels save");
X getlin(qbuf, buf);
X clear_nhwindow(WIN_MESSAGE);
X if (!start && *buf == '\033')
X return 0;
X
X /* Strip any whitespace. Also, if nothing was entered except
X * whitespace, do not change the value of SAVEF.
X */
X for (bp = buf; *bp; bp++)
X if (!isspace(*bp)) {
X strncpy(SAVEF, bp, PATHLEN);
X break;
X }
X }
X return 1;
X}
X
X# endif /* MFLOPPY */
X
X/* Return 1 if the record file was found */
Xstatic boolean
Xrecord_exists()
X{
X FILE *fp;
X
X fp = fopen_datafile(RECORD, "r");
X if (fp) {
X fclose(fp);
X return TRUE;
X }
X return FALSE;
X}
X
X# ifdef TOS
X#define comspec_exists() 1
X# else
X/* Return 1 if the comspec was found */
Xstatic boolean
Xcomspec_exists()
X{
X int fd;
X char *comspec;
X
X if (comspec = getcomspec())
X if ((fd = open(comspec, O_RDONLY)) >= 0) {
X (void) close(fd);
X return TRUE;
X }
X return FALSE;
X}
X# endif
X
X# ifdef MFLOPPY
X/* Prompt for game disk, then check for record file.
X */
Xvoid
XgameDiskPrompt()
X{
X if (flags.asksavedisk) {
X if (record_exists() && comspec_exists())
X return;
X (void) putchar('\n');
X getreturn("when the game disk has been inserted");
X }
X if (comspec_exists() && record_exists())
X return;
X
X if (!comspec_exists())
X msmsg("\n\nWARNING: can't find command processor \"%s\"!\n", getcomspec());
X if (!record_exists())
X msmsg("\n\nWARNING: can't find record file \"%s\"!\n", RECORD);
X msmsg("If the game disk is not in, insert it now.\n");
X getreturn("to continue");
X return;
X}
X# endif /* MFLOPPY */
X#endif /* MICRO */
X
X/*
X * Add a backslash to any name not ending in /, \ or : There must
X * be room for the \
X */
Xvoid
Xappend_slash(name)
Xchar *name;
X{
X char *ptr;
X
X if (!*name)
X return;
X ptr = name + (strlen(name) - 1);
X if (*ptr != '\\' && *ptr != '/' && *ptr != ':') {
X *++ptr = '\\';
X *++ptr = '\0';
X }
X return;
X}
X
Xvoid
Xgetreturn(str)
Xconst char *str;
X{
X#ifdef TOS
X msmsg("Hit <Return> %s.", str);
X#else
X msmsg("Hit <Enter> %s.", str);
X#endif
X while (Getchar() != '\n') ;
X return;
X}
X
Xvoid
Xmsmsg VA_DECL(const char *, fmt)
X VA_START(fmt);
X VA_INIT(fmt, const char *);
X Vprintf(fmt, VA_ARGS);
X flushout();
X VA_END();
X return;
X}
X
X/*
X * Follow the PATH, trying to fopen the file.
X */
X#ifdef TOS
X# ifdef __MINT__
X#define PATHSEP ':'
X# else
X#define PATHSEP ','
X# endif
X#else
X#define PATHSEP ';'
X#endif
X
XFILE *
Xfopenp(name, mode)
Xconst char *name, *mode;
X{
X char buf[BUFSIZ], *bp, *pp, lastch = 0;
X FILE *fp;
X
X /* Try the default directory first. Then look along PATH.
X */
X Strcpy(buf, name);
X if (fp = fopen(buf, mode))
X return fp;
X else {
X pp = getenv("PATH");
X while (pp && *pp) {
X bp = buf;
X while (*pp && *pp != PATHSEP)
X lastch = *bp++ = *pp++;
X if (lastch != '\\' && lastch != '/')
X *bp++ = '\\';
X Strcpy(bp, name);
X if (fp = fopen(buf, mode))
X return fp;
X if (*pp)
X pp++;
X }
X }
X#ifdef OS2_CODEVIEW /* one more try for hackdir */
X Strcpy(buf,hackdir);
X append_slash(buf);
X Strcat(buf,name);
X if(fp = fopen(buf,mode))
X return fp;
X#endif
X return (FILE *)0;
X}
X
X/* Chdir back to original directory
X */
X#undef exit
X#ifdef TOS
Xextern boolean run_from_desktop; /* set in pcmain.c */
X#endif
X
Xvoid exit(int);
X
Xvoid
Xmsexit(code)
Xint code;
X{
X#ifdef CHDIR
X extern char orgdir[];
X#endif
X
X flushout();
X#ifndef TOS
X# ifndef WIN32
X enable_ctrlP(); /* in case this wasn't done */
X# endif
X#endif
X#ifdef MFLOPPY
X if (ramdisk) copybones(TOPERM);
X#endif
X#ifdef CHDIR
X chdir(orgdir); /* chdir, not chdirx */
X chdrive(orgdir);
X#endif
X#ifdef TOS
X if (run_from_desktop)
X getreturn("to continue"); /* so the user can read the score list */
X# ifdef TEXTCOLOR
X if (colors_changed)
X restore_colors();
X# endif
X#endif
X#ifdef WIN32CON
X /* Only if we started from Progman, not command prompt,
X * we need to get one last return, so the score board does
X * not vanish instantly after being created.
X * ProgmanLaunched is defined and set in nttty.c.
X */
X
X if (ProgmanLaunched) getreturn("to end");
X#endif
X exit(code);
X return;
X}
X
END_OF_FILE
if test 9317 -ne `wc -c <'sys/share/pcsys.c'`; then
echo shar: \"'sys/share/pcsys.c'\" unpacked with wrong size!
fi
# end of 'sys/share/pcsys.c'
echo shar: End of archive 28 \(of 33\).
cp /dev/null ark28isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 33 archives.
echo "Now execute ./patchit.sh"
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0

0 new messages