home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / volume16 / nethck31 / patch2bb < prev    next >
Encoding:
Text File  |  1993-06-15  |  60.2 KB  |  2,652 lines

  1. Path: uunet!news.tek.com!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v17i103:  nethack31 - display oriented dungeons & dragons (Ver. 3.1), Patch2bb/33
  5. Date: 11 Jun 1993 00:18:31 GMT
  6. Organization: Tektronix, Inc, Redmond, OR, USA
  7. Lines: 2639
  8. Approved: billr@saab.CNA.TEK.COM
  9. Message-ID: <1v8j0n$j9i@ying.cna.tek.com>
  10. NNTP-Posting-Host: saab.cna.tek.com
  11. Xref: uunet comp.sources.games:1785
  12.  
  13. Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
  14. Posting-number: Volume 17, Issue 103
  15. Archive-name: nethack31/Patch2bb
  16. Patch-To: nethack31: Volume 16, Issue 1-116
  17. Environment: Amiga, Atari, Mac, MS-DOS, Windows-NT, OS2, Unix, VMS, X11
  18.  
  19.  
  20.  
  21. #! /bin/sh
  22. # This is a shell archive.  Remove anything before this line, then unpack
  23. # it by saving it into a file and typing "sh file".  To overwrite existing
  24. # files, type "sh file -c".  You can also feed this as standard input via
  25. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  26. # will see the following message at the end:
  27. #        "End of archive 28 (of 33)."
  28. # Contents:  sys/amiga/splitter/splitter.c sys/amiga/winami.c
  29. #   sys/share/pcsys.c
  30. # Wrapped by billr@saab on Thu Jun 10 16:55:07 1993
  31. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  32. if test -f 'sys/amiga/splitter/splitter.c' -a "${1}" != "-c" ; then 
  33.   echo shar: Renaming existing file \"'sys/amiga/splitter/splitter.c'\" to \"'sys/amiga/splitter/splitter.c.orig'\"
  34.   mv -f 'sys/amiga/splitter/splitter.c' 'sys/amiga/splitter/splitter.c.orig'
  35. fi
  36. echo shar: Extracting \"'sys/amiga/splitter/splitter.c'\" \(15390 characters\)
  37. sed "s/^X//" >'sys/amiga/splitter/splitter.c' <<'END_OF_FILE'
  38. X/*    SCCS Id: @(#)splitter.c        3.1   93/01/08
  39. X/*    Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1992, 1993 */
  40. X/* NetHack may be freely redistributed.  See license for details. */
  41. X
  42. X#define SOUT    /* split output files */
  43. X#define SPLITSIZE (800 * 1024)        /* somewhat < one floppy */
  44. X
  45. X#include <stdio.h>
  46. X#include <stdlib.h>
  47. X#include <string.h>
  48. X#include <fcntl.h>
  49. X
  50. X#include <proto/exec.h>
  51. X#include <exec/types.h>
  52. X#include <exec/nodes.h>
  53. X#include <exec/lists.h>
  54. X
  55. X#include "split.h"
  56. X#include "amiout.h"
  57. X#include "arg.h"
  58. X
  59. Xint main(int,char **);
  60. X
  61. Xchar *code_proto="%n.c%C";
  62. Xchar *data_proto="%n.d%D";
  63. Xchar *dir_proto="%n.dir";
  64. X
  65. Xchar trace[MAXTRACEVAR];        /* debugging info */
  66. Xchar *basename;
  67. Xint datacount;    /* for ssubst - should be replaced */
  68. Xint codecount;
  69. Xint data_file_count=0;    /* actual maxima */
  70. Xint code_file_count=0;
  71. Xstruct hheader hheader;
  72. Xstruct shunk (*hlist)[];
  73. Xchar buf[80];
  74. Xint wsf_count;
  75. X
  76. Xmain(argc,argv)
  77. X    int argc;
  78. X    char **argv;
  79. X{
  80. X    int cur_arg;
  81. X
  82. X    arg_init("C:D:d:t:T",argc,argv);
  83. X    while((cur_arg=arg_next())!=ARG_DONE){
  84. X    switch(cur_arg){
  85. X    case 'C':    /* code prototype */
  86. X        code_proto=strdup(argarg);break;
  87. X    case 'D':    /* data prototype */
  88. X        data_proto=strdup(argarg);break;
  89. X    case 'd':    /* directions prototype */
  90. X        dir_proto=strdup(argarg);break;
  91. X    case 't':    /* trace (debug) */
  92. X        {
  93. X        int dtype=0,dlevel=0;    /* rude defaults */
  94. X        sscanf(argarg,"%d=%d",&dtype,&dlevel);
  95. X        if(dtype<0 || dtype>=MAXTRACEVAR){
  96. X            fprintf(stderr,"-t: bad trace num ignored\n");
  97. X        }else{
  98. X            trace[dtype]=dlevel?dlevel:1;
  99. X        }
  100. X        break;
  101. X        }
  102. X    case 'T':    /* trace everything */
  103. X        {
  104. X        int dtype;
  105. X        for(dtype=0;dtype<MAXTRACEVAR;dtype++)trace[dtype]=255;
  106. X        }
  107. X        break;
  108. X    default:
  109. X        fprintf(stderr,"Unrecognized option.\n");
  110. X        /* FALLTHROUGH */
  111. X    case ARG_ERROR:
  112. X        panic("Error processing arguments.");
  113. X    case ARG_FREE:
  114. X        basename=strdup(argarg);
  115. X        read_load_file(basename);break;
  116. X    }
  117. X    }
  118. X    renumber();
  119. X    out_start(code_proto);
  120. X    write_header();
  121. X    write_code_file();
  122. X    out_stop();
  123. X    out_start(data_proto);
  124. X    write_data_file();
  125. X    out_stop();
  126. X    write_dir_file();
  127. X    exit(0);
  128. X}
  129. X
  130. Xchar *
  131. Xssubst(buf,pat)
  132. X    char *buf;
  133. X    const char *pat;
  134. X{
  135. X    char *buf1=buf;
  136. X
  137. X    while(*pat){
  138. X    if(*pat!='%'){
  139. X        *buf++=*pat++;
  140. X    } else {
  141. X        pat++;
  142. X        switch(*pat++){
  143. X        case '%': *buf++='%';break;
  144. X        case 'n': strcpy(buf,basename);buf=eos(buf);break;
  145. X        case 'D': sprintf(buf,"%02d",datacount);buf=eos(buf);break;
  146. X        case 'C': sprintf(buf,"%02d",codecount);buf=eos(buf);break;
  147. X        default:  panic("pattern substitution error");
  148. X        }
  149. X    }
  150. X    }
  151. X    *buf='\0';
  152. X    return buf1;
  153. X}
  154. X
  155. Xvoid
  156. Xpanic(s)
  157. X    char *s;
  158. X{
  159. X    fprintf(stderr,"\npanic: %s\n",s);
  160. X    exit(1);
  161. X}
  162. X
  163. Xchar *
  164. Xeos(s)
  165. X    char *s;
  166. X{
  167. X    while(*s)s++;
  168. X    return s;
  169. X}
  170. X
  171. X/* input routines */
  172. X
  173. X    /* macro for reading the next long.  If e==EOF_OK, caller MUST check
  174. X     * for EOF condition via hreadval or assure it can't occur */
  175. Xstatic int hreadval=0;        /* macro internal temporary */
  176. X#define EOF_OK    1
  177. X#define EOF_BAD    0
  178. X#define READLONG(e)    \
  179. X    ((4!=(hreadval=read(f->fd,&(READLONGx),4)))        \
  180. X    ?((0==hreadval && (e)                    \
  181. X        ?0                        \
  182. X        :rderror()))                    \
  183. X    :READLONGx)
  184. Xstatic long READLONGx;
  185. X#define READSHORT(e)    \
  186. X    ((2!=(hreadval=read(f->fd,&(READSHORTx),2)))        \
  187. X    ?((0==hreadval && (e)                    \
  188. X        ?0                        \
  189. X        :rderror()))                    \
  190. X    :READSHORTx)
  191. Xstatic short READSHORTx;
  192. X
  193. X#define LONGLEN(x)    (strlen(x)+3 >>2)    /* # longs for a string */
  194. X
  195. Xvoid
  196. Xread_load_file(name)
  197. X    char *name;
  198. X{
  199. X    int t;
  200. X    int hc;
  201. X    file *f=NewFile(name);
  202. X
  203. X        /* read HUNK_HEADER */
  204. X    t=READLONG(EOF_BAD);if(t!=HUNK_HEADER)panic("no HUNK_HEADER");
  205. X    t=READLONG(EOF_BAD);if(t)while(t--)READLONG(EOF_BAD); /* eat any name */
  206. X    hheader.hcount=READLONG(EOF_BAD);
  207. X    hheader.first=READLONG(EOF_BAD);
  208. X    hheader.last=READLONG(EOF_BAD);
  209. X    if(hheader.hcount !=(hheader.last-hheader.first+1))panic("can't count");
  210. X    hheader.sizes=calloc(hheader.hcount,sizeof(int*));
  211. X    for(t=0;t<hheader.hcount;t++)
  212. X    (*hheader.sizes)[t]=READLONG(EOF_BAD);
  213. X
  214. X    hlist=calloc(hheader.hcount,sizeof(struct shunk));
  215. X    for(hc=0;hc<hheader.hcount;hc++){
  216. X    struct shunk *th = &(*hlist)[hc];
  217. X            /* read each hunk */
  218. X    th->h=ReadHunk(f);
  219. X    }
  220. X    close(f->fd);
  221. X}
  222. X
  223. X/* write routines */
  224. X#define S_CODE    0
  225. X#define S_DATA    1
  226. X
  227. Xvoid
  228. Xwrite_header(){
  229. X    int x;
  230. X    int target=0;
  231. X
  232. X    owrite_long(HUNK_HEADER);
  233. X    owrite_long(0);
  234. X    owrite_long(hheader.hcount);
  235. X    owrite_long(hheader.first);
  236. X    owrite_long(hheader.last);
  237. X
  238. X    for(x=0;x<hheader.hcount;x++){
  239. X    hunk *hp = (*hlist)[x].h;
  240. X    if(hp->hunknum==target){
  241. X        owrite_long((*hheader.sizes)[x]);
  242. X        target++;
  243. X    }
  244. X    }
  245. X    for(x=0;x<hheader.hcount;x++){
  246. X    hunk *hp = (*hlist)[x].h;
  247. X    if(hp->hunknum==target){
  248. X        owrite_long((*hheader.sizes)[x]);
  249. X        target++;
  250. X    }
  251. X    }
  252. X    if(target!=hheader.hcount)panic("lost hunks?");
  253. X}
  254. X
  255. Xvoid
  256. Xwrite_code_file(){
  257. X    code_file_count=write_split_file(S_CODE)-1;
  258. X}
  259. X
  260. Xvoid
  261. Xwrite_data_file(){
  262. X    data_file_count=write_split_file(S_DATA)-1;
  263. X}
  264. X
  265. Xvoid
  266. Xwrite_dir_file(){
  267. X    int x;
  268. X    FILE *fp=fopen(ssubst(buf,dir_proto),"w");
  269. X
  270. X    fprintf(fp,"# split binary direction file\n");
  271. X    fprintf(fp,"# Each line consists of:\n");
  272. X    fprintf(fp,"#   A single C or D for the type of the file (Code or Data)\n");
  273. X    fprintf(fp,"#   The full path of the file.\n");
  274. X
  275. X    for(x=0;x<=code_file_count;x++){
  276. X    codecount=x;
  277. X    fprintf(fp,"C%s\n",ssubst(buf,code_proto));
  278. X    }
  279. X    for(x=0;x<=data_file_count;x++){
  280. X    datacount=x;
  281. X    fprintf(fp,"D%s\n",ssubst(buf,data_proto));
  282. X    }
  283. X    fclose(fp);
  284. X}
  285. X
  286. X/* BUGFIX: 9/23/92: see HT() above */
  287. X#define HT(x)    ((x) & ~MEM_OBJ_EXTEND)
  288. X
  289. Xint
  290. Xwrite_split_file(fl)
  291. X    int fl;
  292. X{
  293. X    int hc;
  294. X    for(hc=0;hc<hheader.hcount;hc++){
  295. X    hunk *hp = (*hlist)[hc].h;
  296. X    if(fl==S_CODE && HT(hp->rb->id)==HUNK_CODE){
  297. X        wsf_hunk(hp);
  298. X    } else if(fl==S_DATA && HT(hp->rb->id)==HUNK_DATA){
  299. X        wsf_hunk(hp);
  300. X    } else if(fl==S_DATA && HT(hp->rb->id)==HUNK_BSS){
  301. X        wsf_hunk(hp);
  302. X    }
  303. X    }
  304. X    return wsf_count;
  305. X}
  306. X
  307. X/* BUGFIX: 9/23/92: see HT() below */
  308. Xvoid
  309. Xwsf_hunk(hp)
  310. X    hunk *hp;
  311. X{
  312. X    listlist *el;
  313. X
  314. X    switch(HT(hp->rb->id)){
  315. X    case HUNK_CODE:
  316. X    case HUNK_DATA:
  317. X    owrite(hp->rb->b,(2+hp->rb->b[1])*sizeof(long));
  318. X    break;
  319. X    case HUNK_BSS:
  320. X    owrite(hp->rb->b,2*sizeof(long));
  321. X    break;
  322. X    default:panic("wsf_hunk: bad type");
  323. X    }
  324. X    foreach(el,&(hp->reloc),(listlist*)){
  325. X    write_lreloc(hp,el);
  326. X    }
  327. X    owrite_long(HUNK_END);
  328. X}
  329. X
  330. Xvoid
  331. Xwrite_lreloc(hp,ll)
  332. X    hunk *hp;listlist *ll;
  333. X    {
  334. X    block *bp;
  335. X
  336. X#ifdef EMIT_32s
  337. X    int x;
  338. X    ULONG *p;
  339. X
  340. X        /* can we write the entire block with a HUNK_RELOC32s? */
  341. X    foreach(bp,&(ll->list),(block*)){
  342. X    if((((*hlist)[bp->b[1]]).h->hunknum)>0xffff)goto no_32s; /* no */
  343. X    for(p= &(bp->b[2]), x=bp->b[0];x;x--,p++){
  344. X            if(*p>0xffff)goto no_32s;    /* no, offset too big */
  345. X    }
  346. X    }
  347. X        /* yes */
  348. X    owrite_long(HUNK_RELOC32s);
  349. X    foreach(bp,&(ll->list),(block*)){
  350. X    owrite_long(bp->b[0]);
  351. X    owrite_short(((*hlist)[bp->b[1]]).h->hunknum);
  352. X    for(p= &(bp->b[2]), x=bp->b[0];x;x--,p++){
  353. X        owrite_short(*p);
  354. X    }
  355. X            /* force long alignment.  Not documented, but makes
  356. X             * reading dumps easier */
  357. X    if((bp->b[0] & 1) == 0){    /* note hunknum also short */
  358. X        owrite_short(0);
  359. X    }
  360. X    }
  361. X    owrite_long(0);
  362. X    return;
  363. Xno_32s:
  364. X#endif
  365. X    owrite_long(HUNK_RELOC32);
  366. X    foreach(bp,&(ll->list),(block*)){
  367. X    owrite_long(bp->b[0]);
  368. X    owrite_long(((*hlist)[bp->b[1]]).h->hunknum);
  369. X    owrite(&(bp->b[2]),bp->b[0]*sizeof(long));
  370. X    }
  371. X    owrite_long(0);
  372. X}
  373. X
  374. Xvoid
  375. Xrenumber()
  376. X{
  377. X    int n;
  378. X    n=renumber2(S_CODE,0);
  379. X    renumber2(S_DATA,n);
  380. X}
  381. X
  382. X/* BUGFIX 9/23/92: hp->rb->id must be wrapped with a bit stripper to ignore
  383. X * memory type bits still in that longword.
  384. X */
  385. X
  386. Xrenumber2(fl,n)
  387. X    int fl;
  388. X    int n;
  389. X{
  390. X    int hc;
  391. X    for(hc=0;hc<hheader.hcount;hc++){
  392. X    hunk *hp = (*hlist)[hc].h;
  393. X    if(fl==S_CODE && HT(hp->rb->id)==HUNK_CODE){
  394. X        hp->hunknum=n++;
  395. X    } else if(fl==S_DATA && HT(hp->rb->id)==HUNK_DATA){
  396. X        hp->hunknum=n++;
  397. X    } else if(fl==S_DATA && HT(hp->rb->id)==HUNK_BSS){
  398. X        hp->hunknum=n++;
  399. X    }
  400. X    }
  401. X    return n;
  402. X}
  403. X
  404. X/* output package */
  405. X#ifndef SOUT
  406. X/* NB - this version does NOT cope with multiple output files per type */
  407. Xint ofile;
  408. X
  409. Xvoid
  410. Xout_start(prot)
  411. X    char *prot;
  412. X{
  413. X    datacount=codecount=0;
  414. X    file=open(ssubst(buf,prot),O_WRONLY|O_CREAT|O_TRUNC);
  415. X    if(ofile<0)panic("can't open output file");
  416. X}
  417. X
  418. Xvoid
  419. Xout_stop(){
  420. X    close(ofile);
  421. X}
  422. X
  423. Xvoid
  424. Xowrite_long(literal)
  425. X    long literal;
  426. X{
  427. X    long x=literal;
  428. X    owrite(&x,sizeof(x));
  429. X}
  430. X
  431. Xvoid
  432. Xowrite_short(literal)
  433. X    short literal;
  434. X{
  435. X    short x=literal;
  436. X    owrite(&x,sizeof(x));
  437. X}
  438. X
  439. Xvoid
  440. Xowrite(where,len)
  441. X    void *where;
  442. X    long len;
  443. X{
  444. X    write(ofile,where,len);
  445. X}
  446. X#else /* SOUT */
  447. Xint ofile=0;
  448. Xint osize;
  449. Xchar *oprot;
  450. Xvoid
  451. Xout_start(prot)
  452. X    char *prot;
  453. X{
  454. X    datacount=codecount=wsf_count=0;
  455. X    oprot=prot;
  456. X    new_file();
  457. X}
  458. X
  459. Xvoid
  460. Xout_stop(){
  461. X    close(ofile);
  462. X    ofile=0;
  463. X}
  464. X
  465. Xvoid
  466. Xowrite_long(literal)
  467. X    long literal;
  468. X{
  469. X    long x=literal;
  470. X    if((osize+sizeof(x))>SPLITSIZE)new_file();
  471. X    owrite(&x,sizeof(x));
  472. X    osize += sizeof(x);
  473. X}
  474. X
  475. Xvoid
  476. Xowrite_short(literal)
  477. X    short literal;
  478. X{
  479. X    short x=literal;
  480. X    if((osize+sizeof(x))>SPLITSIZE)new_file();
  481. X    owrite(&x,sizeof(x));
  482. X    osize += sizeof(x);
  483. X}
  484. X
  485. Xvoid
  486. Xowrite(where,len)
  487. X    void *where;
  488. X    long len;
  489. X{
  490. X    if((osize+len)>SPLITSIZE)new_file();
  491. X    write(ofile,where,len);
  492. X    osize += len;
  493. X}
  494. X
  495. Xvoid
  496. Xnew_file(){
  497. X    if(ofile)close(ofile);
  498. X    ofile=open(ssubst(buf,oprot),O_WRONLY|O_CREAT|O_TRUNC);
  499. X    if(ofile<0)panic("can't open output file");
  500. X    wsf_count++,datacount++,codecount++;
  501. X    osize=0;
  502. X}
  503. X#endif /* SOUT */
  504. X
  505. Xstruct Node *Head(l)
  506. X    struct List *l;
  507. X{
  508. X    if(!l)panic("Head(NULL)\n");
  509. X    return l->lh_Head->ln_Succ?l->lh_Head:0;
  510. X}
  511. Xstruct Node *Tail(l)
  512. X    struct List *l;
  513. X{
  514. X    if(!l)panic("Tail(NULL)\n");
  515. X    return (l->lh_TailPred==(NODE_P)l)?0:l->lh_TailPred;
  516. X}
  517. Xstruct Node *Next(n)
  518. X    struct Node *n;
  519. X{
  520. X    if(!n)printf("Warning: Next(NULL)\n");
  521. X    return n?(n->ln_Succ->ln_Succ?n->ln_Succ:0):0;
  522. X}
  523. Xstruct Node *Prev(n)
  524. X    struct Node *n;
  525. X{
  526. X    if(!n)printf("Warning: Prev(NULL)\n");
  527. X    return n?(n->ln_Pred->ln_Pred?n->ln_Pred:0):0;
  528. X}
  529. X
  530. Xstruct List *_fortemp;    /* scratch for foreach macro */
  531. X
  532. Xvoid
  533. Xdump_after_read(struct List *root){
  534. X    file *f;
  535. X    foreach(f,root,(file *)){
  536. X        punit *p;
  537. X        printf("FILE '%s'\n",f->name);
  538. X        foreach(p,&(f->punits),(punit *)){
  539. X        hunk *h;
  540. X        print_text_block("\tPUNIT %.*s\n",p->unit_header);
  541. X        if(p->libsize){
  542. X        printf("\tlibsize=%08x\n",p->libsize);
  543. X        } else {
  544. X        /* */
  545. X        }
  546. X        foreach(h,&(p->hunks),(hunk *)){
  547. X        print_text_block("\t\tHUNK %.*s",h->name);
  548. X        printf(" @%08x\n",h);
  549. X        print_bin_block(h->rb);
  550. X        printf("\t\t\tCode Reloc\n");
  551. X        printf("\t\t\tData Reloc\n");
  552. X        if(h->merge)printf("\t\t\tmerge(%08x)\n",h->merge);
  553. X        if(h->hunkstart)printf("\t\t\thunkstart\n");
  554. X        if(h->hunkchain)printf("\t\t\thunkchain\n");
  555. X        if(h->hunkgone)printf("\t\t\thunkgone\n");
  556. X        printf("\t\t\toverlay(%08x) hunknum(%08x) offset(%08x)\n",
  557. X          h->overlay,h->hunknum,h->hunkoffset);
  558. X        }
  559. X        }
  560. X    }
  561. X}
  562. X
  563. Xvoid
  564. Xprint_text_block(char *fmt,block *b){
  565. X    if(!b){
  566. X    printf(fmt,10,"(no block)");
  567. X    } else {
  568. X    if(b->sw){
  569. X        printf(fmt,13,"(swapped out)");
  570. X    } else {
  571. X        if(!(b->b[1]) || !*(char*)&(b->b[2])){
  572. X        printf(fmt,6,"(null)");
  573. X        } else {
  574. X        printf(fmt,b->b[1]*4,&(b->b[2]));
  575. X        }
  576. X    }
  577. X    }
  578. X}
  579. X
  580. Xvoid
  581. Xprint_bin_block(block *b){
  582. X    if(b->sw){
  583. X    printf("\t\t\t(swapped out)\n");
  584. X    } else {
  585. X    printf("\t\t\tid1=%08x id2=%08x len=%08x\n", b->id,b->b[0],b->b[1]);
  586. X    }
  587. X}
  588. X
  589. X/*
  590. X * read routines
  591. X */
  592. X
  593. X/*
  594. X * ReadSimpleBlock
  595. X * If the given id is recognized as a simple block (id, length, data),
  596. X * allocate and fill in a block structure.  Include the id in the block.
  597. X */
  598. Xblock *ReadSimpleBlock(f,id)
  599. X    file *f;
  600. X    long id;
  601. X{
  602. X    long len;
  603. X    long hid;
  604. X    block *b;
  605. X
  606. X    hid=id & 0x0fffffff;
  607. X    if(    hid !=HUNK_UNIT && hid != HUNK_NAME && hid != HUNK_CODE &&
  608. X        hid != HUNK_DATA && hid != HUNK_BSS && hid != HUNK_DEBUG
  609. X      ){
  610. X    printf("%08x\n",id);
  611. X    panic("ReadSImpleBlock");
  612. X    }
  613. X
  614. X    len=READLONG(EOF_BAD);
  615. X    b=NewBlock();
  616. X    b->id=id;
  617. X    b->sw=0;
  618. X    b->b=NewData((hid==HUNK_BSS)?2:len+2);
  619. X    b->b[0]=id;
  620. X    b->b[1]=len;
  621. X    if(hid != HUNK_BSS)read(f->fd,&(b->b[2]),len*4);
  622. X    return(b);
  623. X}
  624. X
  625. X/*
  626. X * TossSimpleBlock
  627. X * Skip past something we don't need.
  628. X */
  629. Xint TossSimpleBlock(f)
  630. X    file *f;
  631. X{
  632. X    long len=READLONG(EOF_BAD);
  633. X
  634. X    if(len)if( lseek(f->fd,len*4,1) == -1)panic("Toss failed\n");
  635. X    return(len);
  636. X}
  637. X
  638. X/*
  639. X * ReadHunk
  640. X * Read an entire hunk, building lists of each block type in the given hunk
  641. X * structure.  If we are listing, do the listing as we read so we can see
  642. X * where things die if we hit a type code we don't recognize.
  643. X */
  644. Xhunk *ReadHunk(f)
  645. X    file *f;
  646. X{
  647. X    long id;
  648. X    hunk *h=NewHunk();
  649. X
  650. X    while(1){
  651. X    id=READLONG(EOF_OK);
  652. X    switch(id & 0x0fffffff){    /* ignore memory type bits */
  653. X    case 0: return 0;        /* EOF - not good test */
  654. X    case HUNK_RELOC32:
  655. X        LIST{printf("Reloc32:\n");}
  656. X        ReadReloc(f,id,&h->reloc);break;
  657. X    case HUNK_CODE:
  658. X        h->rb=ReadSimpleBlock(f,id);
  659. X        LIST{printf("Code size %d\n",block_size(h->rb)*4);};
  660. X        break;
  661. X    case HUNK_DATA:
  662. X        h->rb=ReadSimpleBlock(f,id);
  663. X        LIST{printf("Data size %d\n",block_size(h->rb)*4);};
  664. X        break;
  665. X    case HUNK_BSS:
  666. X        h->rb=ReadSimpleBlock(f,id);
  667. X        LIST{printf("Bss size %d\n",block_size(h->rb)*4);};
  668. X        break;
  669. X    case HUNK_SYMBOL:
  670. X        while(TossSimpleBlock(f))READLONG(EOF_BAD);
  671. X        LIST{printf("Symbols skipped\n");};
  672. X        break;
  673. X    case HUNK_DEBUG:
  674. X        (void)TossSimpleBlock(f);
  675. X        LIST{printf("Debug hunk skipped\n");};
  676. X        break;
  677. X    case HUNK_END:    LIST{printf("End of hunk\n");};return h;
  678. X    case HUNK_BREAK:LIST{printf("End of overlay\n");};break;
  679. X    default:
  680. X            printf("Lost id=0x%x\n",id);exit(2);
  681. X    }
  682. X    }
  683. X    return 0;
  684. X}
  685. X
  686. X/*
  687. X * ReadReloc
  688. X * Read a relocation block and build a linked list of the sections.
  689. X * If we are listing, do that now.
  690. X */
  691. Xvoid ReadReloc(f,id,ls)
  692. X    file *f;
  693. X    long id;
  694. X    struct List *ls;
  695. X{
  696. X    long len;
  697. X    block *cur;
  698. X    listlist *blist=NewListList();
  699. X
  700. X    AddTail(ls,blist);
  701. X    blist->id=id;
  702. X    len=READLONG(EOF_BAD);
  703. X    while(len){
  704. X    cur=NewBlock();
  705. X    cur->b=NewData(len+2);
  706. X    read(f->fd,&(cur->b[1]),len*4+4);
  707. X    cur->b[0]=len;
  708. X    LIST{printf("\thunk #%d - %d items\n",cur->b[1],len);}
  709. X    AddTail(&blist->list,cur);
  710. X    len=READLONG(EOF_BAD);
  711. X    }
  712. X}
  713. X
  714. Xint rderror(){
  715. X    panic("read error\n");
  716. X    return 0;    /* just to make it quiet - NOTREACHED */
  717. X}
  718. X
  719. Xlong block_size(blk)
  720. X    block *blk;
  721. X{
  722. X    return(blk->b[1]);
  723. X}
  724. X
  725. X/* Allocation routines - if this was C++ then this code would be buried in the
  726. X * constructors.  Doing it this way means we can re-write the allocation later
  727. X * to allocate things we'll need lots of in larger blocks to avoid the time and
  728. X * space penalties of malloc. */
  729. Xfile *NewFile(fname)
  730. X    char *fname;
  731. X    {
  732. X    file *ret=calloc(sizeof(file),1);
  733. X
  734. X    NewList(&ret->punits);
  735. X    ret->name=strdup(fname);
  736. X    ret->fd= open(fname,O_RDONLY);
  737. X    return(ret);
  738. X}
  739. X
  740. Xpunit *NewPunit(){
  741. X    punit *ret=calloc(sizeof(punit),1);
  742. X    NewList(&ret->hunks);
  743. X    return(ret);
  744. X}
  745. X
  746. Xhunk *NewHunk(){
  747. X    hunk *ret=calloc(sizeof(hunk),1);
  748. X
  749. X    NewList(&ret->reloc);
  750. X    NewList(&ret->dreloc);
  751. X    NewList(&ret->extsym);
  752. X    ret->overlay=UNASSIGNED_HUNK;
  753. X    return(ret);
  754. X}
  755. X
  756. Xblock *NewBlock(){
  757. X    return calloc(sizeof(block),1);
  758. X}
  759. X
  760. Xlistlist *NewListList(){
  761. X    listlist *ret=calloc(sizeof(listlist),1);
  762. X
  763. X    NewList(&ret->list);
  764. X    return(ret);
  765. X}
  766. X
  767. Xlong *NewData(longs)
  768. X    long longs;    
  769. X    {
  770. X    return(malloc(longs*4));
  771. X}
  772. END_OF_FILE
  773. if test 15390 -ne `wc -c <'sys/amiga/splitter/splitter.c'`; then
  774.     echo shar: \"'sys/amiga/splitter/splitter.c'\" unpacked with wrong size!
  775. fi
  776. # end of 'sys/amiga/splitter/splitter.c'
  777. if test -f 'sys/amiga/winami.c' -a "${1}" != "-c" ; then 
  778.   echo shar: Renaming existing file \"'sys/amiga/winami.c'\" to \"'sys/amiga/winami.c.orig'\"
  779.   mv -f 'sys/amiga/winami.c' 'sys/amiga/winami.c.orig'
  780. fi
  781. echo shar: Extracting \"'sys/amiga/winami.c'\" \(31018 characters\)
  782. sed "s/^X//" >'sys/amiga/winami.c' <<'END_OF_FILE'
  783. X/*    SCCS Id: @(#)winami.c    3.1    93/04/02 */
  784. X/* Copyright (c) Gregg Wonderly, Naperville, Illinois,  1991,1992,1993. */
  785. X/* NetHack may be freely redistributed.  See license for details. */
  786. X
  787. X#include "amiga:windefs.h"
  788. X#include "amiga:winext.h"
  789. X#include "amiga:winproto.h"
  790. X
  791. X#ifdef AMIGA_INTUITION
  792. X
  793. X#ifdef    SHAREDLIB
  794. Xstruct DosLibrary *DOSBase;
  795. X#else
  796. Xstruct amii_DisplayDesc *amiIDisplay;    /* the Amiga Intuition descriptor */
  797. X#endif
  798. X
  799. Xint clipping = 0;
  800. Xint clipx=0;
  801. Xint clipy=0;
  802. Xint clipxmax=0;
  803. Xint clipymax=0;
  804. Xint scrollmsg = 1;
  805. Xint alwaysinvent = 0;
  806. X
  807. X#ifndef    SHAREDLIB
  808. X
  809. X/* Interface definition, for use by windows.c and winprocs.h to provide
  810. X * the intuition interface for the amiga...
  811. X */
  812. Xstruct window_procs amii_procs =
  813. X{
  814. X    "amii",
  815. X    amii_init_nhwindows,
  816. X    amii_player_selection,
  817. X    amii_askname,
  818. X    amii_get_nh_event,
  819. X    amii_exit_nhwindows,
  820. X    amii_suspend_nhwindows,
  821. X    amii_resume_nhwindows,
  822. X    amii_create_nhwindow,
  823. X    amii_clear_nhwindow,
  824. X    amii_display_nhwindow,
  825. X    amii_destroy_nhwindow,
  826. X    amii_curs,
  827. X    amii_putstr,
  828. X    amii_display_file,
  829. X    amii_start_menu,
  830. X    amii_add_menu,
  831. X    amii_end_menu,
  832. X    amii_select_menu,
  833. X    amii_update_inventory,
  834. X    amii_mark_synch,
  835. X    amii_wait_synch,
  836. X#ifdef CLIPPING
  837. X    amii_cliparound,
  838. X#endif
  839. X    amii_print_glyph,
  840. X    amii_raw_print,
  841. X    amii_raw_print_bold,
  842. X    amii_nhgetch,
  843. X    amii_nh_poskey,
  844. X    amii_bell,
  845. X    amii_doprev_message,
  846. X    amii_yn_function,
  847. X    amii_getlin,
  848. X#ifdef COM_COMPL
  849. X    amii_get_ext_cmd,
  850. X#endif /* COM_COMPL */
  851. X    amii_number_pad,
  852. X    amii_delay_output,
  853. X#ifdef CHANGE_COLOR    /* only a Mac option currently */
  854. X    amii_change_color,
  855. X    amii_get_color_string,
  856. X#endif
  857. X    /* other defs that really should go away (they're tty specific) */
  858. X    amii_delay_output,
  859. X    amii_delay_output,
  860. X    amii_outrip,
  861. X};
  862. X
  863. X/* The view window layout uses the same function names so we can use
  864. X * a shared library to allow the executable to be smaller.
  865. X */
  866. Xstruct window_procs amiv_procs =
  867. X{
  868. X    "amiv",
  869. X    amii_init_nhwindows,
  870. X    amii_player_selection,
  871. X    amii_askname,
  872. X    amii_get_nh_event,
  873. X    amii_exit_nhwindows,
  874. X    amii_suspend_nhwindows,
  875. X    amii_resume_nhwindows,
  876. X    amii_create_nhwindow,
  877. X    amii_clear_nhwindow,
  878. X    amii_display_nhwindow,
  879. X    amii_destroy_nhwindow,
  880. X    amii_curs,
  881. X    amii_putstr,
  882. X    amii_display_file,
  883. X    amii_start_menu,
  884. X    amii_add_menu,
  885. X    amii_end_menu,
  886. X    amii_select_menu,
  887. X    amii_update_inventory,
  888. X    amii_mark_synch,
  889. X    amii_wait_synch,
  890. X#ifdef CLIPPING
  891. X    amii_cliparound,
  892. X#endif
  893. X    amii_print_glyph,
  894. X    amii_raw_print,
  895. X    amii_raw_print_bold,
  896. X    amii_nhgetch,
  897. X    amii_nh_poskey,
  898. X    amii_bell,
  899. X    amii_doprev_message,
  900. X    amii_yn_function,
  901. X    amii_getlin,
  902. X#ifdef COM_COMPL
  903. X    amii_get_ext_cmd,
  904. X#endif /* COM_COMPL */
  905. X    amii_number_pad,
  906. X    amii_delay_output,
  907. X#ifdef CHANGE_COLOR    /* only a Mac option currently */
  908. X    amii_change_color,
  909. X    amii_get_color_string,
  910. X#endif
  911. X    /* other defs that really should go away (they're tty specific) */
  912. X    amii_delay_output,
  913. X    amii_delay_output,
  914. X    amii_outrip,
  915. X};
  916. X#endif
  917. X
  918. X#ifndef    SHAREDLIB
  919. Xunsigned short amii_initmap[ 1L << DEPTH ] =
  920. X{
  921. X    0x0000, /* color #0 */
  922. X    0x0FFF, /* color #1 */
  923. X    0x0830, /* color #2 */
  924. X    0x07ac, /* color #3 */
  925. X    0x0181, /* color #4 */
  926. X    0x0C06, /* color #5 */
  927. X    0x023E, /* color #6 */
  928. X    0x0c00  /* color #7 */
  929. X#ifdef    VIEWWINDOW
  930. X    0x0AAA,
  931. X    0x0fff,
  932. X    0x0444,
  933. X    0x0666,
  934. X    0x0888,
  935. X    0x0bbb,
  936. X    0x0ddd,
  937. X    0x0222,
  938. X#endif
  939. X};
  940. X#endif
  941. X
  942. Xstruct Rectangle lastinvent, lastmsg;
  943. X
  944. X#ifdef    SHAREDLIB
  945. XWinamiBASE *WinamiBase;
  946. X
  947. Xint
  948. X__UserLibInit( void )
  949. X{
  950. X    WinamiBase = (WinamiBASE *)getreg( REG_A6 );
  951. X    if ( (DOSBase = (struct DosLibrary *)
  952. X        OpenLibrary("dos.library", 0)) == NULL)
  953. X    {
  954. X    Abort(AG_OpenLib | AO_DOSLib);
  955. X    }
  956. X
  957. X    if ( (IntuitionBase = (struct IntuitionBase *)
  958. X        OpenLibrary("intuition.library", INTUITION_VERSION)) == NULL)
  959. X    {
  960. X    Abort(AG_OpenLib | AO_Intuition);
  961. X    }
  962. X
  963. X    if ( (GfxBase = (struct GfxBase *)
  964. X        OpenLibrary("graphics.library", GRAPHICS_VERSION)) == NULL)
  965. X    {
  966. X    Abort(AG_OpenLib | AO_GraphicsLib);
  967. X    }
  968. X
  969. X#ifdef    VIEWWINDOW
  970. X    if ( (LayersBase = (struct Library *)
  971. X        OpenLibrary("layers.library", 0)) == NULL)
  972. X    {
  973. X    Abort(AG_OpenLib | AO_LayersLib);
  974. X    }
  975. X#endif
  976. X
  977. X    return( 0 );
  978. X}
  979. X
  980. Xvoid
  981. X__UserLibCleanup( void )
  982. X{
  983. X    amii_cleanup();
  984. X}
  985. X
  986. Xchar _ProgramName[ 100 ] = "Nethack";
  987. Xlong __curdir;
  988. Xlong _WBenchMsg;
  989. Xint _OSERR;
  990. X#endif
  991. X
  992. X#ifndef TTY_GRAPHICS    /* this should be shared better */
  993. Xchar morc;  /* the character typed in response to a --more-- prompt */
  994. X#endif
  995. Xchar spaces[ 76 ] =
  996. X"                                                                           ";
  997. X
  998. X#ifndef    SHAREDLIB
  999. Xwinid WIN_BASE = WIN_ERR;
  1000. Xwinid amii_rawprwin = WIN_ERR;
  1001. X#endif
  1002. X
  1003. X#ifdef    VIEWWINDOW
  1004. Xwinid WIN_VIEW = WIN_ERR;
  1005. Xwinid WIN_VIEWBOX = WIN_ERR;
  1006. X#endif
  1007. X
  1008. X/* Changed later during window/screen opens... */
  1009. Xint txwidth = FONTWIDTH, txheight = FONTHEIGHT, txbaseline = FONTBASELINE;
  1010. X
  1011. X/* If a 240 or more row screen is in front when we start, this will be
  1012. X * set to 1, and the windows will be given borders to allow them to be
  1013. X * arranged differently.  The Message window may eventually get a scroller...
  1014. X */
  1015. X#ifndef    SHAREDLIB
  1016. Xint bigscreen = 0;
  1017. X#endif
  1018. X#ifdef    VIEWWINDOW
  1019. Xstruct BitMap amii_vbm;
  1020. X#endif
  1021. X
  1022. X/* This gadget data is replicated for menu/text windows... */
  1023. Xstruct PropInfo PropScroll = { AUTOKNOB|FREEVERT,
  1024. X                    0xffff,0xffff, 0xffff,0xffff, };
  1025. Xstruct Image Image1 = { 0,0, 7,102, 0, NULL, 0x0000,0x0000, NULL };
  1026. Xstruct Gadget MenuScroll = {
  1027. X    NULL, -15,10, 15,-19, GRELRIGHT|GRELHEIGHT,
  1028. X    RELVERIFY|FOLLOWMOUSE|RIGHTBORDER|GADGIMMEDIATE|RELVERIFY,
  1029. X    PROPGADGET, (APTR)&Image1, NULL, NULL, NULL, (APTR)&PropScroll,
  1030. X    1, NULL
  1031. X};
  1032. X
  1033. X/* This gadget is for the message window... */
  1034. Xstruct PropInfo MsgPropScroll = { AUTOKNOB|FREEVERT,
  1035. X                    0xffff,0xffff, 0xffff,0xffff, };
  1036. Xstruct Image MsgImage1 = { 0,0, 7,102, 0, NULL, 0x0000,0x0000, NULL };
  1037. Xstruct Gadget MsgScroll = {
  1038. X    NULL, -14,10, 13,-19, GRELRIGHT|GRELHEIGHT,
  1039. X    RELVERIFY|FOLLOWMOUSE|RIGHTBORDER|GADGIMMEDIATE|RELVERIFY,
  1040. X    PROPGADGET, (APTR)&MsgImage1, NULL, NULL, NULL, (APTR)&MsgPropScroll,
  1041. X    1, NULL
  1042. X};
  1043. X
  1044. Xint wincnt=0;   /* # of nh windows opened */
  1045. X
  1046. X/* We advertise a public screen to allow some people to do other things
  1047. X * while they are playing...  like compiling...
  1048. X */
  1049. X
  1050. X#ifdef  INTUI_NEW_LOOK
  1051. Xstruct TagItem tags[] =
  1052. X{
  1053. X    { WA_PubScreenName, (ULONG)"NetHack", },
  1054. X    { TAG_DONE, 0, },
  1055. X};
  1056. X#endif
  1057. X
  1058. X/*
  1059. X * The default dimensions and status values for each window type.  The
  1060. X * data here is generally changed in create_nhwindow(), so beware that
  1061. X * what you see here may not be exactly what you get.
  1062. X */
  1063. Xstruct win_setup new_wins[] =
  1064. X{
  1065. X
  1066. X    /* First entry not used, types are based at 1 */
  1067. X    {{0}},
  1068. X
  1069. X    /* NHW_MESSAGE */
  1070. X    {{0,1,640,11,0xff,0xff,
  1071. X    NEWSIZE|GADGETUP|GADGETDOWN|MOUSEMOVE|MOUSEBUTTONS|RAWKEY,
  1072. X    BORDERLESS|ACTIVATE|SMART_REFRESH
  1073. X#ifdef  INTUI_NEW_LOOK
  1074. X    |WFLG_NW_EXTENDED
  1075. X#endif
  1076. X    ,
  1077. X    NULL,NULL,(UBYTE*)"Messages",NULL,NULL,640,40,0xffff,0xffff,CUSTOMSCREEN,
  1078. X#ifdef  INTUI_NEW_LOOK
  1079. X    tags,
  1080. X#endif
  1081. X    },
  1082. X    0,0,1,1,80,80},
  1083. X
  1084. X    /* NHW_STATUS */
  1085. X    {{0,181,640,24,0xff,0xff, RAWKEY|MENUPICK|DISKINSERTED,
  1086. X    BORDERLESS|ACTIVATE|SMART_REFRESH
  1087. X#ifdef  INTUI_NEW_LOOK
  1088. X    |WFLG_NW_EXTENDED
  1089. X#endif
  1090. X    ,
  1091. X    NULL,NULL,(UBYTE*)"Game Status",NULL,NULL,-1,-1,0xffff,0xffff,CUSTOMSCREEN,
  1092. X#ifdef  INTUI_NEW_LOOK
  1093. X    tags,
  1094. X#endif
  1095. X    },
  1096. X    0,0,2,2,78,78},
  1097. X
  1098. X    /* NHW_MAP */
  1099. X    {{0,0,WIDTH,WINDOWHEIGHT,0xff,0xff,
  1100. X    RAWKEY|MENUPICK|MOUSEBUTTONS|ACTIVEWINDOW|MOUSEMOVE,
  1101. X    BORDERLESS|ACTIVATE|SMART_REFRESH|BACKDROP
  1102. X#ifdef  INTUI_NEW_LOOK
  1103. X    |WFLG_NW_EXTENDED
  1104. X#endif
  1105. X    ,
  1106. X    NULL,NULL,(UBYTE*)"Dungeon Map",NULL,NULL,-1,-1,0xffff,0xffff,CUSTOMSCREEN,
  1107. X#ifdef  INTUI_NEW_LOOK
  1108. X    tags,
  1109. X#endif
  1110. X    },
  1111. X    0,0,22,22,80,80},
  1112. X
  1113. X    /* NHW_MENU */
  1114. X    {{400,10,10,10,80,30,
  1115. X    RAWKEY|MENUPICK|DISKINSERTED|MOUSEMOVE|MOUSEBUTTONS|
  1116. X    GADGETUP|GADGETDOWN|CLOSEWINDOW|VANILLAKEY|NEWSIZE|INACTIVEWINDOW,
  1117. X    WINDOWSIZING|WINDOWCLOSE|WINDOWDRAG|ACTIVATE|SMART_REFRESH
  1118. X#ifdef  INTUI_NEW_LOOK
  1119. X    |WFLG_NW_EXTENDED
  1120. X#endif
  1121. X    ,
  1122. X    &MenuScroll,NULL,(UBYTE*)"Pick an Item",
  1123. X    NULL,NULL,-1,-1,0xffff,0xffff,CUSTOMSCREEN,
  1124. X#ifdef  INTUI_NEW_LOOK
  1125. X    tags,
  1126. X#endif
  1127. X    },
  1128. X    0,0,1,1,22,78},
  1129. X
  1130. X    /* NHW_TEXT */
  1131. X    {{0,0,640,200,0xff,0xff,
  1132. X    RAWKEY|MENUPICK|DISKINSERTED|MOUSEMOVE|
  1133. X    GADGETUP|CLOSEWINDOW|VANILLAKEY|NEWSIZE,
  1134. X    WINDOWSIZING|WINDOWCLOSE|WINDOWDRAG|ACTIVATE|SMART_REFRESH
  1135. X#ifdef  INTUI_NEW_LOOK
  1136. X    |WFLG_NW_EXTENDED
  1137. X#endif
  1138. X    ,
  1139. X    &MenuScroll,NULL,(UBYTE*)NULL,NULL,NULL,-1,-1,0xffff,0xffff,CUSTOMSCREEN,
  1140. X#ifdef  INTUI_NEW_LOOK
  1141. X    tags,
  1142. X#endif
  1143. X    },
  1144. X    0,0,1,1,22,78},
  1145. X
  1146. X    /* NHW_BASE */
  1147. X    {{0,0,WIDTH,WINDOWHEIGHT,0xff,0xff,
  1148. X    RAWKEY|MENUPICK|MOUSEBUTTONS,
  1149. X    BORDERLESS|ACTIVATE|SMART_REFRESH|BACKDROP
  1150. X#ifdef  INTUI_NEW_LOOK
  1151. X    |WFLG_NW_EXTENDED
  1152. X#endif
  1153. X    ,
  1154. X    NULL,NULL,(UBYTE*)NULL,NULL,NULL,-1,-1,0xffff,0xffff,CUSTOMSCREEN,
  1155. X#ifdef  INTUI_NEW_LOOK
  1156. X    tags,
  1157. X#endif
  1158. X    },
  1159. X    0,0,22,22,80,80},
  1160. X
  1161. X#ifdef    VIEWWINDOW
  1162. X    /* NHW_VIEW */
  1163. X    {{0,0,WIDTH,WINDOWHEIGHT,0xff,0xff,
  1164. X    RAWKEY|MENUPICK|MOUSEBUTTONS,
  1165. X    BORDERLESS|ACTIVATE|SMART_REFRESH
  1166. X#ifdef  INTUI_NEW_LOOK
  1167. X    |WFLG_NW_EXTENDED
  1168. X#endif
  1169. X    ,
  1170. X    NULL,NULL,(UBYTE*)NULL,NULL,NULL,-1,-1,0xffff,0xffff,CUSTOMSCREEN,
  1171. X#ifdef  INTUI_NEW_LOOK
  1172. X    tags,
  1173. X#endif
  1174. X    },
  1175. X    0,0,VIEWCHARWIDTH,VIEWCHARHEIGHT,VIEWCHARWIDTH,VIEWCHARHEIGHT},
  1176. X
  1177. X    /* NHW_VIEWBOX */
  1178. X    {{0,0,WIDTH,WINDOWHEIGHT,0xff,0xff,
  1179. X    RAWKEY|MENUPICK|MOUSEBUTTONS|REFRESHWINDOW,
  1180. X    WINDOWSIZING|WINDOWDRAG|ACTIVATE|SIMPLE_REFRESH
  1181. X#ifdef  INTUI_NEW_LOOK
  1182. X    |WFLG_NW_EXTENDED
  1183. X#endif
  1184. X    ,
  1185. X    NULL,NULL,(UBYTE*)NULL,NULL,NULL,-1,-1,0xffff,0xffff,CUSTOMSCREEN,
  1186. X#ifdef  INTUI_NEW_LOOK
  1187. X    tags,
  1188. X#endif
  1189. X    },
  1190. X    0,0,VIEWCHARWIDTH,VIEWCHARHEIGHT,VIEWCHARWIDTH,VIEWCHARHEIGHT},
  1191. X#endif
  1192. X};
  1193. X
  1194. Xconst char winpanicstr[] = "Bad winid %d in %s()";
  1195. X
  1196. X/* The opened windows information */
  1197. Xstruct amii_WinDesc *amii_wins[ MAXWIN + 1 ];
  1198. X
  1199. X#ifdef  INTUI_NEW_LOOK
  1200. XUWORD scrnpens[] =
  1201. X{
  1202. X#ifndef    VIEWWINDOW
  1203. X    C_BLACK,        /* DETAILPEN        */
  1204. X    C_BLUE,         /* BLOCKPEN         */
  1205. X    C_BROWN,        /* TEXTPEN          */
  1206. X    C_WHITE,        /* SHINEPEN         */
  1207. X    C_BLUE,        /* SHADOWPEN        */
  1208. X    C_CYAN,        /* FILLPEN          */
  1209. X    C_WHITE,        /* FILLTEXTPEN      */
  1210. X    C_CYAN,        /* BACKGROUNDPEN    */
  1211. X    C_RED,        /* HIGHLIGHTTEXTPEN */
  1212. X#else
  1213. X    C_BLACK,        /* DETAILPEN        */
  1214. X    C_BLUE,        /* BLOCKPEN         */
  1215. X    C_BROWN,        /* TEXTPEN          */
  1216. X    C_WHITE,        /* SHINEPEN         */
  1217. X    C_BLUE,        /* SHADOWPEN        */
  1218. X    C_CYAN,        /* FILLPEN          */
  1219. X    C_WHITE,        /* FILLTEXTPEN      */
  1220. X    C_CYAN,        /* BACKGROUNDPEN    */
  1221. X    C_RED,        /* HIGHLIGHTTEXTPEN */
  1222. X#endif
  1223. X};
  1224. X
  1225. Xstruct TagItem scrntags[] =
  1226. X{
  1227. X    { SA_PubName, (ULONG)"NetHack" },
  1228. X    { SA_Overscan, OSCAN_TEXT },
  1229. X    { SA_Pens, (ULONG)scrnpens },
  1230. X    { TAG_DONE, 0 },
  1231. X};
  1232. X#endif
  1233. X
  1234. Xstruct NewScreen NewHackScreen =
  1235. X{
  1236. X    0, 0, WIDTH, SCREENHEIGHT, DEPTH,
  1237. X    C_BROWN, C_BLUE,     /* DetailPen, BlockPen */
  1238. X    HIRES,
  1239. X    CUSTOMSCREEN
  1240. X#ifdef  INTUI_NEW_LOOK
  1241. X    |NS_EXTENDED
  1242. X#endif
  1243. X    ,
  1244. X    &Hack80,  /* Font */
  1245. X    NULL,     /*(UBYTE *)" NetHack X.Y.Z" */
  1246. X    NULL,     /* Gadgets */
  1247. X    NULL,     /* CustomBitmap */
  1248. X#ifdef  INTUI_NEW_LOOK
  1249. X    scrntags,
  1250. X#endif
  1251. X};
  1252. X
  1253. X/*
  1254. X * plname is filled either by an option (-u Player  or  -uPlayer) or
  1255. X * explicitly (by being the wizard) or by askname.
  1256. X * It may still contain a suffix denoting pl_character.
  1257. X * Always called after init_nhwindows() and before display_gamewindows().
  1258. X */
  1259. Xvoid
  1260. Xamii_askname()
  1261. X{
  1262. X    *plname = 0;
  1263. X    do {
  1264. X    getlin( "Who are you?", plname );
  1265. X    } while( strlen( plname ) == 0 );
  1266. X
  1267. X    if( *plname == '\33' )
  1268. X    {
  1269. X    clearlocks();
  1270. X    exit_nhwindows(NULL);
  1271. X    terminate(0);
  1272. X    }
  1273. X}
  1274. X
  1275. X#include "Amiga:char.c"
  1276. X
  1277. X/* Get the player selection character */
  1278. X
  1279. Xvoid
  1280. Xamii_player_selection()
  1281. X{
  1282. X    register struct Window *cwin;
  1283. X    register struct IntuiMessage *imsg;
  1284. X    register int aredone = 0;
  1285. X    register struct Gadget *gd;
  1286. X    static int once=0;
  1287. X    long class, code;
  1288. X
  1289. X    amii_clear_nhwindow( WIN_BASE );
  1290. X    if( *pl_character ){
  1291. X    pl_character[ 0 ] = toupper( pl_character[ 0 ] );
  1292. X    if( index( pl_classes, pl_character[ 0 ] ) )
  1293. X        return;
  1294. X    }
  1295. X
  1296. X    if( !once ){
  1297. X    if( bigscreen ){
  1298. X        Type_NewWindowStructure1.TopEdge =
  1299. X          (HackScreen->Height/2) - (Type_NewWindowStructure1.Height/2);
  1300. X    }
  1301. X    for( gd = Type_NewWindowStructure1.FirstGadget; gd;
  1302. X      gd = gd->NextGadget )
  1303. X    {
  1304. X        if( gd->GadgetID != 0 )
  1305. X        SetBorder( gd );
  1306. X    }
  1307. X    once = 1;
  1308. X    }
  1309. X
  1310. X    Type_NewWindowStructure1.Screen = HackScreen;
  1311. X    if( ( cwin = OpenShWindow( (void *)&Type_NewWindowStructure1 ) ) == NULL )
  1312. X    {
  1313. X    return;
  1314. X    }
  1315. X    WindowToFront( cwin );
  1316. X
  1317. X    while( !aredone )
  1318. X    {
  1319. X    WaitPort( cwin->UserPort );
  1320. X    while( ( imsg = (void *) GetMsg( cwin->UserPort ) ) != NULL )
  1321. X    {
  1322. X        class = imsg->Class;
  1323. X        code = imsg->Code;
  1324. X        gd = (struct Gadget *)imsg->IAddress;
  1325. X        ReplyMsg( (struct Message *)imsg );
  1326. X
  1327. X        switch( class )
  1328. X        {
  1329. X        case VANILLAKEY:
  1330. X        if( index( pl_classes, toupper( code ) ) )
  1331. X        {
  1332. X            pl_character[0] = toupper( code );
  1333. X            aredone = 1;
  1334. X        }
  1335. X        else if( code == ' ' || code == '\n' || code == '\r' )
  1336. X        {
  1337. X#ifdef  TOURIST
  1338. X            strcpy( pl_character, roles[ rnd( 11 ) ] );
  1339. X#else
  1340. X            strcpy( pl_character, roles[ rnd( 10 ) ] );
  1341. X#endif
  1342. X            aredone = 1;
  1343. X            amii_clear_nhwindow( WIN_BASE );
  1344. X            CloseShWindow( cwin );
  1345. X            RandomWindow( pl_character );
  1346. X            return;
  1347. X        }
  1348. X        else if( code == 'q' || code == 'Q' )
  1349. X        {
  1350. X        CloseShWindow( cwin );
  1351. X        clearlocks();
  1352. X        exit_nhwindows(NULL);
  1353. X        terminate(0);
  1354. X        }
  1355. X        else
  1356. X            DisplayBeep( NULL );
  1357. X        break;
  1358. X
  1359. X        case GADGETUP:
  1360. X        switch( gd->GadgetID )
  1361. X        {
  1362. X        case 1: /* Random Character */
  1363. X#ifdef  TOURIST
  1364. X            strcpy( pl_character, roles[ rnd( 11 ) ] );
  1365. X#else
  1366. X            strcpy( pl_character, roles[ rnd( 10 ) ] );
  1367. X#endif
  1368. X            amii_clear_nhwindow( WIN_BASE );
  1369. X            CloseShWindow( cwin );
  1370. X            RandomWindow( pl_character );
  1371. X            return;
  1372. X
  1373. X        default:
  1374. X            pl_character[0] = gd->GadgetID;
  1375. X            break;
  1376. X        }
  1377. X        aredone = 1;
  1378. X        break;
  1379. X
  1380. X        case CLOSEWINDOW:
  1381. X        CloseShWindow( cwin );
  1382. X        clearlocks();
  1383. X        exit_nhwindows(NULL);
  1384. X        terminate(0);
  1385. X        break;
  1386. X        }
  1387. X    }
  1388. X    }
  1389. X    amii_clear_nhwindow( WIN_BASE );
  1390. X    CloseShWindow( cwin );
  1391. X}
  1392. X
  1393. X#include "Amiga:randwin.c"
  1394. X
  1395. Xvoid
  1396. XRandomWindow( name )
  1397. X    char *name;
  1398. X{
  1399. X    struct MsgPort *tport;
  1400. X    struct timerequest *trq;
  1401. X    static int once = 0;
  1402. X    struct Gadget *gd;
  1403. X    struct Window *w;
  1404. X    struct IntuiMessage *imsg;
  1405. X    int ticks = 0, aredone = 0, timerdone = 0;
  1406. X    long mask, got;
  1407. X
  1408. X    tport = CreatePort( 0, 0 );
  1409. X    trq = (struct timerequest *)CreateExtIO( tport, sizeof( *trq ) );
  1410. X    if( tport == NULL || trq == NULL )
  1411. X    {
  1412. Xallocerr:
  1413. X    if( tport ) DeletePort( tport );
  1414. X    if( trq ) DeleteExtIO( (struct IORequest *)trq );
  1415. X    Delay( 8 * 50 );
  1416. X    return;
  1417. X    }
  1418. X
  1419. X    if( OpenDevice( TIMERNAME, UNIT_VBLANK, (struct IORequest *)trq, 0L ) != 0 )
  1420. X    goto allocerr;
  1421. X
  1422. X    trq->tr_node.io_Command = TR_ADDREQUEST;
  1423. X    trq->tr_time.tv_secs = 8;
  1424. X    trq->tr_time.tv_micro = 0;
  1425. X
  1426. X    SendIO( (struct IORequest *)trq );
  1427. X
  1428. X    /* Place the name in the center of the screen */
  1429. X    Rnd_IText5.IText = name;
  1430. X    Rnd_IText6.LeftEdge = Rnd_IText4.LeftEdge +
  1431. X        (strlen(Rnd_IText4.IText)+1)*8;
  1432. X    Rnd_NewWindowStructure1.Width = (
  1433. X        (strlen( Rnd_IText2.IText )+1) * 8 ) +
  1434. X        HackScreen->WBorLeft + HackScreen->WBorRight;
  1435. X    Rnd_IText5.LeftEdge = (Rnd_NewWindowStructure1.Width -
  1436. X        (strlen(name)*8))/2;
  1437. X
  1438. X    gd = Rnd_NewWindowStructure1.FirstGadget;
  1439. X    gd->LeftEdge = (Rnd_NewWindowStructure1.Width - gd->Width)/2;
  1440. X    /* Chose correct modifier */
  1441. X    Rnd_IText6.IText = "a";
  1442. X    switch( *name )
  1443. X    {
  1444. X    case 'a': case 'e': case 'i': case 'o':
  1445. X    case 'u': case 'A': case 'E': case 'I':
  1446. X    case 'O': case 'U':
  1447. X    Rnd_IText6.IText = "an";
  1448. X    break;
  1449. X    }
  1450. X
  1451. X    if( !once )
  1452. X    {
  1453. X    if( bigscreen )
  1454. X    {
  1455. X        Rnd_NewWindowStructure1.TopEdge =
  1456. X        (HackScreen->Height/2) - (Rnd_NewWindowStructure1.Height/2);
  1457. X    }
  1458. X    for( gd = Rnd_NewWindowStructure1.FirstGadget; gd; gd = gd->NextGadget )
  1459. X    {
  1460. X        if( gd->GadgetID != 0 )
  1461. X        SetBorder( gd );
  1462. X    }
  1463. X    Rnd_NewWindowStructure1.IDCMPFlags |= VANILLAKEY;
  1464. X
  1465. X    once = 1;
  1466. X    }
  1467. X
  1468. X    Rnd_NewWindowStructure1.Screen = HackScreen;
  1469. X    if( ( w = OpenShWindow( (void *)&Rnd_NewWindowStructure1 ) ) == NULL )
  1470. X    {
  1471. X    AbortIO( (struct IORequest *)trq );
  1472. X    WaitIO( (struct IORequest *)trq );
  1473. X    CloseDevice( (struct IORequest *)trq );
  1474. X    DeleteExtIO( (struct IORequest *) trq );
  1475. X    DeletePort( tport );
  1476. X    Delay( 50 * 8 );
  1477. X    return;
  1478. X    }
  1479. X
  1480. X    PrintIText( w->RPort, &Rnd_IntuiTextList1, 0, 0 );
  1481. X
  1482. X    mask = (1L << tport->mp_SigBit)|(1L << w->UserPort->mp_SigBit);
  1483. X    while( !aredone )
  1484. X    {
  1485. X    got = Wait( mask );
  1486. X    if( got & (1L << tport->mp_SigBit ) )
  1487. X    {
  1488. X        aredone = 1;
  1489. X        timerdone = 1;
  1490. X        GetMsg( tport );
  1491. X        }
  1492. X        while( w && ( imsg = (struct IntuiMessage *) GetMsg( w->UserPort ) ) )
  1493. X        {
  1494. X        switch( imsg->Class )
  1495. X        {
  1496. X        /* Must be up for a little while... */
  1497. X        case INACTIVEWINDOW:
  1498. X        if( ticks >= 40 )
  1499. X            aredone = 1;
  1500. X        break;
  1501. X
  1502. X        case INTUITICKS:
  1503. X        ++ticks;
  1504. X        break;
  1505. X
  1506. X        case GADGETUP:
  1507. X        aredone = 1;
  1508. X        break;
  1509. X
  1510. X        case VANILLAKEY:
  1511. X        if(imsg->Code=='\n' || imsg->Code==' ' || imsg->Code=='\r')
  1512. X            aredone = 1;
  1513. X        break;
  1514. X        }
  1515. X        ReplyMsg( (struct Message *)imsg );
  1516. X        }
  1517. X    }
  1518. X
  1519. X    if( !timerdone )
  1520. X    {
  1521. X    AbortIO( (struct IORequest *)trq );
  1522. X    WaitIO( (struct IORequest *)trq );
  1523. X    }
  1524. X
  1525. X    CloseDevice( (struct IORequest *)trq );
  1526. X    DeleteExtIO( (struct IORequest *) trq );
  1527. X    DeletePort( tport );
  1528. X    if(w) CloseShWindow( w );
  1529. X}
  1530. X
  1531. X/* this should probably not be needed (or be renamed)
  1532. Xvoid
  1533. Xflush_output(){} */
  1534. X
  1535. X#ifdef COM_COMPL
  1536. X/* Read in an extended command - doing command line completion for
  1537. X * when enough characters have been entered to make a unique command.
  1538. X */
  1539. Xvoid
  1540. Xamii_get_ext_cmd(bufp)
  1541. Xregister char *bufp;
  1542. X{
  1543. X    register char *obufp = bufp;
  1544. X    register int c;
  1545. X    int com_index, oindex;
  1546. X    struct amii_WinDesc *cw;
  1547. X    struct Window *w;
  1548. X    int colx;
  1549. X    int did_comp=0;    /* did successful completion? */
  1550. X    int bottom = 0;
  1551. X
  1552. X    if( WIN_MESSAGE == WIN_ERR || ( cw = amii_wins[ WIN_MESSAGE ] ) == NULL )
  1553. X    panic(winpanicstr, WIN_MESSAGE, "get_ext_cmd");
  1554. X    amii_clear_nhwindow( NHW_MESSAGE );
  1555. X    pline("# ");
  1556. X    colx = 3;
  1557. X    w = cw->win;
  1558. X
  1559. X    if( bigscreen )
  1560. X    {
  1561. X        bottom = w->Height - w->BorderTop - w->BorderBottom;
  1562. X        bottom /= w->RPort->TxHeight;
  1563. X        if( bottom > 0 )
  1564. X        --bottom;
  1565. X    }
  1566. X    while((c = WindowGetchar()) != EOF)
  1567. X    {
  1568. X    amii_curs( WIN_MESSAGE, colx, bottom );
  1569. X    if(c == '?' )
  1570. X    {
  1571. X        int win, i, sel;
  1572. X        char buf[ 100 ];
  1573. X
  1574. X        win = amii_create_nhwindow( NHW_MENU );
  1575. X        amii_start_menu( win );
  1576. X
  1577. X        for( i = 0; extcmdlist[ i ].ef_txt != NULL; ++i )
  1578. X        {
  1579. X        sprintf( buf, "%-10s - %s ",
  1580. X             extcmdlist[ i ].ef_txt,
  1581. X             extcmdlist[ i ].ef_desc );
  1582. X        amii_add_menu( win, extcmdlist[i].ef_txt[0], 0, buf );
  1583. X        }
  1584. X
  1585. X        amii_end_menu( win, i, "\33", NULL );
  1586. X        sel = amii_select_menu( win );
  1587. X        amii_destroy_nhwindow( win );
  1588. X
  1589. X        if( sel == '\33' || !sel )
  1590. X        {
  1591. X        *obufp = '\33';
  1592. X        obufp[ 1 ] = 0;
  1593. X        }
  1594. X        else
  1595. X        {
  1596. X        for( i = 0; extcmdlist[ i ].ef_txt != NULL; ++i )
  1597. X        {
  1598. X            if( sel == extcmdlist[i].ef_txt[0] )
  1599. X            break;
  1600. X        }
  1601. X
  1602. X        /* copy in the text */
  1603. X        amii_clear_nhwindow( WIN_MESSAGE );
  1604. X        strcpy( obufp, extcmdlist[ i ].ef_txt );
  1605. X        colx = 0;
  1606. X        pline( "# " );
  1607. X        pline( obufp );
  1608. X        bufp = obufp + 2;
  1609. X        }
  1610. X        return;
  1611. X    }
  1612. X    else if(c == '\033')
  1613. X    {
  1614. X        *obufp = c;
  1615. X        obufp[1] = 0;
  1616. X        return;
  1617. X    }
  1618. X    else if(c == '\b')
  1619. X    {
  1620. X        if(did_comp){
  1621. X        while(bufp!=obufp){
  1622. X            bufp--;
  1623. X            amii_curs(WIN_MESSAGE, --colx, bottom);
  1624. X            Text(w->RPort,spaces,1);
  1625. X            amii_curs(WIN_MESSAGE,colx,bottom);
  1626. X            did_comp=0;
  1627. X        }
  1628. X        }else
  1629. X        if(bufp != obufp)
  1630. X        {
  1631. X        bufp--;
  1632. X        amii_curs( WIN_MESSAGE, --colx, bottom);
  1633. X        Text( w->RPort, spaces, 1 );
  1634. X        amii_curs( WIN_MESSAGE, colx, bottom);
  1635. X        }
  1636. X        else
  1637. X        DisplayBeep( NULL );
  1638. X    }
  1639. X    else if( c == '\n' || c == '\r' )
  1640. X    {
  1641. X        *bufp = 0;
  1642. X        return;
  1643. X    }
  1644. X    else if(' ' <= c && c < '\177')
  1645. X    {
  1646. X        /* avoid isprint() - some people don't have it
  1647. X           ' ' is not always a printing char */
  1648. X        *bufp = c;
  1649. X        bufp[1] = 0;
  1650. X        oindex = 0;
  1651. X        com_index = -1;
  1652. X
  1653. X        while(extcmdlist[oindex].ef_txt != NULL)
  1654. X        {
  1655. X        if(!strnicmp(obufp, extcmdlist[oindex].ef_txt, strlen(obufp)))
  1656. X        {
  1657. X            if(com_index == -1) /* No matches yet*/
  1658. X            com_index = oindex;
  1659. X            else /* More than 1 match */
  1660. X            com_index = -2;
  1661. X        }
  1662. X        oindex++;
  1663. X        }
  1664. X
  1665. X        if(com_index >= 0 && *obufp )
  1666. X        {
  1667. X        Strcpy(obufp, extcmdlist[com_index].ef_txt);
  1668. X        /* finish printing our string */
  1669. X        Text( w->RPort, bufp, strlen( bufp ) );
  1670. X        amii_curs( WIN_MESSAGE, colx += strlen( bufp ), bottom);
  1671. X        bufp = obufp; /* reset it */
  1672. X        if(strlen(obufp) < BUFSZ-1 && strlen(obufp) < COLNO)
  1673. X            bufp += strlen(obufp);
  1674. X            did_comp=1;
  1675. X        }
  1676. X        else
  1677. X        {
  1678. X        Text( w->RPort, bufp, strlen( bufp ) );
  1679. X        amii_curs( WIN_MESSAGE, colx += strlen( bufp ), bottom);
  1680. X        if(bufp-obufp < BUFSZ-1 && bufp-obufp < COLNO)
  1681. X            bufp++;
  1682. X        }
  1683. X    }
  1684. X    else if(c == ('X'-64) || c == '\177')
  1685. X    {
  1686. X        colx = 0;
  1687. X        amii_clear_nhwindow( WIN_MESSAGE );
  1688. X        pline( "# " );
  1689. X        bufp = obufp;
  1690. X    } else
  1691. X        DisplayBeep( NULL );
  1692. X    }
  1693. X    *bufp = 0;
  1694. X    return;
  1695. X}
  1696. X#endif /* COM_COMPL */
  1697. X
  1698. X#ifdef WINDOW_YN
  1699. XSHORT Ask_BorderVectors1[] = { 0,0, 29,0, 29,11, 0,11, 0,0 };
  1700. Xstruct Border Ask_Border1 = { -1,-1, 3,0,JAM1, 5, Ask_BorderVectors1, NULL };
  1701. Xstruct IntuiText Ask_IText1 = { 3,0,JAM2, 2,1, NULL, "(?)", NULL };
  1702. X
  1703. Xstruct Gadget Ask_Gadget1 = {
  1704. X    NULL, 9,4, 28,10, NULL, RELVERIFY, BOOLGADGET, (APTR)&Ask_Border1,
  1705. X    NULL, &Ask_IText1, NULL, NULL, NULL, NULL
  1706. X};
  1707. X
  1708. X#define Ask_GadgetList1 Ask_Gadget1
  1709. X
  1710. Xstruct IntuiText Ask_IText2 = { 1,0,JAM2, 44,5, NULL, NULL, NULL };
  1711. X
  1712. X#define Ask_IntuiTextList1 Ask_IText2
  1713. X
  1714. Xstruct NewWindow Ask_Window = {
  1715. X    75,85, 524,18, 0,1, GADGETUP+VANILLAKEY, ACTIVATE+NOCAREREFRESH,
  1716. X    &Ask_Gadget1, NULL, NULL, NULL, NULL, 5,5, -1,-1, CUSTOMSCREEN
  1717. X};
  1718. X#endif
  1719. X
  1720. X/* Ask a question and get a response */
  1721. X
  1722. X#ifdef OLDCODE
  1723. X
  1724. Xchar amii_yn_function( prompt, resp, def )
  1725. X    const char *prompt,*resp;
  1726. X    char def;
  1727. X{
  1728. X    char ch;
  1729. X    char buf[ 80 ];
  1730. X
  1731. X    if( def && def!='q')
  1732. X    {
  1733. X    sprintf( buf, "%s [%c] ", prompt, def );
  1734. X    amii_addtopl( buf );
  1735. X    } else {
  1736. X    amii_addtopl( prompt );
  1737. X    }
  1738. X
  1739. X    cursor_on( WIN_MESSAGE );
  1740. X    do {
  1741. X    ch = WindowGetchar();
  1742. X    if( ch == '\33' )
  1743. X        break;
  1744. X    else if( def && ( ch == '\n' || ch == '\r' ) )
  1745. X    {
  1746. X        ch = def;
  1747. X        break;
  1748. X    }
  1749. X    else if( isdigit(ch) && index(resp, '#')){
  1750. X        
  1751. X    }
  1752. X    } while( resp && *resp && index( resp, ch ) == 0 );
  1753. X
  1754. X    cursor_off( WIN_MESSAGE );
  1755. X    if( ch == '\33' )
  1756. X    {
  1757. X    if(index(resp, 'q'))
  1758. X        ch = 'q';
  1759. X    else if(index(resp, 'n'))
  1760. X        ch = 'n';
  1761. X    else ch = def;
  1762. X    }
  1763. X    /* Try this to make topl behave more appropriately? */
  1764. X    clear_nhwindow( WIN_MESSAGE );
  1765. X    return( ch );
  1766. X}
  1767. X#else
  1768. Xchar amii_yn_function(query,resp, def)
  1769. Xconst char *query,*resp;
  1770. Xchar def;
  1771. X/*
  1772. X *   Generic yes/no function. 'def' is the default (returned by space or
  1773. X *   return; 'esc' returns 'q', or 'n', or the default, depending on
  1774. X *   what's in the string. The 'query' string is printed before the user
  1775. X *   is asked about the string.
  1776. X *   If resp is NULL, any single character is accepted and returned.
  1777. X */
  1778. X{
  1779. X    register char q;
  1780. X    char rtmp[40];
  1781. X    boolean digit_ok, allow_num;
  1782. X    char prompt[QBUFSZ];
  1783. X    register struct amii_WinDesc *cw;
  1784. X
  1785. X    if( cw = amii_wins[ WIN_MESSAGE ] )
  1786. X        cw->disprows = 0;
  1787. X    if(resp) {
  1788. X        allow_num = (index(resp, '#') != 0);
  1789. X        if(def)
  1790. X        Sprintf(prompt, "%s [%s] (%c) ", query, resp, def);
  1791. X        else
  1792. X        Sprintf(prompt, "%s [%s] ", query, resp);
  1793. X        amii_addtopl(prompt);
  1794. X    } else {
  1795. X        amii_addtopl(query);
  1796. X        cursor_on(WIN_MESSAGE);
  1797. X        q = WindowGetchar();
  1798. X        cursor_off(WIN_MESSAGE);
  1799. X#if 1
  1800. X        TOPL_NOSPACE;
  1801. X        *rtmp = q;
  1802. X        rtmp[ 1 ] = 0;
  1803. X        amii_putstr(WIN_MESSAGE,-1,rtmp);
  1804. X        TOPL_SPACE;
  1805. X#endif
  1806. X        goto clean_up;
  1807. X    }
  1808. X
  1809. X    do {    /* loop until we get valid input */
  1810. X        cursor_on(WIN_MESSAGE);
  1811. X        q = lowc(WindowGetchar());
  1812. X        cursor_off(WIN_MESSAGE);
  1813. X#if 0
  1814. X/* fix for PL2 */
  1815. X        if (q == '\020') { /* ctrl-P */
  1816. X        if(!doprev) (void) tty_doprev_message(); /* need two initially */
  1817. X        (void) tty_doprev_message();
  1818. X        q = (char)0;
  1819. X        doprev = 1;
  1820. X        continue;
  1821. X        } else if(doprev) {
  1822. X        tty_clear_nhwindow(WIN_MESSAGE);
  1823. X        cw->maxcol = cw->maxrow;
  1824. X        doprev = 0;
  1825. X        amii_addtopl(prompt);
  1826. X        continue;
  1827. X        }
  1828. X#endif
  1829. X        digit_ok = allow_num && isdigit(q);
  1830. X        if (q == '\033') {
  1831. X        if (index(resp, 'q'))
  1832. X            q = 'q';
  1833. X        else if (index(resp, 'n'))
  1834. X            q = 'n';
  1835. X        else
  1836. X            q = def;
  1837. X        break;
  1838. X        } else if (index(quitchars, q)) {
  1839. X        q = def;
  1840. X        break;
  1841. X        }
  1842. X        if (!index(resp, q) && !digit_ok) {
  1843. X        amii_bell();
  1844. X        q = (char)0;
  1845. X        } else if (q == '#' || digit_ok) {
  1846. X        char z, digit_string[2];
  1847. X        int n_len = 0;
  1848. X        long value = 0;
  1849. X        TOPL_NOSPACE;
  1850. X        amii_addtopl("#"),  n_len++;
  1851. X        TOPL_SPACE;
  1852. X        digit_string[1] = '\0';
  1853. X        if (q != '#') {
  1854. X            digit_string[0] = q;
  1855. X            TOPL_NOSPACE;
  1856. X            amii_addtopl(digit_string),  n_len++;
  1857. X            TOPL_SPACE;
  1858. X            value = q - '0';
  1859. X            q = '#';
  1860. X        }
  1861. X        do {    /* loop until we get a non-digit */
  1862. X            cursor_on(WIN_MESSAGE);
  1863. X            z = lowc(WindowGetchar());
  1864. X            cursor_off(WIN_MESSAGE);
  1865. X            if (isdigit(z)) {
  1866. X            value = (10 * value) + (z - '0');
  1867. X            if (value < 0) break;    /* overflow: try again */
  1868. X            digit_string[0] = z;
  1869. X            TOPL_NOSPACE;
  1870. X            amii_addtopl(digit_string),  n_len++;
  1871. X            TOPL_SPACE;
  1872. X            } else if (z == 'y' || index(quitchars, z)) {
  1873. X            if (z == '\033')  value = -1;    /* abort */
  1874. X            z = '\n';    /* break */
  1875. X            } else if ( z == '\b') {
  1876. X            if (n_len <= 1) { value = -1;  break; }
  1877. X            else { value /= 10;  removetopl(1),  n_len--; }
  1878. X            } else {
  1879. X            value = -1;    /* abort */
  1880. X            amii_bell();
  1881. X            break;
  1882. X            }
  1883. X        } while (z != '\n');
  1884. X        if (value > 0) yn_number = value;
  1885. X        else if (value == 0) q = 'n';        /* 0 => "no" */
  1886. X        else {    /* remove number from top line, then try again */
  1887. X            removetopl(n_len),  n_len = 0;
  1888. X            q = '\0';
  1889. X        }
  1890. X        }
  1891. X    } while(!q);
  1892. X
  1893. X    if (q != '#') {
  1894. X        Sprintf(rtmp, "%c", q);
  1895. X#if 0
  1896. X        amii_addtopl(rtmp);
  1897. X#else
  1898. X        TOPL_NOSPACE;
  1899. X        amii_putstr(WIN_MESSAGE,-1,rtmp);
  1900. X        TOPL_SPACE;
  1901. X#endif
  1902. X    }
  1903. X    clean_up:
  1904. X    cursor_off(WIN_MESSAGE);
  1905. X    clear_nhwindow(WIN_MESSAGE);
  1906. X    return q;
  1907. X}
  1908. X
  1909. X#endif
  1910. X
  1911. X
  1912. Xvoid
  1913. Xamii_display_file(fn, complain)
  1914. Xconst char *fn;
  1915. Xboolean complain;
  1916. X{
  1917. X    register struct amii_WinDesc *cw;
  1918. X    register int win;
  1919. X    register FILE *fp;
  1920. X    register char *t;
  1921. X    register char buf[ 200 ];
  1922. X
  1923. X    if( fn == NULL )
  1924. X    panic("NULL file name in display_file()");
  1925. X
  1926. X    if( ( fp = fopenp( fn, "r" ) ) == NULL )
  1927. X    {
  1928. X    if (complain) {
  1929. X        sprintf( buf, "Can't display %s: %s", fn,
  1930. X#ifdef  __SASC_60
  1931. X            __sys_errlist[ errno ]
  1932. X#else
  1933. X            sys_errlist[ errno ]
  1934. X#endif
  1935. X            );
  1936. X        amii_addtopl( buf );
  1937. X    }
  1938. X    return;
  1939. X    }
  1940. X    win = amii_create_nhwindow( NHW_TEXT );
  1941. X
  1942. X    /* Set window title to file name */
  1943. X    if( cw = amii_wins[ win ] )
  1944. X    cw->morestr = fn;
  1945. X
  1946. X    while( fgets( buf, sizeof( buf ), fp ) != NULL )
  1947. X    {
  1948. X    if( t = index( buf, '\n' ) )
  1949. X        *t = 0;
  1950. X    amii_putstr( win, 0, buf );
  1951. X    }
  1952. X    fclose( fp );
  1953. X
  1954. X    /* If there were lines in the file, display those lines */
  1955. X
  1956. X    if( amii_wins[ win ]->cury > 0 )
  1957. X    amii_display_nhwindow( win, TRUE );
  1958. X
  1959. X    amii_wins[win]->morestr = NULL;        /* don't free title string */
  1960. X    amii_destroy_nhwindow( win );
  1961. X}
  1962. X
  1963. X/* Put a 3-D motif border around the gadget.  String gadgets or those
  1964. X * which do not have highlighting are rendered down.  Boolean gadgets
  1965. X * are rendered in the up position by default.
  1966. X */
  1967. X
  1968. Xvoid
  1969. XSetBorder( gd )
  1970. X    register struct Gadget *gd;
  1971. X{
  1972. X    register struct Border *bp;
  1973. X    register short *sp;
  1974. X    register int i, inc = -1, dec = -1;
  1975. X    int borders = 6;
  1976. X
  1977. X    /* Allocate two border structures one for up image and one for down
  1978. X     * image, plus vector arrays for the border lines.
  1979. X     */
  1980. X
  1981. X    if( gd->GadgetType == STRGADGET )
  1982. X    borders = 12;
  1983. X
  1984. X    if( ( bp = (struct Border *)alloc( ( ( sizeof( struct Border ) * 2 ) +
  1985. X            ( sizeof( short ) * borders ) ) * 2 ) ) == NULL )
  1986. X    {
  1987. X    return;
  1988. X    }
  1989. X
  1990. X    /* For a string gadget, we expand the border beyond the area where
  1991. X     * the text will be entered.
  1992. X     */
  1993. X
  1994. X    /* Remove any special rendering flags to avoid confusing intuition
  1995. X     */
  1996. X
  1997. X    gd->Flags &= ~(GADGHIGHBITS|GADGIMAGE);
  1998. X
  1999. X    sp = (short *)(bp + 4);
  2000. X    if( gd->GadgetType == STRGADGET || ( gd->GadgetType == BOOLGADGET &&
  2001. X                ( gd->Flags & GADGHIGHBITS ) == GADGHNONE ) )
  2002. X    {
  2003. X    sp[0] = -1;
  2004. X    sp[1] = gd->Height - 1;
  2005. X    sp[2] = -1;
  2006. X    sp[3] = -1;
  2007. X    sp[4] = gd->Width - 1;
  2008. X    sp[5] = -1;
  2009. X
  2010. X    sp[6] = gd->Width + 1;
  2011. X    sp[7] = -2;
  2012. X    sp[8] = gd->Width + 1;
  2013. X    sp[9] = gd->Height + 1;
  2014. X    sp[10] = -2;
  2015. X    sp[11] = gd->Height + 1;
  2016. X
  2017. X    sp[12] = -2;
  2018. X    sp[13] = gd->Height;
  2019. X    sp[14] = -2;
  2020. X    sp[15] = -2;
  2021. X    sp[16] = gd->Width;
  2022. X    sp[17] = -2;
  2023. X    sp[18] = gd->Width;
  2024. X    sp[19] = gd->Height;
  2025. X    sp[20] = -2;
  2026. X    sp[21] = gd->Height;
  2027. X
  2028. X    for( i = 0; i < 3; ++i )
  2029. X    {
  2030. X        bp[ i ].LeftEdge = bp[ i ].TopEdge = -1;
  2031. X        bp[ i ].FrontPen = ( i == 0 || i == 1 ) ? C_BLUE : C_WHITE;
  2032. X
  2033. X        /* Have to use JAM2 so that the old colors disappear. */
  2034. X        bp[ i ].BackPen = C_BLACK;
  2035. X        bp[ i ].DrawMode = JAM2;
  2036. X        bp[ i ].Count = ( i == 0 || i == 1 ) ? 3 : 5;
  2037. X        bp[ i ].XY = &sp[ i*6 ];
  2038. X        bp[ i ].NextBorder = ( i == 2 ) ? NULL : &bp[ i + 1 ];
  2039. X    }
  2040. X
  2041. X    /* bp[0] and bp[1] two pieces for the up image */
  2042. X    gd->GadgetRender = (APTR) bp;
  2043. X
  2044. X    /* No image change for select */
  2045. X    gd->SelectRender = (APTR) bp;
  2046. X
  2047. X    gd->LeftEdge++;
  2048. X    gd->TopEdge++;
  2049. X    gd->Flags |= GADGHCOMP;
  2050. X    }
  2051. X    else
  2052. X    {
  2053. X    /* Create the border vector values for up and left side, and
  2054. X     * also the lower and right side.
  2055. X     */
  2056. X
  2057. X    sp[0] = dec;
  2058. X    sp[1] = gd->Height + inc;
  2059. X    sp[2] = dec;
  2060. X    sp[3] = dec;
  2061. X    sp[4] = gd->Width + inc;
  2062. X    sp[5] = dec;
  2063. X
  2064. X    sp[6] = gd->Width + inc;
  2065. X    sp[7] = dec;
  2066. X    sp[8] = gd->Width + inc;
  2067. X    sp[9] = gd->Height + inc;
  2068. X    sp[10] = dec;
  2069. X    sp[11] = gd->Height + inc;
  2070. X
  2071. X    /* We are creating 4 sets of borders, the two sides of the
  2072. X     * rectangle share the border vectors with the opposite image,
  2073. X     * but specify different colors.
  2074. X     */
  2075. X
  2076. X    for( i = 0; i < 4; ++i )
  2077. X    {
  2078. X        bp[ i ].TopEdge = bp[ i ].LeftEdge = 0;
  2079. X
  2080. X        /* A GADGHNONE is always down */
  2081. X
  2082. X        if( gd->GadgetType == BOOLGADGET &&
  2083. X                ( gd->Flags & GADGHIGHBITS ) != GADGHNONE )
  2084. X        {
  2085. X        bp[ i ].FrontPen =
  2086. X                ( i == 1 || i == 2 ) ? C_BLUE : C_WHITE;
  2087. X        }
  2088. X        else
  2089. X        {
  2090. X        bp[ i ].FrontPen =
  2091. X                ( i == 1 || i == 3 ) ? C_WHITE : C_BLUE;
  2092. X        }
  2093. X
  2094. X        /* Have to use JAM2 so that the old colors disappear. */
  2095. X        bp[ i ].BackPen = C_BLACK;
  2096. X        bp[ i ].DrawMode = JAM2;
  2097. X        bp[ i ].Count = 3;
  2098. X        bp[ i ].XY = &sp[ 6 * ((i &1) != 0) ];
  2099. X        bp[ i ].NextBorder =
  2100. X                ( i == 1 || i == 3 ) ? NULL : &bp[ i + 1 ];
  2101. X    }
  2102. X
  2103. X    /* bp[0] and bp[1] two pieces for the up image */
  2104. X    gd->GadgetRender = (APTR) bp;
  2105. X
  2106. X    /* bp[2] and bp[3] two pieces for the down image */
  2107. X    gd->SelectRender = (APTR) (bp + 2);
  2108. X    gd->Flags |= GADGHIMAGE;
  2109. X    }
  2110. X}
  2111. X
  2112. X#ifndef    SHAREDLIB
  2113. X#if 0
  2114. Xvoid *
  2115. Xmalloc( register unsigned size )
  2116. X{
  2117. X    register long *p;
  2118. X
  2119. X    size += 4;
  2120. X    p = AllocMem( size, MEMF_PUBLIC );
  2121. X    if( p ) *p++ = size;
  2122. X    else panic( "No memory left" );
  2123. X    return( p );
  2124. X}
  2125. X
  2126. Xvoid
  2127. Xfree( void *q )
  2128. X{
  2129. X    register long *p = q;
  2130. X
  2131. X    if( !q )
  2132. X    panic( "free of NULL pointer" );
  2133. X    FreeMem( p-1, p[-1] );
  2134. X}
  2135. X#endif
  2136. X#endif
  2137. END_OF_FILE
  2138. if test 31018 -ne `wc -c <'sys/amiga/winami.c'`; then
  2139.     echo shar: \"'sys/amiga/winami.c'\" unpacked with wrong size!
  2140. fi
  2141. # end of 'sys/amiga/winami.c'
  2142. if test -f 'sys/share/pcsys.c' -a "${1}" != "-c" ; then 
  2143.   echo shar: Renaming existing file \"'sys/share/pcsys.c'\" to \"'sys/share/pcsys.c.orig'\"
  2144.   mv -f 'sys/share/pcsys.c' 'sys/share/pcsys.c.orig'
  2145. fi
  2146. echo shar: Extracting \"'sys/share/pcsys.c'\" \(9317 characters\)
  2147. sed "s/^X//" >'sys/share/pcsys.c' <<'END_OF_FILE'
  2148. X/*    SCCS Id: @(#)pcsys.c    3.1    93/05/24
  2149. X/* NetHack may be freely redistributed.  See license for details. */
  2150. X
  2151. X/*
  2152. X *  System related functions for MSDOS, OS/2, TOS, and Windows NT
  2153. X */
  2154. X
  2155. X#define NEED_VARARGS
  2156. X#include "hack.h"
  2157. X#include "wintty.h"
  2158. X
  2159. X#include <ctype.h>
  2160. X#include <fcntl.h>
  2161. X#ifndef __GO32__
  2162. X#include <process.h>
  2163. X#else
  2164. X#define P_WAIT          0
  2165. X#define P_NOWAIT        1
  2166. X#endif
  2167. X#ifdef TOS
  2168. X#include <osbind.h>
  2169. X#endif
  2170. X
  2171. X#ifdef MOVERLAY
  2172. Xextern void __far __cdecl _movepause( void );
  2173. Xextern void __far __cdecl _moveresume( void );
  2174. Xextern unsigned short __far __cdecl _movefpause;
  2175. Xextern unsigned short __far __cdecl _movefpaused;
  2176. X#define     __MOVE_PAUSE_DISK     2   /* Represents the executable file */
  2177. X#define     __MOVE_PAUSE_CACHE    4   /* Represents the cache memory */
  2178. X#endif /* MOVERLAY */
  2179. X
  2180. Xstatic boolean NDECL(record_exists);
  2181. X#ifndef TOS
  2182. Xstatic boolean NDECL(comspec_exists);
  2183. X#endif
  2184. X
  2185. X#ifdef WIN32CON
  2186. Xextern int ProgmanLaunched;    /* from nttty.c */
  2187. X#endif
  2188. X
  2189. X#ifdef MICRO
  2190. X
  2191. Xvoid
  2192. Xflushout()
  2193. X{
  2194. X    (void) fflush(stdout);
  2195. X    return;
  2196. X}
  2197. X
  2198. Xstatic const char *COMSPEC = 
  2199. X# ifdef TOS
  2200. X"SHELL";
  2201. X# else
  2202. X"COMSPEC";
  2203. X# endif
  2204. X
  2205. X#define getcomspec() getenv(COMSPEC)
  2206. X
  2207. X# ifdef SHELL
  2208. Xint
  2209. Xdosh()
  2210. X{
  2211. X    extern char orgdir[];
  2212. X    char *comspec;
  2213. X     int spawnstat;
  2214. X
  2215. X    if (comspec = getcomspec()) {
  2216. X#  ifndef TOS    /* TOS has a variety of shells */
  2217. X        suspend_nhwindows("To return to NetHack, enter \"exit\" at the system prompt.\n");
  2218. X#  else
  2219. X        suspend_nhwindows((char *)0);
  2220. X#  endif /* TOS */
  2221. X        chdirx(orgdir, 0);
  2222. X#  ifdef __GO32__
  2223. X        if (system(comspec) < 0) {  /* wsu@eecs.umich.edu */
  2224. X#  else
  2225. X#   ifdef MOVERLAY          
  2226. X       /* Free the cache memory used by overlays, close .exe */ 
  2227. X    _movefpause |= __MOVE_PAUSE_DISK;
  2228. X    _movefpause |= __MOVE_PAUSE_CACHE;
  2229. X    _movepause();
  2230. X#   endif
  2231. X         spawnstat = spawnl(P_WAIT, comspec, comspec, NULL);
  2232. X#   ifdef MOVERLAY
  2233. X                 _moveresume();
  2234. X#   endif
  2235. X         if ( spawnstat < 0) {
  2236. X#  endif
  2237. X            raw_printf("Can't spawn \"%s\"!", comspec);
  2238. X            getreturn("to continue");
  2239. X        }
  2240. X#  ifdef TOS
  2241. X/* Some shells (e.g. Gulam) turn the cursor off when they exit */
  2242. X        if (flags.BIOS)
  2243. X            (void)Cursconf(1, -1);
  2244. X#  endif
  2245. X        get_scr_size(); /* maybe the screen mode changed (TH) */
  2246. X        resume_nhwindows();
  2247. X        chdirx(hackdir, 0);
  2248. X    } else
  2249. X        pline("Can't find %s.",COMSPEC);
  2250. X    return 0;
  2251. X}
  2252. X# endif /* SHELL */
  2253. X
  2254. X# ifdef MFLOPPY
  2255. X
  2256. Xvoid
  2257. Xeraseall(path, files)
  2258. Xconst char *path, *files;
  2259. X{
  2260. X    char buf[PATHLEN];
  2261. X    char *foundfile;
  2262. X
  2263. X    foundfile = foundfile_buffer(); 
  2264. X        Sprintf(buf, "%s%s", path, files);
  2265. X    if (findfirst(buf))
  2266. X        do {
  2267. X               Sprintf(buf, "%s%s", path, foundfile); 
  2268. X        (void) unlink(buf);
  2269. X        } while (findnext());
  2270. X    return;
  2271. X}
  2272. X
  2273. X/*
  2274. X * Rewritten for version 3.3 to be faster
  2275. X */
  2276. Xvoid
  2277. Xcopybones(mode)
  2278. Xint mode;
  2279. X{
  2280. X    char from[PATHLEN], to[PATHLEN], last[13];
  2281. X    char *frompath, *topath;
  2282. X    char *foundfile;
  2283. X#  ifndef TOS
  2284. X    int status;
  2285. X    char copy[8], *comspec;
  2286. X#  endif
  2287. X
  2288. X    if (!ramdisk)
  2289. X        return;
  2290. X
  2291. X    /* Find the name of the last file to be transferred
  2292. X     */
  2293. X    frompath = (mode != TOPERM) ? permbones : levels;
  2294. X    foundfile = foundfile_buffer();
  2295. X    last[0] = '\0';
  2296. X    Sprintf(from, "%s%s", frompath, allbones);
  2297. X    topath = (mode == TOPERM) ? permbones : levels;
  2298. X#  ifdef TOS
  2299. X    eraseall(topath, allbones);
  2300. X#  endif
  2301. X    if (findfirst(from))
  2302. X        do {
  2303. X#  ifdef TOS
  2304. X            Sprintf(from, "%s%s", frompath, foundfile); 
  2305. X            Sprintf(to, "%s%s", topath, foundfile);
  2306. X            if (_copyfile(from, to))
  2307. X                goto error_copying;
  2308. X#  endif
  2309. X            Strcpy(last, foundfile);
  2310. X        } while (findnext());
  2311. X#  ifdef TOS
  2312. X    else
  2313. X        return;
  2314. X#  else
  2315. X    if (last[0]) {
  2316. X        Sprintf(copy, "%cC copy",switchar());
  2317. X
  2318. X        /* Remove any bones files in `to' directory.
  2319. X         */
  2320. X        eraseall(topath, allbones);
  2321. X
  2322. X        /* Copy `from' to `to' */
  2323. X        Sprintf(to, "%s%s", topath, allbones);
  2324. X        comspec = getcomspec();
  2325. X        status =spawnl(P_WAIT, comspec, comspec, copy, from,
  2326. X            to, "> nul", NULL);
  2327. X    } else
  2328. X        return;
  2329. X#  endif /* TOS */
  2330. X
  2331. X    /* See if the last file got there.  If so, remove the ramdisk bones
  2332. X     * files.
  2333. X     */
  2334. X    Sprintf(to, "%s%s", topath, last);
  2335. X    if (findfirst(to)) {
  2336. X        if (mode == TOPERM)
  2337. X            eraseall(frompath, allbones);
  2338. X        return;
  2339. X    }
  2340. X
  2341. X#  ifdef TOS
  2342. Xerror_copying:
  2343. X#  endif
  2344. X    /* Last file didn't get there.
  2345. X     */
  2346. X    Sprintf(to, "%s%s", topath, allbones);
  2347. X    msmsg("Can't copy \"%s\" to \"%s\" -- ", from, to);
  2348. X#  ifndef TOS
  2349. X    if (status < 0)
  2350. X        msmsg("can't spawn \"%s\"!", comspec);
  2351. X    else
  2352. X#  endif
  2353. X        msmsg((freediskspace(topath) < filesize(from)) ?
  2354. X            "insufficient disk space." : "bad path(s)?");
  2355. X    if (mode == TOPERM) {
  2356. X        msmsg("Bones will be left in \"%s\"\n",
  2357. X            *levels ? levels : hackdir);
  2358. X    } else {
  2359. X        /* Remove all bones files on the RAMdisk */
  2360. X        eraseall(levels, allbones);
  2361. X        playwoRAMdisk();
  2362. X    }
  2363. X    return;
  2364. X}
  2365. X
  2366. Xvoid
  2367. XplaywoRAMdisk()
  2368. X{
  2369. X    int c;
  2370. X
  2371. X    msmsg("Do you wish to play without a RAMdisk? [yn] (n)");
  2372. X
  2373. X    /* Set ramdisk false *before* exit-ing (because msexit calls
  2374. X     * copybones)
  2375. X     */
  2376. X    ramdisk = FALSE;
  2377. X    c = tgetch(); if (c == 'Y') c = 'y';
  2378. X    if (c != 'y') {
  2379. X        settty("Be seeing you...\n");
  2380. X        exit(0);
  2381. X    }
  2382. X    set_lock_and_bones();
  2383. X    return;
  2384. X}
  2385. X
  2386. Xint
  2387. XsaveDiskPrompt(start)
  2388. Xint start;
  2389. X{
  2390. X    char buf[BUFSIZ], *bp;
  2391. X    char qbuf[QBUFSZ];
  2392. X
  2393. X    int fd;
  2394. X
  2395. X    if (flags.asksavedisk) {
  2396. X        /* Don't prompt if you can find the save file */
  2397. X        if ((fd = open_savefile()) >= 0) {
  2398. X            (void) close(fd);
  2399. X            return 1;
  2400. X        }
  2401. X        clear_nhwindow(WIN_MESSAGE);
  2402. X        pline("If save file is on a save disk, insert that disk now.");
  2403. X        mark_synch();
  2404. X        Sprintf(qbuf,"File name (default \"%s\"%s) ?", SAVEF,
  2405. X            start ? "" : ", <Esc> cancels save");
  2406. X        getlin(qbuf, buf);
  2407. X        clear_nhwindow(WIN_MESSAGE);
  2408. X        if (!start && *buf == '\033')
  2409. X            return 0;
  2410. X
  2411. X        /* Strip any whitespace. Also, if nothing was entered except
  2412. X         * whitespace, do not change the value of SAVEF.
  2413. X         */
  2414. X        for (bp = buf; *bp; bp++)
  2415. X            if (!isspace(*bp)) {
  2416. X                strncpy(SAVEF, bp, PATHLEN);
  2417. X                break;
  2418. X            }
  2419. X    }
  2420. X    return 1;
  2421. X}
  2422. X
  2423. X# endif /* MFLOPPY */
  2424. X
  2425. X/* Return 1 if the record file was found */
  2426. Xstatic boolean
  2427. Xrecord_exists()
  2428. X{
  2429. X    FILE *fp;
  2430. X
  2431. X    fp = fopen_datafile(RECORD, "r");
  2432. X    if (fp) {
  2433. X        fclose(fp);
  2434. X        return TRUE;
  2435. X    }
  2436. X    return FALSE;
  2437. X}
  2438. X
  2439. X# ifdef TOS
  2440. X#define comspec_exists() 1
  2441. X# else
  2442. X/* Return 1 if the comspec was found */
  2443. Xstatic boolean
  2444. Xcomspec_exists()
  2445. X{
  2446. X    int fd;
  2447. X    char *comspec;
  2448. X
  2449. X    if (comspec = getcomspec())
  2450. X        if ((fd = open(comspec, O_RDONLY)) >= 0) {
  2451. X            (void) close(fd);
  2452. X            return TRUE;
  2453. X        }
  2454. X    return FALSE;
  2455. X}
  2456. X# endif
  2457. X
  2458. X# ifdef MFLOPPY
  2459. X/* Prompt for game disk, then check for record file.
  2460. X */
  2461. Xvoid
  2462. XgameDiskPrompt()
  2463. X{
  2464. X    if (flags.asksavedisk) {
  2465. X        if (record_exists() && comspec_exists())
  2466. X            return;
  2467. X        (void) putchar('\n');
  2468. X        getreturn("when the game disk has been inserted");
  2469. X    }
  2470. X    if (comspec_exists() && record_exists())
  2471. X        return;
  2472. X
  2473. X    if (!comspec_exists())
  2474. X        msmsg("\n\nWARNING: can't find command processor \"%s\"!\n", getcomspec());
  2475. X        if (!record_exists())
  2476. X        msmsg("\n\nWARNING: can't find record file \"%s\"!\n", RECORD);
  2477. X    msmsg("If the game disk is not in, insert it now.\n");
  2478. X    getreturn("to continue");
  2479. X    return;
  2480. X}
  2481. X# endif /* MFLOPPY */
  2482. X#endif /* MICRO */
  2483. X
  2484. X/*
  2485. X * Add a backslash to any name not ending in /, \ or :   There must
  2486. X * be room for the \
  2487. X */
  2488. Xvoid
  2489. Xappend_slash(name)
  2490. Xchar *name;
  2491. X{
  2492. X    char *ptr;
  2493. X
  2494. X    if (!*name)
  2495. X        return;
  2496. X    ptr = name + (strlen(name) - 1);
  2497. X    if (*ptr != '\\' && *ptr != '/' && *ptr != ':') {
  2498. X        *++ptr = '\\';
  2499. X        *++ptr = '\0';
  2500. X    }
  2501. X    return;
  2502. X}
  2503. X
  2504. Xvoid
  2505. Xgetreturn(str)
  2506. Xconst char *str;
  2507. X{
  2508. X#ifdef TOS
  2509. X    msmsg("Hit <Return> %s.", str);
  2510. X#else
  2511. X    msmsg("Hit <Enter> %s.", str);
  2512. X#endif
  2513. X    while (Getchar() != '\n') ;
  2514. X    return;
  2515. X}
  2516. X
  2517. Xvoid
  2518. Xmsmsg VA_DECL(const char *, fmt)
  2519. X    VA_START(fmt);
  2520. X    VA_INIT(fmt, const char *);
  2521. X    Vprintf(fmt, VA_ARGS);
  2522. X    flushout();
  2523. X    VA_END();
  2524. X    return;
  2525. X}
  2526. X
  2527. X/*
  2528. X * Follow the PATH, trying to fopen the file.
  2529. X */
  2530. X#ifdef TOS
  2531. X# ifdef __MINT__
  2532. X#define PATHSEP ':'
  2533. X# else
  2534. X#define PATHSEP    ','
  2535. X# endif
  2536. X#else
  2537. X#define PATHSEP    ';'
  2538. X#endif
  2539. X
  2540. XFILE *
  2541. Xfopenp(name, mode)
  2542. Xconst char *name, *mode;
  2543. X{
  2544. X    char buf[BUFSIZ], *bp, *pp, lastch = 0;
  2545. X    FILE *fp;
  2546. X
  2547. X    /* Try the default directory first.  Then look along PATH.
  2548. X     */
  2549. X    Strcpy(buf, name);
  2550. X    if (fp = fopen(buf, mode))
  2551. X        return fp;
  2552. X    else {
  2553. X        pp = getenv("PATH");
  2554. X        while (pp && *pp) {
  2555. X            bp = buf;
  2556. X            while (*pp && *pp != PATHSEP)
  2557. X                lastch = *bp++ = *pp++;
  2558. X            if (lastch != '\\' && lastch != '/')
  2559. X                *bp++ = '\\';
  2560. X            Strcpy(bp, name);
  2561. X            if (fp = fopen(buf, mode))
  2562. X                return fp;
  2563. X            if (*pp)
  2564. X                pp++;
  2565. X        }
  2566. X    }
  2567. X#ifdef OS2_CODEVIEW /* one more try for hackdir */
  2568. X    Strcpy(buf,hackdir);
  2569. X    append_slash(buf);
  2570. X    Strcat(buf,name);
  2571. X    if(fp = fopen(buf,mode))
  2572. X        return fp;
  2573. X#endif
  2574. X    return (FILE *)0;
  2575. X}
  2576. X
  2577. X/* Chdir back to original directory
  2578. X */
  2579. X#undef exit
  2580. X#ifdef TOS
  2581. Xextern boolean run_from_desktop;    /* set in pcmain.c */
  2582. X#endif
  2583. X
  2584. Xvoid exit(int);
  2585. X
  2586. Xvoid
  2587. Xmsexit(code)
  2588. Xint code;
  2589. X{
  2590. X#ifdef CHDIR
  2591. X    extern char orgdir[];
  2592. X#endif
  2593. X
  2594. X    flushout();
  2595. X#ifndef TOS
  2596. X# ifndef WIN32
  2597. X    enable_ctrlP();        /* in case this wasn't done */
  2598. X# endif
  2599. X#endif
  2600. X#ifdef MFLOPPY
  2601. X    if (ramdisk) copybones(TOPERM);
  2602. X#endif
  2603. X#ifdef CHDIR
  2604. X    chdir(orgdir);        /* chdir, not chdirx */
  2605. X    chdrive(orgdir);
  2606. X#endif
  2607. X#ifdef TOS
  2608. X    if (run_from_desktop)
  2609. X        getreturn("to continue"); /* so the user can read the score list */
  2610. X# ifdef TEXTCOLOR
  2611. X    if (colors_changed)
  2612. X        restore_colors();
  2613. X# endif
  2614. X#endif
  2615. X#ifdef WIN32CON
  2616. X    /* Only if we started from Progman, not command prompt,
  2617. X     * we need to get one last return, so the score board does
  2618. X     * not vanish instantly after being created.
  2619. X     * ProgmanLaunched is defined and set in nttty.c.
  2620. X         */
  2621. X     
  2622. X    if (ProgmanLaunched) getreturn("to end");
  2623. X#endif
  2624. X    exit(code);
  2625. X    return;
  2626. X}
  2627. X
  2628. END_OF_FILE
  2629. if test 9317 -ne `wc -c <'sys/share/pcsys.c'`; then
  2630.     echo shar: \"'sys/share/pcsys.c'\" unpacked with wrong size!
  2631. fi
  2632. # end of 'sys/share/pcsys.c'
  2633. echo shar: End of archive 28 \(of 33\).
  2634. cp /dev/null ark28isdone
  2635. MISSING=""
  2636. 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
  2637.     if test ! -f ark${I}isdone ; then
  2638.     MISSING="${MISSING} ${I}"
  2639.     fi
  2640. done
  2641. if test "${MISSING}" = "" ; then
  2642.     echo You have unpacked all 33 archives.
  2643.     echo "Now execute ./patchit.sh"
  2644.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2645. else
  2646.     echo You still need to unpack the following archives:
  2647.     echo "        " ${MISSING}
  2648. fi
  2649. ##  End of shell archive.
  2650. exit 0
  2651.