1 /* NetHack 3.6	winreq.c	$NHDT-Date: 1432512796 2015/05/25 00:13:16 $  $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ */
2 /* Copyright (c) Gregg Wonderly, Naperville, Illinois,  1991,1992,1993. */
3 /* NetHack may be freely redistributed.  See license for details. */
4 
5 #include "NH:sys/amiga/windefs.h"
6 #include "NH:sys/amiga/winext.h"
7 #include "NH:sys/amiga/winproto.h"
8 
9 #define GADBLUEPEN 2
10 #define GADREDPEN 3
11 #define GADGREENPEN 4
12 #define GADCOLOKAY 5
13 #define GADCOLCANCEL 6
14 #define GADCOLSAVE 7
15 
16 UBYTE UNDOBUFFER[300];
17 SHORT BorderVectors1[] = { 0, 0, 57, 0, 57, 11, 0, 11, 0, 0 };
18 struct Border Border1 = { -1, -1, 3, 0, JAM1, 5, BorderVectors1, NULL };
19 struct IntuiText IText1 = { 3, 0, JAM1, 4, 1, NULL, (UBYTE *) "Cancel",
20                             NULL };
21 struct Gadget Gadget2 = { NULL, 9, 15, 56, 10, NULL, RELVERIFY, BOOLGADGET,
22                           (APTR) &Border1, NULL, &IText1, NULL, NULL, 1,
23                           NULL };
24 UBYTE StrStringSIBuff[300];
25 struct StringInfo StrStringSInfo = { StrStringSIBuff, UNDOBUFFER, 0, 300, 0,
26                                      0, 0, 0, 0, 0, 0, 0, NULL };
27 SHORT BorderVectors2[] = { 0, 0, 439, 0, 439, 11, 0, 11, 0, 0 };
28 struct Border Border2 = { -1, -1, 3, 0, JAM1, 5, BorderVectors2, NULL };
29 struct Gadget String = { &Gadget2, 77, 15, 438, 10, NULL,
30                          RELVERIFY + STRINGCENTER, STRGADGET, (APTR) &Border2,
31                          NULL, NULL, NULL, (APTR) &StrStringSInfo, 2, NULL };
32 
33 #define StrString \
34     ((char *) (((struct StringInfo *) (String.SpecialInfo))->Buffer))
35 
36 struct NewWindow StrWindow = {
37     57, 74, 526, 31, 0, 1, GADGETUP + CLOSEWINDOW + ACTIVEWINDOW + VANILLAKEY,
38     WINDOWDRAG + WINDOWDEPTH + WINDOWCLOSE + ACTIVATE + NOCAREREFRESH,
39     &String, NULL, NULL, NULL, NULL, 5, 5, 0xffff, 0xffff, CUSTOMSCREEN
40 };
41 
42 #include "NH:sys/amiga/colorwin.c"
43 
44 #define XSIZE 2
45 #define YSIZE 3
46 #define XCLIP 4
47 #define YCLIP 5
48 #define GADOKAY 6
49 #define GADCANCEL 7
50 
51 #include "NH:sys/amiga/clipwin.c"
52 
53 void ClearCol(struct Window *w);
54 
55 void
EditColor()56 EditColor()
57 {
58     extern char configfile[];
59     int i, done = 0, okay = 0;
60     long code, qual, class;
61     register struct Gadget *gd, *dgad;
62     register struct Window *nw;
63     register struct IntuiMessage *imsg;
64     register struct PropInfo *pip;
65     register struct Screen *scrn;
66     long aidx;
67     int msx, msy;
68     int curcol = 0, drag = 0;
69     int bxorx, bxory, bxxlen, bxylen;
70     static UWORD colors[AMII_MAXCOLORS];
71     static UWORD svcolors[AMII_MAXCOLORS];
72     static int once = 0;
73     scrn = HackScreen;
74 
75     if (!once) {
76         if (WINVERS_AMIV) {
77             Col_NewWindowStructure1.Width += 300;
78             Col_NewWindowStructure1.Height += 20;
79             Col_NewWindowStructure1.LeftEdge -= 150;
80             Col_BluePen.Width += 300;
81             Col_RedPen.Width += 300;
82             Col_GreenPen.Width += 300;
83             Col_Cancel.LeftEdge += 300;
84             Col_Okay.LeftEdge += 150;
85             Col_Cancel.TopEdge += 20;
86             Col_Save.TopEdge += 20;
87             Col_Okay.TopEdge += 20;
88         }
89         SetBorder(&Col_Okay);
90         SetBorder(&Col_Cancel);
91         SetBorder(&Col_Save);
92         once = 1;
93     }
94 
95     bxylen = Col_NewWindowStructure1.Height
96              - (Col_BluePen.TopEdge + Col_BluePen.Height + 6);
97     bxxlen = Col_BluePen.Width;
98     bxorx = Col_BluePen.LeftEdge;
99     bxory = Col_BluePen.TopEdge + Col_BluePen.Height + 2;
100 
101     /* Save the current colors */
102     for (i = 0; i < amii_numcolors; ++i)
103         svcolors[i] = colors[i] = GetRGB4(scrn->ViewPort.ColorMap, i);
104 
105     Col_NewWindowStructure1.Screen = scrn;
106 #ifdef INTUI_NEW_LOOK
107     if (IntuitionBase->LibNode.lib_Version >= 37) {
108         ((struct PropInfo *) Col_BluePen.SpecialInfo)->Flags |= PROPNEWLOOK;
109         ((struct PropInfo *) Col_RedPen.SpecialInfo)->Flags |= PROPNEWLOOK;
110         ((struct PropInfo *) Col_GreenPen.SpecialInfo)->Flags |= PROPNEWLOOK;
111     }
112 #endif
113     if (WINVERS_AMIV || WINVERS_AMII) {
114 #ifdef INTUI_NEW_LOOK
115         Col_NewWindowStructure1.Extension = wintags;
116         Col_NewWindowStructure1.Flags |= WFLG_NW_EXTENDED;
117 #ifdef __GNUC__
118         fillhook.h_Entry = (void *) &LayerFillHook;
119 #else
120         fillhook.h_Entry = (ULONG (*) ()) LayerFillHook;
121 #endif
122         fillhook.h_Data = (void *) -2;
123         fillhook.h_SubEntry = 0;
124 #endif
125     }
126 
127     nw = OpenWindow((void *) &Col_NewWindowStructure1);
128 
129     if (nw == NULL) {
130         DisplayBeep(NULL);
131         return;
132     }
133 
134     PrintIText(nw->RPort, &Col_IntuiTextList1, 0, 0);
135 
136     ClearCol(nw);
137     DrawCol(nw, curcol, colors);
138     while (!done) {
139         WaitPort(nw->UserPort);
140 
141         while (imsg = (struct IntuiMessage *) GetMsg(nw->UserPort)) {
142             gd = (struct Gadget *) imsg->IAddress;
143             code = imsg->Code;
144             class = imsg->Class;
145             qual = imsg->Qualifier;
146             msx = imsg->MouseX;
147             msy = imsg->MouseY;
148 
149             ReplyMsg((struct Message *) imsg);
150 
151             switch (class) {
152             case VANILLAKEY:
153                 if (code == 'v' && qual == AMIGALEFT)
154                     okay = done = 1;
155                 else if (code == 'b' && qual == AMIGALEFT)
156                     okay = 0, done = 1;
157                 else if (code == 'o' || code == 'O')
158                     okay = done = 1;
159                 else if (code == 'c' || code == 'C')
160                     okay = 0, done = 1;
161                 break;
162 
163             case CLOSEWINDOW:
164                 done = 1;
165                 break;
166 
167             case GADGETUP:
168                 drag = 0;
169                 if (gd->GadgetID == GADREDPEN || gd->GadgetID == GADBLUEPEN
170                     || gd->GadgetID == GADGREENPEN) {
171                     pip = (struct PropInfo *) gd->SpecialInfo;
172                     aidx = pip->HorizPot / (MAXPOT / 15);
173                     if (gd->GadgetID == GADREDPEN) {
174                         colors[curcol] =
175                             (colors[curcol] & ~0xf00) | (aidx << 8);
176                         LoadRGB4(&scrn->ViewPort, colors, amii_numcolors);
177                     } else if (gd->GadgetID == GADBLUEPEN) {
178                         colors[curcol] = (colors[curcol] & ~0xf) | aidx;
179                         LoadRGB4(&scrn->ViewPort, colors, amii_numcolors);
180                     } else if (gd->GadgetID == GADGREENPEN) {
181                         colors[curcol] =
182                             (colors[curcol] & ~0x0f0) | (aidx << 4);
183                         LoadRGB4(&scrn->ViewPort, colors, amii_numcolors);
184                     }
185                     DispCol(nw, curcol, colors);
186                 } else if (gd->GadgetID == GADCOLOKAY) {
187                     done = 1;
188                     okay = 1;
189                 } else if (gd->GadgetID == GADCOLSAVE) {
190                     FILE *fp, *nfp;
191                     char buf[300], nname[300], oname[300];
192                     int once = 0;
193 
194                     fp = fopen(configfile, "r");
195                     if (!fp) {
196                         pline("can't find NetHack.cnf");
197                         break;
198                     }
199 
200                     strcpy(oname, dirname((char *) configfile));
201                     if (oname[strlen(oname) - 1] != ':') {
202                         sprintf(nname, "%s/New_NetHack.cnf", oname);
203                         strcat(oname, "/");
204                         strcat(oname, "Old_NetHack.cnf");
205                     } else {
206                         sprintf(nname, "%sNew_NetHack.cnf", oname);
207                         strcat(oname, "Old_NetHack.cnf");
208                     }
209 
210                     nfp = fopen(nname, "w");
211                     if (!nfp) {
212                         pline("can't write to New_NetHack.cnf");
213                         fclose(fp);
214                         break;
215                     }
216                     while (fgets(buf, sizeof(buf), fp)) {
217                         if (strncmp(buf, "PENS=", 5) == 0) {
218                             once = 1;
219                             fputs("PENS=", nfp);
220                             for (i = 0; i < amii_numcolors; ++i) {
221                                 fprintf(nfp, "%03x", colors[i]);
222                                 if ((i + 1) < amii_numcolors)
223                                     putc('/', nfp);
224                             }
225                             putc('\n', nfp);
226                         } else {
227                             fputs(buf, nfp);
228                         }
229                     }
230 
231                     /* If none in the file yet, now write it */
232                     if (!once) {
233                         fputs("PENS=", nfp);
234                         for (i = 0; i < amii_numcolors; ++i) {
235                             fprintf(nfp, "%03x", colors[i]);
236                             if ((i + 1) < amii_numcolors)
237                                 putc(',', nfp);
238                         }
239                         putc('\n', nfp);
240                     }
241                     fclose(fp);
242                     fclose(nfp);
243                     unlink(oname);
244                     if (filecopy((char *) configfile, oname) == 0)
245                         if (filecopy(nname, (char *) configfile) == 0)
246                             unlink(nname);
247                     done = 1;
248                     okay = 1;
249                 } else if (gd->GadgetID == GADCOLCANCEL) {
250                     done = 1;
251                     okay = 0;
252                 }
253                 break;
254 
255             case GADGETDOWN:
256                 drag = 1;
257                 dgad = gd;
258                 break;
259 
260             case MOUSEMOVE:
261                 if (!drag)
262                     break;
263                 pip = (struct PropInfo *) dgad->SpecialInfo;
264                 aidx = pip->HorizPot / (MAXPOT / 15);
265                 if (dgad->GadgetID == GADREDPEN) {
266                     colors[curcol] = (colors[curcol] & ~0xf00) | (aidx << 8);
267                     LoadRGB4(&scrn->ViewPort, colors, amii_numcolors);
268                 } else if (dgad->GadgetID == GADBLUEPEN) {
269                     colors[curcol] = (colors[curcol] & ~0xf) | aidx;
270                     LoadRGB4(&scrn->ViewPort, colors, amii_numcolors);
271                 } else if (dgad->GadgetID == GADGREENPEN) {
272                     colors[curcol] = (colors[curcol] & ~0x0f0) | (aidx << 4);
273                     LoadRGB4(&scrn->ViewPort, colors, amii_numcolors);
274                 }
275                 DispCol(nw, curcol, colors);
276                 break;
277 
278             case MOUSEBUTTONS:
279                 if (code == SELECTDOWN) {
280                     if (msy > bxory && msy < bxory + bxylen - 1 && msx > bxorx
281                         && msx < bxorx + bxxlen - 1) {
282                         curcol = (msx - bxorx) / (bxxlen / amii_numcolors);
283                         if (curcol >= 0 && curcol < amii_numcolors)
284                             DrawCol(nw, curcol, colors);
285                     }
286                 }
287                 break;
288             }
289         }
290     }
291 
292     if (okay) {
293         for (i = 0; i < (amii_numcolors); ++i)
294             sysflags.amii_curmap[i] = colors[i];
295         LoadRGB4(&scrn->ViewPort, sysflags.amii_curmap, amii_numcolors);
296     } else
297         LoadRGB4(&scrn->ViewPort, svcolors, amii_numcolors);
298     CloseWindow(nw);
299 }
300 
301 void
ShowClipValues(struct Window * nw)302 ShowClipValues(struct Window *nw)
303 {
304     char buf[50];
305     struct Gadget *gd;
306 
307     SetAPen(nw->RPort, 5);
308     SetBPen(nw->RPort, amii_otherBPen);
309     SetDrMd(nw->RPort, JAM2);
310 
311     sprintf(buf, "%d ", mxsize);
312     gd = &ClipXSIZE;
313     Move(nw->RPort, gd->LeftEdge + (nw->Width + gd->Width) + 8,
314          gd->TopEdge + nw->RPort->TxBaseline);
315     Text(nw->RPort, buf, strlen(buf));
316 
317     sprintf(buf, "%d ", mysize);
318     gd = &ClipYSIZE;
319     Move(nw->RPort, gd->LeftEdge + (nw->Width + gd->Width) + 8,
320          gd->TopEdge + nw->RPort->TxBaseline);
321     Text(nw->RPort, buf, strlen(buf));
322 
323     sprintf(buf, "%d ", xclipbord);
324     gd = &ClipXCLIP;
325     Move(nw->RPort, gd->LeftEdge + (nw->Width + gd->Width) + 8,
326          gd->TopEdge + nw->RPort->TxBaseline);
327     Text(nw->RPort, buf, strlen(buf));
328 
329     sprintf(buf, "%d ", yclipbord);
330     gd = &ClipYCLIP;
331     Move(nw->RPort, gd->LeftEdge + (nw->Width + gd->Width) + 8,
332          gd->TopEdge + nw->RPort->TxBaseline);
333     Text(nw->RPort, buf, strlen(buf));
334 }
335 
336 void
EditClipping(void)337 EditClipping(void)
338 {
339     int i;
340     long mflags;
341     static int sizes[] = { 8, 16, 20, 24, 28, 32, 36 };
342     char buf[40];
343     int done = 0, okay = 0;
344     long code, qual, class;
345     register struct Gadget *gd, *dgad;
346     register struct Window *nw;
347     register struct IntuiMessage *imsg;
348     register struct PropInfo *pip;
349     register struct Screen *scrn;
350     long aidx;
351     int lmxsize = mxsize, lmysize = mysize;
352     int lxclipbord = xclipbord, lyclipbord = yclipbord;
353     int msx, msy;
354     int drag = 0;
355     static int once = 0;
356 
357     scrn = HackScreen;
358 
359     if (!once) {
360         SetBorder(&ClipOkay);
361         SetBorder(&ClipCancel);
362         once = 1;
363     }
364     ClipNewWindowStructure1.Screen = scrn;
365 #ifdef INTUI_NEW_LOOK
366     if (IntuitionBase->LibNode.lib_Version >= 37) {
367         ((struct PropInfo *) ClipXSIZE.SpecialInfo)->Flags |= PROPNEWLOOK;
368         ((struct PropInfo *) ClipYSIZE.SpecialInfo)->Flags |= PROPNEWLOOK;
369         ((struct PropInfo *) ClipXCLIP.SpecialInfo)->Flags |= PROPNEWLOOK;
370         ((struct PropInfo *) ClipYCLIP.SpecialInfo)->Flags |= PROPNEWLOOK;
371     }
372 #endif
373     if (WINVERS_AMIV || WINVERS_AMII) {
374 #ifdef INTUI_NEW_LOOK
375         ClipNewWindowStructure1.Extension = wintags;
376         ClipNewWindowStructure1.Flags |= WFLG_NW_EXTENDED;
377 #ifdef __GNUC__
378         fillhook.h_Entry = (void *) &LayerFillHook;
379 #else
380         fillhook.h_Entry = (ULONG (*) ()) LayerFillHook;
381 #endif
382         fillhook.h_Data = (void *) -2;
383         fillhook.h_SubEntry = 0;
384 #endif
385     }
386 
387     nw = OpenWindow((void *) &ClipNewWindowStructure1);
388 
389     if (nw == NULL) {
390         DisplayBeep(NULL);
391         return;
392     }
393 
394     ShowClipValues(nw);
395     mflags = AUTOKNOB | FREEHORIZ;
396 #ifdef INTUI_NEW_LOOK
397     if (IntuitionBase->LibNode.lib_Version >= 37) {
398         mflags |= PROPNEWLOOK;
399     }
400 #endif
401 
402     for (i = 0; i < 7; ++i) {
403         if (mxsize <= sizes[i])
404             break;
405     }
406     NewModifyProp(&ClipXSIZE, nw, NULL, mflags, (i * MAXPOT) / 6, 0,
407                   MAXPOT / 6, 0, 1);
408     for (i = 0; i < 7; ++i) {
409         if (mysize <= sizes[i])
410             break;
411     }
412     NewModifyProp(&ClipYSIZE, nw, NULL, mflags, (i * MAXPOT) / 6, 0,
413                   MAXPOT / 6, 0, 1);
414 
415     NewModifyProp(&ClipXCLIP, nw, NULL, mflags,
416                   ((xclipbord - 2) * MAXPOT) / 6, 0, MAXPOT / 6, 0, 1);
417     NewModifyProp(&ClipYCLIP, nw, NULL, mflags,
418                   ((yclipbord - 2) * MAXPOT) / 6, 0, MAXPOT / 6, 0, 1);
419 
420     while (!done) {
421         WaitPort(nw->UserPort);
422 
423         while (imsg = (struct IntuiMessage *) GetMsg(nw->UserPort)) {
424             gd = (struct Gadget *) imsg->IAddress;
425             code = imsg->Code;
426             class = imsg->Class;
427             qual = imsg->Qualifier;
428             msx = imsg->MouseX;
429             msy = imsg->MouseY;
430 
431             ReplyMsg((struct Message *) imsg);
432 
433             switch (class) {
434             case VANILLAKEY:
435                 if (code == '\33')
436                     okay = 0, done = 1;
437                 else if (code == 'v' && qual == AMIGALEFT)
438                     okay = done = 1;
439                 else if (code == 'b' && qual == AMIGALEFT)
440                     okay = 0, done = 1;
441                 else if (code == 'o' || code == 'O')
442                     okay = done = 1;
443                 else if (code == 'c' || code == 'C')
444                     okay = 0, done = 1;
445                 break;
446 
447             case CLOSEWINDOW:
448                 done = 1;
449                 break;
450 
451             case GADGETUP:
452                 drag = 0;
453                 if (gd->GadgetID == XSIZE || gd->GadgetID == YSIZE
454                     || gd->GadgetID == XCLIP || gd->GadgetID == YCLIP) {
455                     pip = (struct PropInfo *) gd->SpecialInfo;
456                     aidx = pip->HorizPot / (MAXPOT / 6);
457                     if (gd->GadgetID == XSIZE) {
458                         mxsize = sizes[aidx];
459                     } else if (gd->GadgetID == YSIZE) {
460                         mysize = sizes[aidx];
461                     } else if (gd->GadgetID == XCLIP) {
462                         xclipbord = aidx + 2;
463                     } else if (gd->GadgetID == YCLIP) {
464                         yclipbord = aidx + 2;
465                     }
466                     ShowClipValues(nw);
467 #ifdef OPT_DISPMAP
468                     dispmap_sanity();
469 #endif
470                 } else if (gd->GadgetID == GADOKAY) {
471                     done = 1;
472                     okay = 1;
473                 } else if (gd->GadgetID == GADCANCEL) {
474                     done = 1;
475                     okay = 0;
476                 }
477                 ReportMouse(0, nw);
478                 reclip = 2;
479                 doredraw();
480                 flush_glyph_buffer(amii_wins[WIN_MAP]->win);
481                 reclip = 0;
482                 break;
483 
484             case GADGETDOWN:
485                 drag = 1;
486                 dgad = gd;
487                 ReportMouse(1, nw);
488                 break;
489 
490             case MOUSEMOVE:
491                 if (!drag)
492                     break;
493                 pip = (struct PropInfo *) dgad->SpecialInfo;
494                 aidx = pip->HorizPot / (MAXPOT / 6);
495                 Move(nw->RPort,
496                      dgad->LeftEdge + (nw->Width + dgad->Width) + 8,
497                      dgad->TopEdge + nw->RPort->TxBaseline);
498                 if (dgad->GadgetID == XSIZE) {
499                     mxsize = sizes[aidx];
500                     sprintf(buf, "%d ", lmxsize);
501                 } else if (dgad->GadgetID == YSIZE) {
502                     mysize = sizes[aidx];
503                     sprintf(buf, "%d ", mysize);
504                 } else if (dgad->GadgetID == XCLIP) {
505                     xclipbord = aidx + 2;
506                     sprintf(buf, "%d ", xclipbord);
507                 } else if (dgad->GadgetID == YCLIP) {
508                     yclipbord = aidx + 2;
509                     sprintf(buf, "%d ", yclipbord);
510                 }
511                 SetAPen(nw->RPort, 5);
512                 SetBPen(nw->RPort, amii_otherBPen);
513                 SetDrMd(nw->RPort, JAM2);
514                 Text(nw->RPort, buf, strlen(buf));
515 #ifdef OPT_DISPMAP
516                 dispmap_sanity();
517 #endif
518                 break;
519             }
520         }
521     }
522 
523     CloseWindow(nw);
524 
525     /* Restore oldvalues if cancelled. */
526     if (!okay) {
527         mxsize = lmxsize;
528         mysize = lmysize;
529         xclipbord = lxclipbord;
530         yclipbord = lyclipbord;
531     }
532 }
533 
534 char *
dirname(str)535 dirname(str)
536 char *str;
537 {
538     char *t, c;
539     static char dir[300];
540 
541     t = strrchr(str, '/');
542     if (!t)
543         t = strrchr(str, ':');
544     if (!t)
545         t = str;
546     else {
547         c = *t;
548         *t = 0;
549         strcpy(dir, str);
550         *t = c;
551     }
552     return (dir);
553 }
554 
555 char *
basename(str)556 basename(str)
557 char *str;
558 {
559     char *t;
560 
561     t = strrchr(str, '/');
562     if (!t)
563         t = strrchr(str, ':');
564     if (!t)
565         t = str;
566     else
567         ++t;
568     return (t);
569 }
570 
filecopy(from,to)571 filecopy(from, to) char *from, *to;
572 {
573     char *buf;
574     int i = 0;
575 
576     buf = (char *) alloc(strlen(to) + strlen(from) + 20);
577     if (buf) {
578         sprintf(buf, "c:copy \"%s\" \"%s\" clone", from, to);
579 
580 /* Check SysBase instead?  Shouldn't matter  */
581 #ifdef INTUI_NEW_LOOK
582         if (IntuitionBase->LibNode.lib_Version >= 37)
583             i = System(buf, NULL);
584         else
585 #endif
586             Execute(buf, NULL, NULL);
587         free(buf);
588     } else {
589         return (-1);
590     }
591     return (i);
592 }
593 
594 /* The colornames, and the default values for the pens */
595 static struct COLDEF {
596     char *name, *defval;
597 };
598 struct COLDEF amii_colnames[AMII_MAXCOLORS] = {
599     "Black", "(000)", "White",   "(fff)", "Brown", "(830)", "Cyan", "(7ac)",
600     "Green", "(181)", "Magenta", "(c06)", "Blue",  "(23e)", "Red",  "(c00)",
601 };
602 
603 struct COLDEF amiv_colnames[AMII_MAXCOLORS] = {
604     "Black",     "(000)", "White",       "(fff)", "Cyan",        "(0bf)",
605     "Orange",    "(f60)", "Blue",        "(00f)", "Green",       "(090)",
606     "Grey",      "(69b)", "Red",         "(f00)", "Light Green", "(6f0)",
607     "Yellow",    "(ff0)", "Magenta",     "(f0f)", "Brown",       "(940)",
608     "Grey Blue", "(466)", "Light Brown", "(c40)", "Light Grey",  "(ddb)",
609     "Peach",     "(fb9)", "Col 16",      "(222)", "Col 17",      "(eee)",
610     "Col 18",    "(000)", "Col 19",      "(ccc)", "Col 20",      "(bbb)",
611     "Col 21",    "(aaa)", "Col 22",      "(999)", "Col 23",      "(888)",
612     "Col 24",    "(777)", "Col 25",      "(666)", "Col 26",      "(555)",
613     "Col 27",    "(444)", "Col 28",      "(333)", "Col 29",      "(18f)",
614     "Col 30",    "(f81)", "Col 31",      "(fff)",
615 };
616 
617 void
ClearCol(struct Window * w)618 ClearCol(struct Window *w)
619 {
620     int bxorx, bxory, bxxlen, bxylen;
621     int incx, incy;
622 
623     bxylen = Col_Okay.TopEdge - (Col_BluePen.TopEdge + Col_BluePen.Height) - 1
624              - txheight - 3;
625     bxxlen = Col_BluePen.Width - 2;
626     bxorx = Col_BluePen.LeftEdge + 1;
627     bxory = Col_BluePen.TopEdge + Col_BluePen.Height + 2;
628 
629     incx = bxxlen / amii_numcolors;
630     incy = bxylen - 2;
631 
632     bxxlen /= incx;
633     bxxlen *= incx;
634     bxxlen += 2;
635 
636     SetAPen(w->RPort, C_WHITE);
637     SetDrMd(w->RPort, JAM1);
638     RectFill(w->RPort, bxorx, bxory, bxorx + bxxlen + 1, bxory + bxylen);
639 
640     SetAPen(w->RPort, C_BLACK);
641     RectFill(w->RPort, bxorx + 1, bxory + 1, bxorx + bxxlen,
642              bxory + bxylen - 1);
643 }
644 
645 void
DrawCol(w,idx,colors)646 DrawCol(w, idx, colors)
647 struct Window *w;
648 int idx;
649 UWORD *colors;
650 {
651     int bxorx, bxory, bxxlen, bxylen;
652     int i, incx, incy, r, g, b;
653     long mflags;
654 
655     bxylen = Col_Okay.TopEdge - (Col_BluePen.TopEdge + Col_BluePen.Height) - 1
656              - txheight - 3;
657     bxxlen = Col_BluePen.Width - 2;
658     bxorx = Col_BluePen.LeftEdge + 1;
659     bxory = Col_BluePen.TopEdge + Col_BluePen.Height + 2;
660 
661     incx = bxxlen / amii_numcolors;
662     incy = bxylen - 2;
663 
664     bxxlen /= incx;
665     bxxlen *= incx;
666     bxxlen += 2;
667 
668     for (i = 0; i < amii_numcolors; ++i) {
669         int x, y;
670         x = bxorx + 2 + (i * incx);
671         y = bxory + 2;
672 
673         if (i == idx) {
674             SetAPen(w->RPort, sysflags.amii_dripens[SHADOWPEN]);
675             Move(w->RPort, x, y + bxylen - 4);
676             Draw(w->RPort, x, y);
677             Draw(w->RPort, x + incx - 1, y);
678 
679             Move(w->RPort, x + 1, y + bxylen - 5);
680             Draw(w->RPort, x + 1, y + 1);
681             Draw(w->RPort, x + incx - 2, y + 1);
682 
683             SetAPen(w->RPort, sysflags.amii_dripens[SHINEPEN]);
684             Move(w->RPort, x + incx - 1, y + 1);
685             Draw(w->RPort, x + incx - 1, y + bxylen - 4);
686             Draw(w->RPort, x, y + bxylen - 4);
687 
688             Move(w->RPort, x + incx - 2, y + 2);
689             Draw(w->RPort, x + incx - 2, y + bxylen - 5);
690             Draw(w->RPort, x + 1, y + bxylen - 5);
691         } else {
692             SetAPen(w->RPort, C_BLACK);
693             Move(w->RPort, x, y);
694             Draw(w->RPort, x + incx - 1, y);
695             Draw(w->RPort, x + incx - 1, y + bxylen - 4);
696             Draw(w->RPort, x, y + bxylen - 4);
697             Draw(w->RPort, x, y);
698             SetAPen(w->RPort, C_BLACK);
699             Move(w->RPort, x + 1, y + 1);
700             Draw(w->RPort, x + incx - 2, y + 1);
701             Draw(w->RPort, x + incx - 2, y + bxylen - 6);
702             Draw(w->RPort, x + 1, y + bxylen - 6);
703             Draw(w->RPort, x + 1, y + 1);
704         }
705 
706         SetAPen(w->RPort, i);
707         RectFill(w->RPort, x + 3, y + 3, x + incx - 4, y + bxylen - 6);
708     }
709 
710     DispCol(w, idx, colors);
711 
712     r = (colors[idx] & 0xf00) >> 8;
713     g = (colors[idx] & 0x0f0) >> 4;
714     b = colors[idx] & 0x00f;
715 
716     mflags = AUTOKNOB | FREEHORIZ;
717 #ifdef INTUI_NEW_LOOK
718     if (IntuitionBase->LibNode.lib_Version >= 37) {
719         mflags |= PROPNEWLOOK;
720     }
721 #endif
722     NewModifyProp(&Col_RedPen, w, NULL, mflags, (r * MAXPOT) / 15, 0,
723                   MAXPOT / 15, 0, 1);
724     NewModifyProp(&Col_GreenPen, w, NULL, mflags, (g * MAXPOT) / 15, 0,
725                   MAXPOT / 15, 0, 1);
726     NewModifyProp(&Col_BluePen, w, NULL, mflags, (b * MAXPOT) / 15, 0,
727                   MAXPOT / 15, 0, 1);
728 }
729 
730 void
DispCol(w,idx,colors)731 DispCol(w, idx, colors)
732 struct Window *w;
733 int idx;
734 UWORD *colors;
735 {
736     char buf[50];
737     char *colname, *defval;
738 
739     if (WINVERS_AMIV) {
740         colname = amiv_colnames[idx].name;
741         defval = amiv_colnames[idx].defval;
742     } else {
743         colname = amii_colnames[idx].name;
744         defval = amii_colnames[idx].defval;
745     }
746 
747     if (colname == NULL) {
748         colname = "unknown";
749         defval = "unknown";
750     }
751     Move(w->RPort, Col_Save.LeftEdge, Col_Save.TopEdge - 7);
752     sprintf(buf, "%s=%03x default=%s%s", colname, colors[idx], defval,
753             "              " + strlen(colname) + 1);
754     SetAPen(w->RPort, C_RED);
755     SetBPen(w->RPort, amii_otherBPen);
756     SetDrMd(w->RPort, JAM2);
757     Text(w->RPort, buf, strlen(buf));
758 }
759 
760 void
amii_setpens(int count)761 amii_setpens(int count)
762 {
763 #ifdef INTUI_NEW_LOOK
764     struct EasyStruct ea = { sizeof(struct EasyStruct), 0l, "NetHack Request",
765                              "Number of pens requested(%ld) not correct",
766                              "Use default pens|Use requested pens" };
767     struct EasyStruct ea2 = { sizeof(struct EasyStruct), 0l,
768                               "NetHack Request",
769                               "Number of pens requested(%ld) not\ncompatible "
770                               "with game configuration(%ld)",
771                               "Use default pens|Use requested pens" };
772 #endif
773 /* If the pens in amii_curmap are
774  * more pens than in amii_numcolors, then we choose to ignore
775  * those pens.
776  */
777 #ifdef INTUI_NEW_LOOK
778     if (IntuitionBase && IntuitionBase->LibNode.lib_Version >= 39) {
779         if (count != amii_numcolors) {
780             long args[2];
781             args[0] = count;
782             args[1] = amii_numcolors;
783             if (EasyRequest(NULL, &ea2, NULL, args) == 1) {
784                 memcpy(sysflags.amii_curmap, amii_initmap,
785                        amii_numcolors * sizeof(amii_initmap[0]));
786             }
787         }
788     } else if (IntuitionBase && IntuitionBase->LibNode.lib_Version >= 37) {
789         if (count != amii_numcolors) {
790             if (EasyRequest(NULL, &ea, NULL, NULL) == 1) {
791                 memcpy(sysflags.amii_curmap, amii_initmap,
792                        amii_numcolors * sizeof(amii_initmap[0]));
793             }
794         }
795     } else
796 #endif
797         if (count != amii_numcolors) {
798         memcpy(sysflags.amii_curmap, amii_initmap,
799                amii_numcolors * sizeof(amii_initmap[0]));
800     }
801 
802     /* If the pens are set in NetHack.cnf, we can get called before
803      * HackScreen has been opened.
804      */
805     if (HackScreen != NULL) {
806         LoadRGB4(&HackScreen->ViewPort, sysflags.amii_curmap, amii_numcolors);
807     }
808 }
809 
810 /* Generate a requester for a string value. */
811 
812 void
amii_getlin(prompt,bufp)813 amii_getlin(prompt, bufp)
814 const char *prompt;
815 char *bufp;
816 {
817     getlind(prompt, bufp, 0);
818 }
819 
820 /* and with default */
821 void
getlind(prompt,bufp,dflt)822 getlind(prompt, bufp, dflt)
823 const char *prompt;
824 char *bufp;
825 const char *dflt;
826 {
827 #ifndef TOPL_GETLINE
828     register struct Window *cwin;
829     register struct IntuiMessage *imsg;
830     register long class, code, qual;
831     register int aredone = 0;
832     register struct Gadget *gd;
833     static int once;
834 
835     *StrString = 0;
836     if (dflt)
837         strcpy(StrString, dflt);
838     StrWindow.Title = (UBYTE *) prompt;
839     StrWindow.Screen = HackScreen;
840 
841     if (!once) {
842         if (bigscreen) {
843             StrWindow.LeftEdge =
844                 (HackScreen->Width / 2) - (StrWindow.Width / 2);
845             if (amii_wins[WIN_MAP]) {
846                 StrWindow.TopEdge = amii_wins[WIN_MAP]->win->TopEdge;
847             } else {
848                 StrWindow.TopEdge =
849                     (HackScreen->Height / 2) - (StrWindow.Height / 2);
850             }
851         }
852         SetBorder(&String);
853         SetBorder(&Gadget2);
854         once = 1;
855     }
856 
857     if (WINVERS_AMIV || WINVERS_AMII) {
858 #ifdef INTUI_NEW_LOOK
859         StrWindow.Extension = wintags;
860         StrWindow.Flags |= WFLG_NW_EXTENDED;
861 #ifdef __GNUC__
862         fillhook.h_Entry = (void *) &LayerFillHook;
863 #else
864         fillhook.h_Entry = (ULONG (*) ()) LayerFillHook;
865 #endif
866         fillhook.h_Data = (void *) -2;
867         fillhook.h_SubEntry = 0;
868 #endif
869     }
870 
871     if ((cwin = OpenWindow((void *) &StrWindow)) == NULL) {
872         return;
873     }
874 
875     while (!aredone) {
876         WaitPort(cwin->UserPort);
877         while ((imsg = (void *) GetMsg(cwin->UserPort)) != NULL) {
878             class = imsg->Class;
879             code = imsg->Code;
880             qual = imsg->Qualifier;
881             gd = (struct Gadget *) imsg->IAddress;
882 
883             switch (class) {
884             case VANILLAKEY:
885                 if (code == '\033'
886                     && (qual & (IEQUALIFIER_LALT | IEQUALIFIER_RALT
887                                 | IEQUALIFIER_LCOMMAND
888                                 | IEQUALIFIER_RCOMMAND)) == 0) {
889                     if (bufp) {
890                         bufp[0] = '\033';
891                         bufp[1] = 0;
892                     }
893                     aredone = 1;
894                 } else {
895                     ActivateGadget(&String, cwin, NULL);
896                 }
897                 break;
898 
899             case ACTIVEWINDOW:
900                 ActivateGadget(&String, cwin, NULL);
901                 break;
902 
903             case GADGETUP:
904                 switch (gd->GadgetID) {
905                 case 2:
906                     aredone = 1;
907                     if (bufp)
908                         strcpy(bufp, StrString);
909                     break;
910 
911                 case 1:
912                     if (bufp) {
913                         bufp[0] = '\033';
914                         bufp[1] = 0;
915                     }
916                     aredone = 1;
917                     break;
918                 }
919                 break;
920 
921             case CLOSEWINDOW:
922                 if (bufp) {
923                     bufp[0] = '\033';
924                     bufp[1] = 0;
925                 }
926                 aredone = 1;
927                 break;
928             }
929             ReplyMsg((struct Message *) imsg);
930         }
931     }
932 
933     CloseWindow(cwin);
934 #else
935     struct amii_WinDesc *cw;
936     struct Window *w;
937     int colx, ocolx, c;
938     char *obufp;
939 
940     amii_clear_nhwindow(WIN_MESSAGE);
941     amii_putstr(WIN_MESSAGE, 0, prompt);
942     cw = amii_wins[WIN_MESSAGE];
943     w = cw->win;
944     ocolx = colx = strlen(prompt) + 1;
945 
946     obufp = bufp;
947     cursor_on(WIN_MESSAGE);
948     while ((c = WindowGetchar()) != EOF) {
949         cursor_off(WIN_MESSAGE);
950         amii_curs(WIN_MESSAGE, colx, 0);
951         if (c == '\033') {
952             *obufp = c;
953             obufp[1] = 0;
954             return;
955         } else if (c == '\b') {
956             if (bufp != obufp) {
957                 bufp--;
958                 amii_curs(WIN_MESSAGE, --colx, 0);
959                 Text(w->RPort, "\177 ", 2);
960                 amii_curs(WIN_MESSAGE, colx, 0);
961             } else
962                 DisplayBeep(NULL);
963         } else if (c == '\n' || c == '\r') {
964             *bufp = 0;
965             amii_addtopl(obufp);
966             return;
967         } else if (' ' <= c && c < '\177') {
968             /* avoid isprint() - some people don't have it
969                ' ' is not always a printing char */
970             *bufp = c;
971             bufp[1] = 0;
972 
973             Text(w->RPort, bufp, 1);
974             Text(w->RPort, "\177", 1);
975             if (bufp - obufp < BUFSZ - 1 && bufp - obufp < COLNO) {
976                 colx++;
977                 bufp++;
978             }
979         } else if (c == ('X' - 64) || c == '\177') {
980             amii_curs(WIN_MESSAGE, ocolx, 0);
981             Text(w->RPort, "                                                 "
982                            "           ",
983                  colx - ocolx);
984             amii_curs(WIN_MESSAGE, colx = ocolx, 0);
985         } else
986             DisplayBeep(NULL);
987         cursor_on(WIN_MESSAGE);
988     }
989     cursor_off(WIN_MESSAGE);
990     *bufp = 0;
991 #endif
992 }
993 
994 void
amii_change_color(pen,val,rev)995 amii_change_color(pen, val, rev)
996 int pen, rev;
997 long val;
998 {
999     if (rev)
1000         sysflags.amii_curmap[pen] = ~val;
1001     else
1002         sysflags.amii_curmap[pen] = val;
1003 
1004     if (HackScreen)
1005         LoadRGB4(&HackScreen->ViewPort, sysflags.amii_curmap, amii_numcolors);
1006 }
1007 
1008 char *
amii_get_color_string()1009 amii_get_color_string()
1010 {
1011     int i;
1012     char s[10];
1013     static char buf[BUFSZ];
1014 
1015     *buf = 0;
1016     for (i = 0; i < min(32, amii_numcolors); ++i) {
1017         sprintf(s, "%s%03lx", i ? "/" : "", (long) sysflags.amii_curmap[i]);
1018         strcat(buf, s);
1019     }
1020 
1021     return (buf);
1022 }
1023