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