1 /* aNetHack 0.0.1 winami.c $ANH-Date: 1432512794 2015/05/25 00:13:14 $ $ANH-Branch: master $:$ANH-Revision: 1.19 $ */
2 /* Copyright (c) Gregg Wonderly, Naperville, Illinois, 1991,1992,1993,1996.
4 /* aNetHack may be freely redistributed. See license for details. */
6 #include "NH:sys/amiga/windefs.h"
7 #include "NH:sys/amiga/winext.h"
8 #include "NH:sys/amiga/winproto.h"
11 #ifdef AMIGA_INTUITION
13 static int FDECL(put_ext_cmd
, (char *, int, struct amii_WinDesc
*, int));
15 struct amii_DisplayDesc
*amiIDisplay
; /* the Amiga Intuition descriptor */
16 struct Rectangle lastinvent
, lastmsg
;
27 /* Interface definition, for use by windows.c and winprocs.h to provide
28 * the intuition interface for the amiga...
30 struct window_procs amii_procs
= {
31 "amii", WC_COLOR
| WC_HILITE_PET
| WC_INVERSE
, 0L, amii_init_nhwindows
,
32 amii_player_selection
, amii_askname
, amii_get_nh_event
,
33 amii_exit_nhwindows
, amii_suspend_nhwindows
, amii_resume_nhwindows
,
34 amii_create_nhwindow
, amii_clear_nhwindow
, amii_display_nhwindow
,
35 amii_destroy_nhwindow
, amii_curs
, amii_putstr
, genl_putmixed
,
36 amii_display_file
, amii_start_menu
, amii_add_menu
, amii_end_menu
,
37 amii_select_menu
, genl_message_menu
, amii_update_inventory
,
38 amii_mark_synch
, amii_wait_synch
,
45 amii_print_glyph
, amii_raw_print
, amii_raw_print_bold
, amii_nhgetch
,
46 amii_nh_poskey
, amii_bell
, amii_doprev_message
, amii_yn_function
,
47 amii_getlin
, amii_get_ext_cmd
, amii_number_pad
, amii_delay_output
,
48 #ifdef CHANGE_COLOR /* only a Mac option currently */
49 amii_change_color
, amii_get_color_string
,
51 /* other defs that really should go away (they're tty specific) */
52 amii_delay_output
, amii_delay_output
, amii_outrip
, genl_preference_update
,
53 genl_getmsghistory
, genl_putmsghistory
,
54 #ifdef STATUS_VIA_WINDOWPORT
55 genl_status_init
, genl_status_finish
, genl_status_enablefield
,
58 genl_status_threshold
,
64 /* The view window layout uses the same function names so we can use
65 * a shared library to allow the executable to be smaller.
67 struct window_procs amiv_procs
= {
68 "amitile", WC_COLOR
| WC_HILITE_PET
| WC_INVERSE
, 0L, amii_init_nhwindows
,
69 amii_player_selection
, amii_askname
, amii_get_nh_event
,
70 amii_exit_nhwindows
, amii_suspend_nhwindows
, amii_resume_nhwindows
,
71 amii_create_nhwindow
, amii_clear_nhwindow
, amii_display_nhwindow
,
72 amii_destroy_nhwindow
, amii_curs
, amii_putstr
, genl_putmixed
,
73 amii_display_file
, amii_start_menu
, amii_add_menu
, amii_end_menu
,
74 amii_select_menu
, genl_message_menu
, amii_update_inventory
,
75 amii_mark_synch
, amii_wait_synch
,
82 amii_print_glyph
, amii_raw_print
, amii_raw_print_bold
, amii_nhgetch
,
83 amii_nh_poskey
, amii_bell
, amii_doprev_message
, amii_yn_function
,
84 amii_getlin
, amii_get_ext_cmd
, amii_number_pad
, amii_delay_output
,
85 #ifdef CHANGE_COLOR /* only a Mac option currently */
86 amii_change_color
, amii_get_color_string
,
88 /* other defs that really should go away (they're tty specific) */
89 amii_delay_output
, amii_delay_output
, amii_outrip
, genl_preference_update
,
90 genl_getmsghistory
, genl_putmsghistory
,
91 #ifdef STATUS_VIA_WINDOWPORT
92 genl_status_init
, genl_status_finish
, genl_status_enablefield
,
95 genl_status_threshold
,
101 unsigned short amii_initmap
[AMII_MAXCOLORS
];
102 /* Default pens used unless user overides in anethack.cnf. */
103 unsigned short amii_init_map
[AMII_MAXCOLORS
] = {
104 0x0000, /* color #0 C_BLACK */
105 0x0FFF, /* color #1 C_WHITE */
106 0x0830, /* color #2 C_BROWN */
107 0x07ac, /* color #3 C_CYAN */
108 0x0181, /* color #4 C_GREEN */
109 0x0C06, /* color #5 C_MAGENTA */
110 0x023E, /* color #6 C_BLUE */
111 0x0c00, /* color #7 C_RED */
114 unsigned short amiv_init_map
[AMII_MAXCOLORS
] = {
115 0x0000, /* color #0 C_BLACK */
116 0x0fff, /* color #1 C_WHITE */
117 0x00bf, /* color #2 C_CYAN */
118 0x0f60, /* color #3 C_ORANGE */
119 0x000f, /* color #4 C_BLUE */
120 0x0090, /* color #5 C_GREEN */
121 0x069b, /* color #6 C_GREY */
122 0x0f00, /* color #7 C_RED */
123 0x06f0, /* color #8 C_LTGREEN */
124 0x0ff0, /* color #9 C_YELLOW */
125 0x0f0f, /* color #10 C_MAGENTA */
126 0x0940, /* color #11 C_BROWN */
127 0x0466, /* color #12 C_GREYBLUE */
128 0x0c40, /* color #13 C_LTBROWN */
129 0x0ddb, /* color #14 C_LTGREY */
130 0x0fb9, /* color #15 C_PEACH */
132 /* Pens for dripens etc under AA or better */
133 0x0222, /* color #16 */
134 0x0fdc, /* color #17 */
135 0x0000, /* color #18 */
136 0x0ccc, /* color #19 */
137 0x0bbb, /* color #20 */
138 0x0BA9, /* color #21 */
139 0x0999, /* color #22 */
140 0x0987, /* color #23 */
141 0x0765, /* color #24 */
142 0x0666, /* color #25 */
143 0x0555, /* color #26 */
144 0x0533, /* color #27 */
145 0x0333, /* color #28 */
146 0x018f, /* color #29 */
147 0x0f81, /* color #30 */
148 0x0fff, /* color #31 */
151 #if !defined(TTY_GRAPHICS) \
152 || defined(SHAREDLIB) /* this should be shared better */
153 char morc
; /* the character typed in response to a --more-- prompt */
155 char spaces
[76] = " "
158 winid WIN_BASE
= WIN_ERR
;
159 winid WIN_OVER
= WIN_ERR
;
160 winid amii_rawprwin
= WIN_ERR
;
162 /* Changed later during window/screen opens... */
163 int txwidth
= FONTWIDTH
, txheight
= FONTHEIGHT
, txbaseline
= FONTBASELINE
;
165 /* If a 240 or more row screen is in front when we start, this will be
166 * set to 1, and the windows will be given borders to allow them to be
167 * arranged differently. The Message window may eventually get a scroller...
171 /* This gadget data is replicated for menu/text windows... */
172 struct PropInfo PropScroll
= {
173 AUTOKNOB
| FREEVERT
, 0xffff, 0xffff, 0xffff, 0xffff,
175 struct Image Image1
= { 0, 0, 7, 102, 0, NULL
, 0x0000, 0x0000, NULL
};
176 struct Gadget MenuScroll
= { NULL
, -15, 10, 15, -19, GRELRIGHT
| GRELHEIGHT
,
177 RELVERIFY
| FOLLOWMOUSE
| RIGHTBORDER
178 | GADGIMMEDIATE
| RELVERIFY
,
179 PROPGADGET
, (APTR
) &Image1
, NULL
, NULL
, NULL
,
180 (APTR
) &PropScroll
, 1, NULL
};
182 /* This gadget is for the message window... */
183 struct PropInfo MsgPropScroll
= {
184 AUTOKNOB
| FREEVERT
, 0xffff, 0xffff, 0xffff, 0xffff,
186 struct Image MsgImage1
= { 0, 0, 7, 102, 0, NULL
, 0x0000, 0x0000, NULL
};
187 struct Gadget MsgScroll
= { NULL
, -15, 10, 14, -19, GRELRIGHT
| GRELHEIGHT
,
188 RELVERIFY
| FOLLOWMOUSE
| RIGHTBORDER
189 | GADGIMMEDIATE
| RELVERIFY
,
190 PROPGADGET
, (APTR
) &MsgImage1
, NULL
, NULL
, NULL
,
191 (APTR
) &MsgPropScroll
, 1, NULL
};
193 int wincnt
= 0; /* # of nh windows opened */
195 /* We advertise a public screen to allow some people to do other things
196 * while they are playing... like compiling...
199 #ifdef INTUI_NEW_LOOK
200 extern struct Hook fillhook
;
201 struct TagItem tags
[] = {
202 { WA_BackFill
, (ULONG
) &fillhook
},
203 { WA_PubScreenName
, (ULONG
) "aNetHack" },
209 * The default dimensions and status values for each window type. The
210 * data here is generally changed in create_nhwindow(), so beware that
211 * what you see here may not be exactly what you get.
213 struct win_setup new_wins
[] = {
215 /* First entry not used, types are based at 1 */
219 { { 0, 1, 640, 11, 0xff, 0xff,
220 NEWSIZE
| GADGETUP
| GADGETDOWN
| MOUSEMOVE
| MOUSEBUTTONS
| RAWKEY
,
221 BORDERLESS
| ACTIVATE
| SMART_REFRESH
222 #ifdef INTUI_NEW_LOOK
226 NULL
, NULL
, (UBYTE
*) "Messages", NULL
, NULL
, 320, 40, 0xffff, 0xffff,
227 #ifdef INTUI_NEW_LOOK
241 { { 0, 181, 640, 24, 0xff, 0xff, RAWKEY
| MENUPICK
| DISKINSERTED
,
242 BORDERLESS
| ACTIVATE
| SMART_REFRESH
| BACKDROP
243 #ifdef INTUI_NEW_LOOK
247 NULL
, NULL
, (UBYTE
*) "Game Status", NULL
, NULL
, 0, 0, 0xffff, 0xffff,
248 #ifdef INTUI_NEW_LOOK
262 { { 0, 0, WIDTH
, WINDOWHEIGHT
, 0xff, 0xff,
263 RAWKEY
| MENUPICK
| MOUSEBUTTONS
| ACTIVEWINDOW
| MOUSEMOVE
,
264 BORDERLESS
| ACTIVATE
| SMART_REFRESH
| BACKDROP
265 #ifdef INTUI_NEW_LOOK
269 NULL
, NULL
, (UBYTE
*) "Dungeon Map", NULL
, NULL
, 64, 64, 0xffff,
271 #ifdef INTUI_NEW_LOOK
285 { { 400, 10, 10, 10, 0xff, 0xff,
286 RAWKEY
| MENUPICK
| DISKINSERTED
| MOUSEMOVE
| MOUSEBUTTONS
| GADGETUP
287 | GADGETDOWN
| CLOSEWINDOW
| VANILLAKEY
| NEWSIZE
289 WINDOWSIZING
| WINDOWCLOSE
| WINDOWDRAG
| ACTIVATE
| SMART_REFRESH
290 #ifdef INTUI_NEW_LOOK
294 &MenuScroll
, NULL
, NULL
, NULL
, NULL
, 64, 32, 0xffff, 0xffff,
295 #ifdef INTUI_NEW_LOOK
309 { { 0, 0, 640, 200, 0xff, 0xff,
310 RAWKEY
| MENUPICK
| DISKINSERTED
| MOUSEMOVE
| GADGETUP
| CLOSEWINDOW
311 | VANILLAKEY
| NEWSIZE
,
312 WINDOWSIZING
| WINDOWCLOSE
| WINDOWDRAG
| ACTIVATE
| SMART_REFRESH
313 #ifdef INTUI_NEW_LOOK
317 &MenuScroll
, NULL
, (UBYTE
*) NULL
, NULL
, NULL
, 100, 32, 0xffff,
319 #ifdef INTUI_NEW_LOOK
333 { { 0, 0, WIDTH
, WINDOWHEIGHT
, 0xff, 0xff,
334 RAWKEY
| MENUPICK
| MOUSEBUTTONS
,
335 BORDERLESS
| ACTIVATE
| SMART_REFRESH
| BACKDROP
336 #ifdef INTUI_NEW_LOOK
340 NULL
, NULL
, (UBYTE
*) NULL
, NULL
, NULL
, -1, -1, 0xffff, 0xffff,
341 #ifdef INTUI_NEW_LOOK
355 { { 320, 20, 319, 179, 0xff, 0xff, RAWKEY
| MENUPICK
| MOUSEBUTTONS
,
356 BORDERLESS
| ACTIVATE
| SMART_REFRESH
| BACKDROP
357 #ifdef INTUI_NEW_LOOK
361 NULL
, NULL
, (UBYTE
*) NULL
, NULL
, NULL
, 64, 32, 0xffff, 0xffff,
362 #ifdef INTUI_NEW_LOOK
376 const char winpanicstr
[] = "Bad winid %d in %s()";
378 /* The opened windows information */
379 struct amii_WinDesc
*amii_wins
[MAXWIN
+ 1];
381 #ifdef INTUI_NEW_LOOK
383 * NUMDRIPENS varies based on headers, so don't use it
384 * here, its value is used elsewhere.
386 UWORD amii_defpens
[20];
388 struct TagItem scrntags
[] = {
389 { SA_PubName
, (ULONG
) "aNetHack" },
390 { SA_Overscan
, OSCAN_TEXT
},
391 { SA_AutoScroll
, TRUE
},
392 #if LIBRARY_VERSION >= 39
393 { SA_Interleaved
, TRUE
},
395 { SA_Pens
, (ULONG
) 0 },
402 struct NewScreen NewHackScreen
= { 0, 0, WIDTH
, SCREENHEIGHT
, 3, 0,
403 1, /* DetailPen, BlockPen */
405 #ifdef INTUI_NEW_LOOK
410 NULL
, /*(UBYTE *)" aNetHack X.Y.Z" */
412 NULL
, /* CustomBitmap */
413 #ifdef INTUI_NEW_LOOK
419 * plname is filled either by an option (-u Player or -uPlayer) or
420 * explicitly (by being the wizard) or by askname.
421 * It may still contain a suffix denoting pl_character.
422 * Always called after init_nhwindows() and before display_gamewindows().
427 char plnametmp
[300]; /* From winreq.c: sizeof(StrStringSIBuff) */
430 amii_getlin("Who are you?", plnametmp
);
431 } while (strlen(plnametmp
) == 0);
433 strncpy(plname
, plnametmp
, PL_NSIZ
- 1); /* Avoid overflowing plname[] */
434 plname
[PL_NSIZ
- 1] = 0;
436 if (*plname
== '\33') {
438 exit_nhwindows(NULL
);
443 /* Discarded ... -jhsa
444 #include "NH:sys/amiga/char.c"
447 /* Get the player selection character */
449 #if 0 /* New function at the bottom */
451 amii_player_selection()
453 register struct Window
*cwin
;
454 register struct IntuiMessage
*imsg
;
455 register int aredone
= 0;
456 register struct Gadget
*gd
;
460 amii_clear_nhwindow( WIN_BASE
);
461 if (validrole(flags
.initrole
))
464 flags
.initrole
=randrole();
467 #if 0 /* Don't query the user ... instead give random character -jhsa */
471 pl_character
[ 0 ] = toupper( pl_character
[ 0 ] );
472 if( index( pl_classes
, pl_character
[ 0 ] ) )
479 Type_NewWindowStructure1
.TopEdge
=
480 (HackScreen
->Height
/2) - (Type_NewWindowStructure1
.Height
/2);
482 for( gd
= Type_NewWindowStructure1
.FirstGadget
; gd
;
483 gd
= gd
->NextGadget
)
485 if( gd
->GadgetID
!= 0 )
493 #ifdef INTUI_NEW_LOOK
494 Type_NewWindowStructure1
.Extension
= wintags
;
495 Type_NewWindowStructure1
.Flags
|= WFLG_NW_EXTENDED
;
496 fillhook
.h_Entry
= (ULONG(*)())LayerFillHook
;
497 fillhook
.h_Data
= (void *)-2;
498 fillhook
.h_SubEntry
= 0;
502 Type_NewWindowStructure1
.Screen
= HackScreen
;
503 if( ( cwin
= OpenShWindow( (void *)&Type_NewWindowStructure1
) ) == NULL
)
508 WindowToFront( cwin
);
513 WaitPort( cwin
->UserPort
);
514 while( ( imsg
= (void *) GetMsg( cwin
->UserPort
) ) != NULL
)
518 gd
= (struct Gadget
*)imsg
->IAddress
;
519 ReplyMsg( (struct Message
*)imsg
);
524 if( index( pl_classes
, toupper( code
) ) )
526 pl_character
[0] = toupper( code
);
529 else if( code
== ' ' || code
== '\n' || code
== '\r' )
531 flags
.initrole
= randrole();
533 strcpy( pl_character
, roles
[ rnd( 11 ) ] );
536 amii_clear_nhwindow( WIN_BASE
);
537 CloseShWindow( cwin
);
538 RandomWindow( pl_character
);
541 else if( code
== 'q' || code
== 'Q' )
543 CloseShWindow( cwin
);
545 exit_nhwindows(NULL
);
553 switch( gd
->GadgetID
)
555 case 1: /* Random Character */
556 flags
.initrole
= randrole();
558 strcpy( pl_character
, roles
[ rnd( 11 ) ] );
560 amii_clear_nhwindow( WIN_BASE
);
561 CloseShWindow( cwin
);
562 RandomWindow( pl_character
);
566 pl_character
[0] = gd
->GadgetID
;
573 CloseShWindow( cwin
);
575 exit_nhwindows(NULL
);
581 amii_clear_nhwindow( WIN_BASE
);
582 CloseShWindow( cwin
);
583 #endif /* Do not query user ... -jhsa */
585 #endif /* Function elsewhere */
587 #if 0 /* Unused ... -jhsa */
589 #include "NH:sys/amiga/randwin.c"
595 struct MsgPort
*tport
;
596 struct timerequest
*trq
;
600 struct IntuiMessage
*imsg
;
601 int ticks
= 0, aredone
= 0, timerdone
= 0;
604 tport
= CreateMsgPort();
605 trq
= (struct timerequest
*)CreateIORequest( tport
, sizeof( *trq
) );
606 if( tport
== NULL
|| trq
== NULL
)
609 if( tport
) DeleteMsgPort( tport
);
610 if( trq
) DeleteIORequest( (struct IORequest
*)trq
);
615 if( OpenDevice( TIMERNAME
, UNIT_VBLANK
, (struct IORequest
*)trq
, 0L ) != 0 )
618 trq
->tr_node
.io_Command
= TR_ADDREQUEST
;
619 trq
->tr_time
.tv_secs
= 8;
620 trq
->tr_time
.tv_micro
= 0;
622 SendIO( (struct IORequest
*)trq
);
624 /* Place the name in the center of the screen */
625 Rnd_IText5
.IText
= name
;
626 Rnd_IText6
.LeftEdge
= Rnd_IText4
.LeftEdge
+
627 (strlen(Rnd_IText4
.IText
)+1)*8;
628 Rnd_NewWindowStructure1
.Width
= (
629 (strlen( Rnd_IText2
.IText
)+1) * 8 ) +
630 HackScreen
->WBorLeft
+ HackScreen
->WBorRight
;
631 Rnd_IText5
.LeftEdge
= (Rnd_NewWindowStructure1
.Width
-
634 gd
= Rnd_NewWindowStructure1
.FirstGadget
;
635 gd
->LeftEdge
= (Rnd_NewWindowStructure1
.Width
- gd
->Width
)/2;
636 /* Chose correct modifier */
637 Rnd_IText6
.IText
= "a";
640 case 'a': case 'e': case 'i': case 'o':
641 case 'u': case 'A': case 'E': case 'I':
643 Rnd_IText6
.IText
= "an";
651 Rnd_NewWindowStructure1
.TopEdge
=
652 (HackScreen
->Height
/2) - (Rnd_NewWindowStructure1
.Height
/2);
654 for( gd
= Rnd_NewWindowStructure1
.FirstGadget
; gd
; gd
= gd
->NextGadget
)
656 if( gd
->GadgetID
!= 0 )
659 Rnd_NewWindowStructure1
.IDCMPFlags
|= VANILLAKEY
;
666 #ifdef INTUI_NEW_LOOK
667 Rnd_NewWindowStructure1
.Extension
= wintags
;
668 Rnd_NewWindowStructure1
.Flags
|= WFLG_NW_EXTENDED
;
669 fillhook
.h_Entry
= (ULONG(*)())LayerFillHook
;
670 fillhook
.h_Data
= (void *)-2;
671 fillhook
.h_SubEntry
= 0;
675 Rnd_NewWindowStructure1
.Screen
= HackScreen
;
676 if( ( w
= OpenShWindow( (void *)&Rnd_NewWindowStructure1
) ) == NULL
)
678 AbortIO( (struct IORequest
*)trq
);
679 WaitIO( (struct IORequest
*)trq
);
680 CloseDevice( (struct IORequest
*)trq
);
681 DeleteIORequest( (struct IORequest
*) trq
);
682 DeleteMsgPort( tport
);
687 PrintIText( w
->RPort
, &Rnd_IntuiTextList1
, 0, 0 );
689 mask
= (1L << tport
->mp_SigBit
)|(1L << w
->UserPort
->mp_SigBit
);
693 if( got
& (1L << tport
->mp_SigBit
) )
699 while( w
&& ( imsg
= (struct IntuiMessage
*) GetMsg( w
->UserPort
) ) )
701 switch( (long)imsg
->Class
)
703 /* Must be up for a little while... */
718 if(imsg
->Code
=='\n' || imsg
->Code
==' ' || imsg
->Code
=='\r')
722 ReplyMsg( (struct Message
*)imsg
);
728 AbortIO( (struct IORequest
*)trq
);
729 WaitIO( (struct IORequest
*)trq
);
732 CloseDevice( (struct IORequest
*)trq
);
733 DeleteIORequest( (struct IORequest
*) trq
);
734 DeleteMsgPort( tport
);
735 if(w
) CloseShWindow( w
);
737 #endif /* Discarded randwin ... -jhsa */
739 /* this should probably not be needed (or be renamed)
743 /* Read in an extended command - doing command line completion for
744 * when enough characters have been entered to make a unique command.
747 amii_get_ext_cmd(void)
751 struct amii_WinDesc
*cw
;
761 register char *bufp
= obufp
;
763 int com_index
, oindex
;
764 int did_comp
= 0; /* did successful completion? */
767 if (WIN_MESSAGE
== WIN_ERR
|| (cw
= amii_wins
[WIN_MESSAGE
]) == NULL
)
768 panic(winpanicstr
, WIN_MESSAGE
, "get_ext_cmd");
770 bottom
= amii_msgborder(w
);
774 if (iflags
.extmenu
) {
775 win
= amii_create_nhwindow(NHW_MENU
);
776 amii_start_menu(win
);
778 amii_putstr(WIN_MESSAGE
, -1, " ");
780 for (i
= 0; extcmdlist
[i
].ef_txt
!= NULL
; ++i
) {
781 id
.a_char
= *extcmdlist
[i
].ef_txt
;
782 sprintf(buf
, "%-10s - %s ", extcmdlist
[i
].ef_txt
,
783 extcmdlist
[i
].ef_desc
);
784 amii_add_menu(win
, NO_GLYPH
, &id
, extcmdlist
[i
].ef_txt
[0], 0, 0,
785 buf
, MENU_UNSELECTED
);
788 amii_end_menu(win
, (char *) 0);
789 sel
= amii_select_menu(win
, PICK_ONE
, &mip
);
790 amii_destroy_nhwindow(win
);
793 sel
= mip
->item
.a_char
;
794 for (i
= 0; extcmdlist
[i
].ef_txt
!= NULL
; ++i
) {
795 if (sel
== extcmdlist
[i
].ef_txt
[0])
799 /* copy in the text */
800 if (extcmdlist
[i
].ef_txt
!= NULL
) {
801 amii_clear_nhwindow(WIN_MESSAGE
);
802 (void) put_ext_cmd((char *) extcmdlist
[i
].ef_txt
, 0, cw
,
813 amii_clear_nhwindow(WIN_MESSAGE
); /* Was NHW_MESSAGE */
822 while ((c
= WindowGetchar()) != EOF
) {
823 amii_curs(WIN_MESSAGE
, colx
, bottom
);
829 while (bufp
!= obufp
) {
831 amii_curs(WIN_MESSAGE
, --colx
, bottom
);
832 Text(w
->RPort
, spaces
, 1);
833 amii_curs(WIN_MESSAGE
, colx
, bottom
);
838 win
= amii_create_nhwindow(NHW_MENU
);
839 amii_start_menu(win
);
841 for (i
= 0; extcmdlist
[i
].ef_txt
!= NULL
; ++i
) {
842 id
.a_char
= extcmdlist
[i
].ef_txt
[0];
843 sprintf(buf
, "%-10s - %s ", extcmdlist
[i
].ef_txt
,
844 extcmdlist
[i
].ef_desc
);
845 amii_add_menu(win
, NO_GLYPH
, &id
, extcmdlist
[i
].ef_txt
[0], 0,
846 0, buf
, MENU_UNSELECTED
);
849 amii_end_menu(win
, (char *) 0);
850 sel
= amii_select_menu(win
, PICK_ONE
, &mip
);
851 amii_destroy_nhwindow(win
);
856 sel
= mip
->item
.a_char
;
857 for (i
= 0; extcmdlist
[i
].ef_txt
!= NULL
; ++i
) {
858 if (sel
== extcmdlist
[i
].ef_txt
[0])
862 /* copy in the text */
863 if (extcmdlist
[i
].ef_txt
!= NULL
) {
864 amii_clear_nhwindow(WIN_MESSAGE
);
865 strcpy(bufp
= obufp
, extcmdlist
[i
].ef_txt
);
866 (void) put_ext_cmd(obufp
, colx
, cw
, bottom
);
871 } else if (c
== '\033') {
873 } else if (c
== '\b') {
875 while (bufp
!= obufp
) {
877 amii_curs(WIN_MESSAGE
, --colx
, bottom
);
878 Text(w
->RPort
, spaces
, 1);
879 amii_curs(WIN_MESSAGE
, colx
, bottom
);
883 } else if (bufp
!= obufp
) {
886 amii_curs(WIN_MESSAGE
, --colx
, bottom
);
887 Text(w
->RPort
, spaces
, 1);
888 amii_curs(WIN_MESSAGE
, colx
, bottom
);
891 } else if (c
== '\n' || c
== '\r') {
893 } else if (c
>= ' ' && c
< '\177') {
894 /* avoid isprint() - some people don't have it
895 ' ' is not always a printing char */
901 while (extcmdlist
[oindex
].ef_txt
!= NULL
) {
902 if (!strnicmp(obufp
, (char *) extcmdlist
[oindex
].ef_txt
,
904 if (com_index
== -1) /* No matches yet*/
906 else /* More than 1 match */
912 if (com_index
>= 0 && *obufp
) {
913 Strcpy(obufp
, extcmdlist
[com_index
].ef_txt
);
914 /* finish printing our string */
915 colx
= put_ext_cmd(obufp
, colx
, cw
, bottom
);
916 bufp
= obufp
; /* reset it */
917 if (strlen(obufp
) < BUFSZ
- 1 && strlen(obufp
) < COLNO
)
918 bufp
+= strlen(obufp
);
922 colx
= put_ext_cmd(obufp
, colx
, cw
, bottom
);
923 if (bufp
- obufp
< BUFSZ
- 1 && bufp
- obufp
< COLNO
)
926 } else if (c
== ('X' - 64) || c
== '\177') {
928 amii_clear_nhwindow(WIN_MESSAGE
);
938 static int put_ext_cmd(obufp
, colx
, cw
, bottom
) char * obufp
;
940 struct amii_WinDesc
*cw
;
942 struct Window
*w
= cw
->win
;
945 t
= (char *) alloc(strlen(obufp
) + 7);
948 sprintf(t
, "xxx%s", obufp
);
952 amii_curs(WIN_MESSAGE
, 0, bottom
);
953 SetAPen(w
->RPort
, C_WHITE
);
954 Text(w
->RPort
, "># ", 3);
955 /* SetAPen( w->RPort, C_BLACK ); */ /* Black text on black
956 screen doesn't look too
958 Text(w
->RPort
, t
+ 3, strlen(t
) - 3);
960 sprintf(t
, "# %s", obufp
);
961 amii_curs(WIN_MESSAGE
, 0, bottom
);
962 SetAPen(w
->RPort
, C_WHITE
);
963 Text(w
->RPort
, t
, strlen(t
));
966 SetAPen(w
->RPort
, C_WHITE
);
967 if (cw
->data
[cw
->maxrow
- 1])
968 free(cw
->data
[cw
->maxrow
- 1]);
969 cw
->data
[cw
->maxrow
- 1] = t
;
971 amii_curs(WIN_MESSAGE
, 0, bottom
);
972 SetAPen(w
->RPort
, C_WHITE
);
973 Text(w
->RPort
, "# ", 2);
974 /* SetAPen( w->RPort, C_BLACK ); */ /* Black on black ... -jhsa */
975 Text(w
->RPort
, obufp
, strlen(obufp
));
976 SetAPen(w
->RPort
, C_WHITE
);
978 amii_curs(WIN_MESSAGE
, colx
= strlen(obufp
) + 3 + (scrollmsg
!= 0),
983 /* Ask a question and get a response */
985 char amii_yn_function(query
, resp
, def
) const char * query
, *resp
;
988 * Generic yes/no function. 'def' is the default (returned by space or
989 * return; 'esc' returns 'q', or 'n', or the default, depending on
990 * what's in the string. The 'query' string is printed before the user
991 * is asked about the string.
992 * If resp is NULL, any single character is accepted and returned.
993 * If not-NULL, only characters in it are allowed (exceptions: the
994 * quitchars are always allowed, and if it contains '#' then digits
995 * are allowed); if it includes an <esc>, anything beyond that won't
996 * be shown in the prompt to the user but will be acceptable as input.
1001 boolean digit_ok
, allow_num
;
1003 register struct amii_WinDesc
*cw
;
1005 if (cw
= amii_wins
[WIN_MESSAGE
])
1008 char *rb
, respbuf
[QBUFSZ
];
1010 allow_num
= (index(resp
, '#') != 0);
1011 Strcpy(respbuf
, resp
);
1012 /* any acceptable responses that follow <esc> aren't displayed */
1013 if ((rb
= index(respbuf
, '\033')) != 0)
1015 (void) strncpy(prompt
, query
, QBUFSZ
- 1);
1016 prompt
[QBUFSZ
- 1] = '\0';
1017 Sprintf(eos(prompt
), " [%s]", respbuf
);
1019 Sprintf(eos(prompt
), " (%c)", def
);
1020 Strcat(prompt
, " ");
1021 pline("%s", prompt
);
1023 amii_putstr(WIN_MESSAGE
, 0, query
);
1024 cursor_on(WIN_MESSAGE
);
1025 q
= WindowGetchar();
1026 cursor_off(WIN_MESSAGE
);
1033 do { /* loop until we get valid input */
1034 cursor_on(WIN_MESSAGE
);
1035 q
= lowc(WindowGetchar());
1036 cursor_off(WIN_MESSAGE
);
1039 if (q
== '\020') { /* ctrl-P */
1040 if(!doprev
) (void) tty_doprev_message(); /* need two initially */
1041 (void) tty_doprev_message();
1046 tty_clear_nhwindow(WIN_MESSAGE
);
1047 cw
->maxcol
= cw
->maxrow
;
1049 amii_addtopl(prompt
);
1053 digit_ok
= allow_num
&& isdigit(q
);
1055 if (index(resp
, 'q'))
1057 else if (index(resp
, 'n'))
1062 } else if (index(quitchars
, q
)) {
1066 if (!index(resp
, q
) && !digit_ok
) {
1069 } else if (q
== '#' || digit_ok
) {
1070 char z
, digit_string
[2];
1073 amii_addtopl("#"), n_len
++;
1074 digit_string
[1] = '\0';
1076 digit_string
[0] = q
;
1077 amii_addtopl(digit_string
), n_len
++;
1081 do { /* loop until we get a non-digit */
1082 cursor_on(WIN_MESSAGE
);
1083 z
= lowc(WindowGetchar());
1084 cursor_off(WIN_MESSAGE
);
1086 value
= (10 * value
) + (z
- '0');
1088 break; /* overflow: try again */
1089 digit_string
[0] = z
;
1090 amii_addtopl(digit_string
), n_len
++;
1091 } else if (z
== 'y' || index(quitchars
, z
)) {
1093 value
= -1; /* abort */
1094 z
= '\n'; /* break */
1095 } else if (z
== '\b') {
1101 removetopl(1), n_len
--;
1104 value
= -1; /* abort */
1108 } while (z
!= '\n');
1111 else if (value
== 0)
1112 q
= 'n'; /* 0 => "no" */
1113 else { /* remove number from top line, then try again */
1114 removetopl(n_len
), n_len
= 0;
1120 if (q
!= '#' && q
!= '\033') {
1121 Sprintf(rtmp
, "%c", q
);
1125 cursor_off(WIN_MESSAGE
);
1126 clear_nhwindow(WIN_MESSAGE
);
1130 void amii_display_file(fn
, complain
) const char * fn
;
1133 register struct amii_WinDesc
*cw
;
1137 register char buf
[200];
1140 panic("NULL file name in display_file()");
1142 if ((fp
= dlb_fopen(fn
, RDTMODE
)) == (dlb
*) NULL
) {
1144 sprintf(buf
, "Can't display %s: %s", fn
,
1145 #if defined(_DCC) || defined(__GNUC__)
1149 __sys_errlist
[errno
]
1159 win
= amii_create_nhwindow(NHW_TEXT
);
1161 /* Set window title to file name */
1162 if (cw
= amii_wins
[win
])
1163 cw
->morestr
= (char *) fn
;
1165 while (dlb_fgets(buf
, sizeof(buf
), fp
) != NULL
) {
1166 if (t
= index(buf
, '\n'))
1168 amii_putstr(win
, 0, buf
);
1172 /* If there were lines in the file, display those lines */
1174 if (amii_wins
[win
]->cury
> 0)
1175 amii_display_nhwindow(win
, TRUE
);
1177 amii_wins
[win
]->morestr
= NULL
; /* don't free title string */
1178 amii_destroy_nhwindow(win
);
1181 /* Put a 3-D motif border around the gadget. String gadgets or those
1182 * which do not have highlighting are rendered down. Boolean gadgets
1183 * are rendered in the up position by default.
1186 void SetBorder(gd
) register struct Gadget
* gd
;
1188 register struct Border
*bp
;
1190 register int i
, inc
= -1, dec
= -1;
1192 int hipen
= sysflags
.amii_dripens
[SHINEPEN
],
1193 shadowpen
= sysflags
.amii_dripens
[SHADOWPEN
];
1194 #ifdef INTUI_NEW_LOOK
1195 struct DrawInfo
*dip
;
1198 #ifdef INTUI_NEW_LOOK
1199 if (IntuitionBase
->LibNode
.lib_Version
>= 37) {
1200 if (dip
= GetScreenDrawInfo(HackScreen
)) {
1201 hipen
= dip
->dri_Pens
[SHINEPEN
];
1202 shadowpen
= dip
->dri_Pens
[SHADOWPEN
];
1203 FreeScreenDrawInfo(HackScreen
, dip
);
1207 /* Allocate two border structures one for up image and one for down
1208 * image, plus vector arrays for the border lines.
1211 if (gd
->GadgetType
== STRGADGET
)
1214 if ((bp
= (struct Border
*) alloc(((sizeof(struct Border
) * 2)
1215 + (sizeof(short) * borders
)) * 2))
1220 /* For a string gadget, we expand the border beyond the area where
1221 * the text will be entered.
1224 /* Remove any special rendering flags to avoid confusing intuition
1227 gd
->Flags
&= ~(GADGHIGHBITS
| GADGIMAGE
);
1229 sp
= (short *) (bp
+ 4);
1230 if (gd
->GadgetType
== STRGADGET
1231 || (gd
->GadgetType
== BOOLGADGET
1232 && (gd
->Flags
& GADGHIGHBITS
) == GADGHNONE
)) {
1234 sp
[1] = gd
->Height
- 1;
1237 sp
[4] = gd
->Width
- 1;
1240 sp
[6] = gd
->Width
+ 1;
1242 sp
[8] = gd
->Width
+ 1;
1243 sp
[9] = gd
->Height
+ 1;
1245 sp
[11] = gd
->Height
+ 1;
1248 sp
[13] = gd
->Height
;
1254 sp
[19] = gd
->Height
;
1256 sp
[21] = gd
->Height
;
1258 for (i
= 0; i
< 3; ++i
) {
1259 bp
[i
].LeftEdge
= bp
[i
].TopEdge
= -1;
1260 bp
[i
].FrontPen
= (i
== 0 || i
== 1) ? shadowpen
: hipen
;
1262 /* Have to use JAM2 so that the old colors disappear. */
1263 bp
[i
].BackPen
= C_BLACK
;
1264 bp
[i
].DrawMode
= JAM2
;
1265 bp
[i
].Count
= (i
== 0 || i
== 1) ? 3 : 5;
1266 bp
[i
].XY
= &sp
[i
* 6];
1267 bp
[i
].NextBorder
= (i
== 2) ? NULL
: &bp
[i
+ 1];
1270 /* bp[0] and bp[1] two pieces for the up image */
1271 gd
->GadgetRender
= (APTR
) bp
;
1273 /* No image change for select */
1274 gd
->SelectRender
= (APTR
) bp
;
1278 gd
->Flags
|= GADGHCOMP
;
1280 /* Create the border vector values for up and left side, and
1281 * also the lower and right side.
1285 sp
[1] = gd
->Height
+ inc
;
1288 sp
[4] = gd
->Width
+ inc
;
1291 sp
[6] = gd
->Width
+ inc
;
1293 sp
[8] = gd
->Width
+ inc
;
1294 sp
[9] = gd
->Height
+ inc
;
1296 sp
[11] = gd
->Height
+ inc
;
1298 /* We are creating 4 sets of borders, the two sides of the
1299 * rectangle share the border vectors with the opposite image,
1300 * but specify different colors.
1303 for (i
= 0; i
< 4; ++i
) {
1304 bp
[i
].TopEdge
= bp
[i
].LeftEdge
= 0;
1306 /* A GADGHNONE is always down */
1308 if (gd
->GadgetType
== BOOLGADGET
1309 && (gd
->Flags
& GADGHIGHBITS
) != GADGHNONE
) {
1310 bp
[i
].FrontPen
= (i
== 1 || i
== 2) ? shadowpen
: hipen
;
1312 bp
[i
].FrontPen
= (i
== 1 || i
== 3) ? hipen
: shadowpen
;
1315 /* Have to use JAM2 so that the old colors disappear. */
1316 bp
[i
].BackPen
= C_BLACK
;
1317 bp
[i
].DrawMode
= JAM2
;
1319 bp
[i
].XY
= &sp
[6 * ((i
& 1) != 0)];
1320 bp
[i
].NextBorder
= (i
== 1 || i
== 3) ? NULL
: &bp
[i
+ 1];
1323 /* bp[0] and bp[1] two pieces for the up image */
1324 gd
->GadgetRender
= (APTR
) bp
;
1326 /* bp[2] and bp[3] two pieces for the down image */
1327 gd
->SelectRender
= (APTR
)(bp
+ 2);
1328 gd
->Flags
|= GADGHIMAGE
;
1332 /* Following function copied from wintty.c */
1333 /* Modified slightly to fit amiga needs */
1335 void amii_player_selection()
1338 char pick4u
= 'n', thisch
, lastch
= 0;
1339 char pbuf
[QBUFSZ
], plbuf
[QBUFSZ
], rolenamebuf
[QBUFSZ
];
1342 menu_item
*selected
= 0;
1344 rigid_role_checks();
1346 /* Should we randomly pick for the player? */
1347 if (flags
.initrole
== ROLE_NONE
|| flags
.initrace
== ROLE_NONE
1348 || flags
.initgend
== ROLE_NONE
|| flags
.initalign
== ROLE_NONE
) {
1349 char *prompt
= build_plselection_prompt(
1350 pbuf
, QBUFSZ
, flags
.initrole
, flags
.initrace
, flags
.initgend
,
1352 pline("%s", prompt
);
1353 do { /* loop until we get valid input */
1354 cursor_on(WIN_MESSAGE
);
1355 pick4u
= lowc(WindowGetchar());
1356 cursor_off(WIN_MESSAGE
);
1357 if (index(quitchars
, pick4u
))
1359 } while (!index(ynqchars
, pick4u
));
1364 if (pick4u
!= 'y' && pick4u
!= 'n') {
1367 free((genericptr_t
) selected
);
1369 exit_nhwindows(NULL
);
1376 (void) root_plselection_prompt(plbuf
, QBUFSZ
- 1, flags
.initrole
,
1377 flags
.initrace
, flags
.initgend
,
1380 /* Select a role, if necessary */
1381 /* we'll try to be compatible with pre-selected race/gender/alignment,
1382 * but may not succeed */
1383 if (flags
.initrole
< 0) {
1384 /* Process the choice */
1385 if (pick4u
== 'y' || flags
.initrole
== ROLE_RANDOM
1386 || flags
.randomall
) {
1387 /* Pick a random role */
1388 flags
.initrole
= pick_role(flags
.initrace
, flags
.initgend
,
1389 flags
.initalign
, PICK_RANDOM
);
1390 if (flags
.initrole
< 0) {
1391 amii_putstr(WIN_MESSAGE
, 0, "Incompatible role!");
1392 flags
.initrole
= randrole();
1395 /* Prompt for a role */
1396 win
= create_nhwindow(NHW_MENU
);
1398 any
.a_void
= 0; /* zero out all bits */
1399 for (i
= 0; roles
[i
].name
.m
; i
++) {
1400 if (ok_role(i
, flags
.initrace
, flags
.initgend
,
1402 any
.a_int
= i
+ 1; /* must be non-zero */
1403 thisch
= lowc(roles
[i
].name
.m
[0]);
1404 if (thisch
== lastch
)
1405 thisch
= highc(thisch
);
1406 if (flags
.initgend
!= ROLE_NONE
1407 && flags
.initgend
!= ROLE_RANDOM
) {
1408 if (flags
.initgend
== 1 && roles
[i
].name
.f
)
1409 Strcpy(rolenamebuf
, roles
[i
].name
.f
);
1411 Strcpy(rolenamebuf
, roles
[i
].name
.m
);
1413 if (roles
[i
].name
.f
) {
1414 Strcpy(rolenamebuf
, roles
[i
].name
.m
);
1415 Strcat(rolenamebuf
, "/");
1416 Strcat(rolenamebuf
, roles
[i
].name
.f
);
1418 Strcpy(rolenamebuf
, roles
[i
].name
.m
);
1420 add_menu(win
, NO_GLYPH
, &any
, thisch
, 0, ATR_NONE
,
1421 an(rolenamebuf
), MENU_UNSELECTED
);
1425 any
.a_int
= pick_role(flags
.initrace
, flags
.initgend
,
1426 flags
.initalign
, PICK_RANDOM
) + 1;
1427 if (any
.a_int
== 0) /* must be non-zero */
1428 any
.a_int
= randrole() + 1;
1429 add_menu(win
, NO_GLYPH
, &any
, '*', 0, ATR_NONE
, "Random",
1431 any
.a_int
= i
+ 1; /* must be non-zero */
1432 add_menu(win
, NO_GLYPH
, &any
, 'q', 0, ATR_NONE
, "Quit",
1434 Sprintf(pbuf
, "Pick a role for your %s", plbuf
);
1435 end_menu(win
, pbuf
);
1436 n
= select_menu(win
, PICK_ONE
, &selected
);
1437 destroy_nhwindow(win
);
1439 /* Process the choice */
1440 if (n
!= 1 || selected
[0].item
.a_int
== any
.a_int
)
1441 goto give_up
; /* Selected quit */
1443 flags
.initrole
= selected
[0].item
.a_int
- 1;
1444 free((genericptr_t
) selected
), selected
= 0;
1446 (void) root_plselection_prompt(plbuf
, QBUFSZ
- 1, flags
.initrole
,
1447 flags
.initrace
, flags
.initgend
,
1451 /* Select a race, if necessary */
1452 /* force compatibility with role, try for compatibility with
1453 * pre-selected gender/alignment */
1454 if (flags
.initrace
< 0
1455 || !validrace(flags
.initrole
, flags
.initrace
)) {
1456 /* pre-selected race not valid */
1457 if (pick4u
== 'y' || flags
.initrace
== ROLE_RANDOM
1458 || flags
.randomall
) {
1459 flags
.initrace
= pick_race(flags
.initrole
, flags
.initgend
,
1460 flags
.initalign
, PICK_RANDOM
);
1461 if (flags
.initrace
< 0) {
1462 amii_putstr(WIN_MESSAGE
, 0, "Incompatible race!");
1463 flags
.initrace
= randrace(flags
.initrole
);
1465 } else { /* pick4u == 'n' */
1466 /* Count the number of valid races */
1467 n
= 0; /* number valid */
1468 k
= 0; /* valid race */
1469 for (i
= 0; races
[i
].noun
; i
++) {
1470 if (ok_race(flags
.initrole
, i
, flags
.initgend
,
1477 for (i
= 0; races
[i
].noun
; i
++) {
1478 if (validrace(flags
.initrole
, i
)) {
1485 /* Permit the user to pick, if there is more than one */
1487 win
= create_nhwindow(NHW_MENU
);
1489 any
.a_void
= 0; /* zero out all bits */
1490 for (i
= 0; races
[i
].noun
; i
++)
1491 if (ok_race(flags
.initrole
, i
, flags
.initgend
,
1493 any
.a_int
= i
+ 1; /* must be non-zero */
1494 add_menu(win
, NO_GLYPH
, &any
, races
[i
].noun
[0], 0,
1495 ATR_NONE
, races
[i
].noun
,
1498 any
.a_int
= pick_race(flags
.initrole
, flags
.initgend
,
1499 flags
.initalign
, PICK_RANDOM
) + 1;
1500 if (any
.a_int
== 0) /* must be non-zero */
1501 any
.a_int
= randrace(flags
.initrole
) + 1;
1502 add_menu(win
, NO_GLYPH
, &any
, '*', 0, ATR_NONE
, "Random",
1504 any
.a_int
= i
+ 1; /* must be non-zero */
1505 add_menu(win
, NO_GLYPH
, &any
, 'q', 0, ATR_NONE
, "Quit",
1507 Sprintf(pbuf
, "Pick the race of your %s", plbuf
);
1508 end_menu(win
, pbuf
);
1509 n
= select_menu(win
, PICK_ONE
, &selected
);
1510 destroy_nhwindow(win
);
1511 if (n
!= 1 || selected
[0].item
.a_int
== any
.a_int
)
1512 goto give_up
; /* Selected quit */
1514 k
= selected
[0].item
.a_int
- 1;
1515 free((genericptr_t
) selected
), selected
= 0;
1519 (void) root_plselection_prompt(plbuf
, QBUFSZ
- 1, flags
.initrole
,
1520 flags
.initrace
, flags
.initgend
,
1524 /* Select a gender, if necessary */
1525 /* force compatibility with role/race, try for compatibility with
1526 * pre-selected alignment */
1527 if (flags
.initgend
< 0
1528 || !validgend(flags
.initrole
, flags
.initrace
, flags
.initgend
)) {
1529 /* pre-selected gender not valid */
1530 if (pick4u
== 'y' || flags
.initgend
== ROLE_RANDOM
1531 || flags
.randomall
) {
1532 flags
.initgend
= pick_gend(flags
.initrole
, flags
.initrace
,
1533 flags
.initalign
, PICK_RANDOM
);
1534 if (flags
.initgend
< 0) {
1535 amii_putstr(WIN_MESSAGE
, 0, "Incompatible gender!");
1536 flags
.initgend
= randgend(flags
.initrole
, flags
.initrace
);
1538 } else { /* pick4u == 'n' */
1539 /* Count the number of valid genders */
1540 n
= 0; /* number valid */
1541 k
= 0; /* valid gender */
1542 for (i
= 0; i
< ROLE_GENDERS
; i
++) {
1543 if (ok_gend(flags
.initrole
, flags
.initrace
, i
,
1550 for (i
= 0; i
< ROLE_GENDERS
; i
++) {
1551 if (validgend(flags
.initrole
, flags
.initrace
, i
)) {
1558 /* Permit the user to pick, if there is more than one */
1560 win
= create_nhwindow(NHW_MENU
);
1562 any
.a_void
= 0; /* zero out all bits */
1563 for (i
= 0; i
< ROLE_GENDERS
; i
++)
1564 if (ok_gend(flags
.initrole
, flags
.initrace
, i
,
1567 add_menu(win
, NO_GLYPH
, &any
, genders
[i
].adj
[0],
1568 0, ATR_NONE
, genders
[i
].adj
,
1571 any
.a_int
= pick_gend(flags
.initrole
, flags
.initrace
,
1572 flags
.initalign
, PICK_RANDOM
) + 1;
1573 if (any
.a_int
== 0) /* must be non-zero */
1575 randgend(flags
.initrole
, flags
.initrace
) + 1;
1576 add_menu(win
, NO_GLYPH
, &any
, '*', 0, ATR_NONE
, "Random",
1578 any
.a_int
= i
+ 1; /* must be non-zero */
1579 add_menu(win
, NO_GLYPH
, &any
, 'q', 0, ATR_NONE
, "Quit",
1581 Sprintf(pbuf
, "Pick the gender of your %s", plbuf
);
1582 end_menu(win
, pbuf
);
1583 n
= select_menu(win
, PICK_ONE
, &selected
);
1584 destroy_nhwindow(win
);
1585 if (n
!= 1 || selected
[0].item
.a_int
== any
.a_int
)
1586 goto give_up
; /* Selected quit */
1588 k
= selected
[0].item
.a_int
- 1;
1589 free((genericptr_t
) selected
), selected
= 0;
1593 (void) root_plselection_prompt(plbuf
, QBUFSZ
- 1, flags
.initrole
,
1594 flags
.initrace
, flags
.initgend
,
1598 /* Select an alignment, if necessary */
1599 /* force compatibility with role/race/gender */
1600 if (flags
.initalign
< 0
1601 || !validalign(flags
.initrole
, flags
.initrace
, flags
.initalign
)) {
1602 /* pre-selected alignment not valid */
1603 if (pick4u
== 'y' || flags
.initalign
== ROLE_RANDOM
1604 || flags
.randomall
) {
1605 flags
.initalign
= pick_align(flags
.initrole
, flags
.initrace
,
1606 flags
.initgend
, PICK_RANDOM
);
1607 if (flags
.initalign
< 0) {
1608 amii_putstr(WIN_MESSAGE
, 0, "Incompatible alignment!");
1610 randalign(flags
.initrole
, flags
.initrace
);
1612 } else { /* pick4u == 'n' */
1613 /* Count the number of valid alignments */
1614 n
= 0; /* number valid */
1615 k
= 0; /* valid alignment */
1616 for (i
= 0; i
< ROLE_ALIGNS
; i
++) {
1617 if (ok_align(flags
.initrole
, flags
.initrace
,
1618 flags
.initgend
, i
)) {
1624 for (i
= 0; i
< ROLE_ALIGNS
; i
++) {
1625 if (validalign(flags
.initrole
, flags
.initrace
, i
)) {
1632 /* Permit the user to pick, if there is more than one */
1634 win
= create_nhwindow(NHW_MENU
);
1636 any
.a_void
= 0; /* zero out all bits */
1637 for (i
= 0; i
< ROLE_ALIGNS
; i
++)
1638 if (ok_align(flags
.initrole
, flags
.initrace
,
1639 flags
.initgend
, i
)) {
1641 add_menu(win
, NO_GLYPH
, &any
, aligns
[i
].adj
[0], 0,
1642 ATR_NONE
, aligns
[i
].adj
,
1645 any
.a_int
= pick_align(flags
.initrole
, flags
.initrace
,
1646 flags
.initgend
, PICK_RANDOM
) + 1;
1647 if (any
.a_int
== 0) /* must be non-zero */
1649 randalign(flags
.initrole
, flags
.initrace
) + 1;
1650 add_menu(win
, NO_GLYPH
, &any
, '*', 0, ATR_NONE
, "Random",
1652 any
.a_int
= i
+ 1; /* must be non-zero */
1653 add_menu(win
, NO_GLYPH
, &any
, 'q', 0, ATR_NONE
, "Quit",
1655 Sprintf(pbuf
, "Pick the alignment of your %s", plbuf
);
1656 end_menu(win
, pbuf
);
1657 n
= select_menu(win
, PICK_ONE
, &selected
);
1658 destroy_nhwindow(win
);
1659 if (n
!= 1 || selected
[0].item
.a_int
== any
.a_int
)
1660 goto give_up
; /* Selected quit */
1662 k
= selected
[0].item
.a_int
- 1;
1663 free((genericptr_t
) selected
), selected
= 0;
1665 flags
.initalign
= k
;
1670 #endif /* AMIGA_INTUITION */