/* SCCS Id: @(#)wingem.c 3.4 1999/12/10 */ /* Copyright (c) Christian Bressler, 1999 */ /* NetHack may be freely redistributed. See license for details. */ #include "hack.h" #include "func_tab.h" #include "dlb.h" #include #ifdef SHORT_FILENAMES #include "patchlev.h" #else #include "patchlevel.h" #endif #ifdef GEM_GRAPHICS #include "wingem.h" static char nullstr[] = "", winpanicstr[] = "Bad window id %d"; static int curr_status_line; static char *FDECL(copy_of, (const char *)); static void FDECL(bail, (const char *)); /* __attribute__((noreturn)) */ extern int mar_set_tile_mode(int); extern void mar_set_font(int,const char*,int); extern void mar_set_margin(int); extern void mar_set_msg_visible(int); extern void mar_set_status_align(int); extern void mar_set_msg_align(int); extern void mar_set_tilefile(char *); extern void mar_set_tilex(int); extern void mar_set_tiley(int); extern short glyph2tile[MAX_GLYPH]; /* from tile.c */ extern void mar_display_nhwindow(winid); /* from wingem1.c */ void Gem_outrip(winid,int); void Gem_preference_update(const char *); /* Interface definition, for windows.c */ struct window_procs Gem_procs = { "Gem", WC_COLOR|WC_HILITE_PET|WC_ALIGN_MESSAGE|WC_ALIGN_STATUS| WC_INVERSE|WC_SCROLL_MARGIN| WC_FONT_MESSAGE|WC_FONT_STATUS|WC_FONT_MENU|WC_FONT_TEXT|WC_FONT_MAP| WC_FONTSIZ_MESSAGE|WC_FONTSIZ_STATUS|WC_FONTSIZ_MENU|WC_FONTSIZ_TEXT|WC_FONTSIZ_MAP| WC_TILE_WIDTH|WC_TILE_HEIGHT|WC_TILE_FILE|WC_VARY_MSGCOUNT|WC_ASCII_MAP, 0L, Gem_init_nhwindows, Gem_player_selection, Gem_askname, Gem_get_nh_event, Gem_exit_nhwindows, Gem_suspend_nhwindows, Gem_resume_nhwindows, Gem_create_nhwindow, Gem_clear_nhwindow, Gem_display_nhwindow, Gem_destroy_nhwindow, Gem_curs, Gem_putstr, Gem_display_file, Gem_start_menu, Gem_add_menu, Gem_end_menu, Gem_select_menu, genl_message_menu, Gem_update_inventory, Gem_mark_synch, Gem_wait_synch, #ifdef CLIPPING Gem_cliparound, #endif #ifdef POSITIONBAR Gem_update_positionbar, #endif Gem_print_glyph, Gem_raw_print, Gem_raw_print_bold, Gem_nhgetch, Gem_nh_poskey, Gem_nhbell, Gem_doprev_message, Gem_yn_function, Gem_getlin, Gem_get_ext_cmd, Gem_number_pad, Gem_delay_output, #ifdef CHANGE_COLOR /* the Mac uses a palette device */ Gem_change_color, #ifdef MAC Gem_change_background, Gem_set_font_name, #endif Gem_get_color_string, #endif /* other defs that really should go away (they're tty specific) */ Gem_start_screen, Gem_end_screen, Gem_outrip, Gem_preference_update }; #ifdef MAC void * Gem_change_background(dummy) int dummy; {} short * Gem_set_font_name(foo,bar) winid foo; char *bar; {} #endif /*************************** Proceduren *************************************/ int mar_hp_query(void){ if(Upolyd) return(u.mh ? u.mhmax/u.mh : -1); return(u.uhp ? u.uhpmax/u.uhp : -1); } int mar_iflags_numpad() { return(iflags.num_pad ? 1 : 0); } int mar_get_msg_history() { return(iflags.msg_history); } int mar_get_msg_visible() { return(iflags.wc_vary_msgcount); } /* clean up and quit */ static void bail(mesg) const char *mesg; { clearlocks(); Gem_exit_nhwindows(mesg); terminate(EXIT_SUCCESS); /*NOTREACHED*/ } /*$$$*/ #define DEF_CLIPAROUND_MARGIN -1 #ifndef TILE_X #define TILE_X 16 #endif #define TILE_Y 16 #define TILES_PER_LINE 20 #define NHFONT_DEFAULT_SIZE 10 #define NHFONT_SIZE_MIN 3 #define NHFONT_SIZE_MAX 20 /*$$$*/ /*ARGSUSED*/ void Gem_init_nhwindows(argcp,argv) int* argcp; char** argv; { argv=argv, argcp=argcp; colors_changed=TRUE; set_wc_option_mod_status( WC_ALIGN_MESSAGE | WC_ALIGN_STATUS | WC_TILE_WIDTH | WC_TILE_HEIGHT | WC_TILE_FILE, DISP_IN_GAME); set_wc_option_mod_status( WC_HILITE_PET | WC_SCROLL_MARGIN | WC_FONT_MESSAGE | WC_FONT_MAP | WC_FONT_STATUS | WC_FONT_MENU | WC_FONT_TEXT | WC_FONTSIZ_MESSAGE | WC_FONTSIZ_MAP | WC_FONTSIZ_STATUS | WC_FONTSIZ_MENU | WC_FONTSIZ_TEXT | WC_VARY_MSGCOUNT, SET_IN_GAME ); if( iflags.wc_align_message==0 ) iflags.wc_align_message = ALIGN_TOP; if( iflags.wc_align_status==0 ) iflags.wc_align_status = ALIGN_BOTTOM; if( iflags.wc_scroll_margin==0 ) iflags.wc_scroll_margin = DEF_CLIPAROUND_MARGIN; if( iflags.wc_tile_width==0 ) iflags.wc_tile_width = TILE_X; if( iflags.wc_tile_height==0 ) iflags.wc_tile_height = TILE_Y; if(iflags.wc_tile_file && *iflags.wc_tile_file) mar_set_tilefile(iflags.wc_tile_file); if( iflags.wc_vary_msgcount==0 ) iflags.wc_vary_msgcount = 3; mar_set_tile_mode(!iflags.wc_ascii_map); /* MAR -- 17.Mar 2002 True is tiles */ mar_set_tilex(iflags.wc_tile_width); mar_set_tiley(iflags.wc_tile_height); mar_set_msg_align(iflags.wc_align_message-ALIGN_BOTTOM); mar_set_status_align(iflags.wc_align_status-ALIGN_BOTTOM); if(mar_gem_init()==0){ bail((char *)0); /*NOTREACHED*/ } iflags.window_inited = TRUE; CO=80; /* MAR -- whatsoever */ LI=25; add_menu_cmd_alias(' ', MENU_NEXT_PAGE); mar_set_no_glyph(NO_GLYPH); } void Gem_player_selection() { int i, k, n; char pick4u = 'n', pbuf[QBUFSZ], lastch=0, currch; winid win; anything any; menu_item *selected=NULL; /* avoid unnecessary prompts further down */ rigid_role_checks(); /* Should we randomly pick for the player? */ if (!flags.randomall && (flags.initrole == ROLE_NONE || flags.initrace == ROLE_NONE || flags.initgend == ROLE_NONE || flags.initalign == ROLE_NONE)) { /* pick4u = yn_function("Shall I pick a character for you? [ynq]",ynqchars,'n');*/ pick4u = yn_function( build_plselection_prompt(pbuf, QBUFSZ, flags.initrole,flags.initrace, flags.initgend, flags.initalign) ,ynqchars,'n' ); if(pick4u=='q'){ give_up: /* Just quit */ if (selected) free((genericptr_t) selected); bail((char *)0); /*NOTREACHED*/ return; } } /* Select a role, if necessary */ if (flags.initrole < 0) { /* Process the choice */ if(pick4u=='y' || flags.initrole == ROLE_RANDOM || flags.randomall) { /* Pick a random role */ flags.initrole = pick_role(flags.initrace, flags.initgend, flags.initalign, PICK_RANDOM); if (flags.initrole < 0) { mar_add_message("Incompatible role!"); mar_display_nhwindow(WIN_MESSAGE); flags.initrole = randrole(); } }else{ /* Prompt for a role */ win = create_nhwindow(NHW_MENU); start_menu(win); any.a_void = 0; /* zero out all bits */ for (i = 0; roles[i].name.m; i++) { if (ok_role(i, flags.initrace, flags.initgend, flags.initalign)) { any.a_int = i+1; /* must be non-zero */ currch = lowc(roles[i].name.m[0]); if(currch == lastch) currch = highc(currch); add_menu(win, roles[i].malenum, &any, currch, 0, ATR_NONE, an(roles[i].name.m), MENU_UNSELECTED); lastch = currch; } } any.a_int = pick_role(flags.initrace, flags.initgend, flags.initalign, PICK_RANDOM)+1; if (any.a_int == 0) /* must be non-zero */ any.a_int = randrole()+1; add_menu(win, NO_GLYPH, &any , '*', 0, ATR_NONE, "Random", MENU_UNSELECTED); any.a_int = i+1; /* must be non-zero */ add_menu(win, NO_GLYPH, &any , 'q', 0, ATR_NONE, "Quit", MENU_UNSELECTED); end_menu(win, "Pick a role"); n = select_menu(win, PICK_ONE, &selected); destroy_nhwindow(win); /* Process the choice */ if (n != 1 || selected[0].item.a_int == any.a_int) goto give_up; /* Selected quit */ flags.initrole = selected[0].item.a_int - 1; free((genericptr_t) selected), selected = 0; } } /* Select a race, if necessary */ /* force compatibility with role, try for compatibility with * pre-selected gender/alignment */ if (flags.initrace < 0 || !validrace(flags.initrole, flags.initrace)) { /* pre-selected race not valid */ if (pick4u == 'y' || flags.initrace == ROLE_RANDOM || flags.randomall) { flags.initrace = pick_race(flags.initrole, flags.initgend, flags.initalign, PICK_RANDOM); if (flags.initrace < 0) { mar_add_message("Incompatible race!"); mar_display_nhwindow(WIN_MESSAGE); flags.initrace = randrace(flags.initrole); } } else { /* pick4u == 'n' */ /* Count the number of valid races */ n = 0; /* number valid */ k = 0; /* valid race */ for (i = 0; races[i].noun; i++) { if (ok_race(flags.initrole, i, flags.initgend, flags.initalign)) { n++; k = i; } } if (n == 0) { for (i = 0; races[i].noun; i++) { if (validrace(flags.initrole, i)) { n++; k = i; } } } /* Permit the user to pick, if there is more than one */ if (n > 1) { win = create_nhwindow(NHW_MENU); start_menu(win); any.a_void = 0; /* zero out all bits */ for (i = 0; races[i].noun; i++) if (ok_race(flags.initrole, i, flags.initgend, flags.initalign)) { any.a_int = i+1; /* must be non-zero */ add_menu(win, NO_GLYPH, &any, races[i].noun[0], 0, ATR_NONE, races[i].noun, MENU_UNSELECTED); } any.a_int = pick_race(flags.initrole, flags.initgend, flags.initalign, PICK_RANDOM)+1; if (any.a_int == 0) /* must be non-zero */ any.a_int = randrace(flags.initrole)+1; add_menu(win, NO_GLYPH, &any , '*', 0, ATR_NONE, "Random", MENU_UNSELECTED); any.a_int = i+1; /* must be non-zero */ add_menu(win, NO_GLYPH, &any , 'q', 0, ATR_NONE, "Quit", MENU_UNSELECTED); Sprintf(pbuf, "Pick the race of your %s", roles[flags.initrole].name.m); end_menu(win, pbuf); n = select_menu(win, PICK_ONE, &selected); destroy_nhwindow(win); if (n != 1 || selected[0].item.a_int == any.a_int) goto give_up; /* Selected quit */ k = selected[0].item.a_int - 1; free((genericptr_t) selected), selected = 0; } flags.initrace = k; } } /* Select a gender, if necessary */ /* force compatibility with role/race, try for compatibility with * pre-selected alignment */ if (flags.initgend < 0 || !validgend(flags.initrole, flags.initrace, flags.initgend)) { /* pre-selected gender not valid */ if (pick4u == 'y' || flags.initgend == ROLE_RANDOM || flags.randomall) { flags.initgend = pick_gend(flags.initrole, flags.initrace, flags.initalign, PICK_RANDOM); if (flags.initgend < 0) { mar_add_message("Incompatible gender!"); mar_display_nhwindow(WIN_MESSAGE); flags.initgend = randgend(flags.initrole, flags.initrace); } } else { /* pick4u == 'n' */ /* Count the number of valid genders */ n = 0; /* number valid */ k = 0; /* valid gender */ for (i = 0; i < ROLE_GENDERS; i++) { if (ok_gend(flags.initrole, flags.initrace, i, flags.initalign)) { n++; k = i; } } if (n == 0) { for (i = 0; i < ROLE_GENDERS; i++) { if (validgend(flags.initrole, flags.initrace, i)) { n++; k = i; } } } /* Permit the user to pick, if there is more than one */ if (n > 1) { win = create_nhwindow(NHW_MENU); start_menu(win); any.a_void = 0; /* zero out all bits */ for (i = 0; i < ROLE_GENDERS; i++) if (ok_gend(flags.initrole, flags.initrace, i, flags.initalign)) { any.a_int = i+1; add_menu(win, NO_GLYPH, &any, genders[i].adj[0], 0, ATR_NONE, genders[i].adj, MENU_UNSELECTED); } any.a_int = pick_gend(flags.initrole, flags.initrace, flags.initalign, PICK_RANDOM)+1; if (any.a_int == 0) /* must be non-zero */ any.a_int = randgend(flags.initrole, flags.initrace)+1; add_menu(win, NO_GLYPH, &any , '*', 0, ATR_NONE, "Random", MENU_UNSELECTED); any.a_int = i+1; /* must be non-zero */ add_menu(win, NO_GLYPH, &any , 'q', 0, ATR_NONE, "Quit", MENU_UNSELECTED); Sprintf(pbuf, "Pick the gender of your %s %s", races[flags.initrace].adj, roles[flags.initrole].name.m); end_menu(win, pbuf); n = select_menu(win, PICK_ONE, &selected); destroy_nhwindow(win); if (n != 1 || selected[0].item.a_int == any.a_int) goto give_up; /* Selected quit */ k = selected[0].item.a_int - 1; free((genericptr_t) selected), selected = 0; } flags.initgend = k; } } /* Select an alignment, if necessary */ /* force compatibility with role/race/gender */ if (flags.initalign < 0 || !validalign(flags.initrole, flags.initrace, flags.initalign)) { /* pre-selected alignment not valid */ if (pick4u == 'y' || flags.initalign == ROLE_RANDOM || flags.randomall) { flags.initalign = pick_align(flags.initrole, flags.initrace, flags.initgend, PICK_RANDOM); if (flags.initalign < 0) { mar_add_message("Incompatible alignment!"); mar_display_nhwindow(WIN_MESSAGE); flags.initalign = randalign(flags.initrole, flags.initrace); } } else { /* pick4u == 'n' */ /* Count the number of valid alignments */ n = 0; /* number valid */ k = 0; /* valid alignment */ for (i = 0; i < ROLE_ALIGNS; i++) { if (ok_align(flags.initrole, flags.initrace, flags.initgend, i)) { n++; k = i; } } if (n == 0) { for (i = 0; i < ROLE_ALIGNS; i++) { if (validalign(flags.initrole, flags.initrace, i)) { n++; k = i; } } } /* Permit the user to pick, if there is more than one */ if (n > 1) { win = create_nhwindow(NHW_MENU); start_menu(win); any.a_void = 0; /* zero out all bits */ for (i = 0; i < ROLE_ALIGNS; i++) if (ok_align(flags.initrole, flags.initrace, flags.initgend, i)) { any.a_int = i+1; add_menu(win, NO_GLYPH, &any, aligns[i].adj[0], 0, ATR_NONE, aligns[i].adj, MENU_UNSELECTED); } any.a_int = pick_align(flags.initrole, flags.initrace, flags.initgend, PICK_RANDOM)+1; if (any.a_int == 0) /* must be non-zero */ any.a_int = randalign(flags.initrole, flags.initrace)+1; add_menu(win, NO_GLYPH, &any , '*', 0, ATR_NONE, "Random", MENU_UNSELECTED); any.a_int = i+1; /* must be non-zero */ add_menu(win, NO_GLYPH, &any , 'q', 0, ATR_NONE, "Quit", MENU_UNSELECTED); Sprintf(pbuf, "Pick the alignment of your %s %s %s", genders[flags.initgend].adj, races[flags.initrace].adj, (flags.initgend && roles[flags.initrole].name.f) ? roles[flags.initrole].name.f : roles[flags.initrole].name.m); end_menu(win, pbuf); n = select_menu(win, PICK_ONE, &selected); destroy_nhwindow(win); if (n != 1 || selected[0].item.a_int == any.a_int) goto give_up; /* Selected quit */ k = selected[0].item.a_int - 1; free((genericptr_t) selected), selected = 0; } flags.initalign = k; } } /* Success! */ return; } /* * plname is filled either by an option (-u Player or -uPlayer) or * explicitly (by being the wizard) or by askname. * It may still contain a suffix denoting pl_character. * Always called after init_nhwindows() and before display_gamewindows(). */ void Gem_askname() { strncpy(plname,mar_ask_name(),PL_NSIZ); } void Gem_get_nh_event() {} void Gem_suspend_nhwindows(str) const char *str; { const char *foo; foo=str; /* MAR -- And the compiler whines no more ... */ } void Gem_resume_nhwindows() {} void Gem_end_screen() {} void Gem_start_screen() {} extern void mar_exit_nhwindows(void); extern boolean run_from_desktop; void Gem_exit_nhwindows(str) const char *str; { if(str) Gem_raw_print(str); mar_exit_nhwindows(); if(flags.toptenwin) run_from_desktop=FALSE; iflags.window_inited = 0; } winid Gem_create_nhwindow(type) int type; { winid newid; switch(type) { case NHW_MESSAGE: if(iflags.msg_history < 20) iflags.msg_history = 20; else if(iflags.msg_history > 60) iflags.msg_history = 60; break; case NHW_STATUS: case NHW_MAP: case NHW_MENU: case NHW_TEXT: break; default: panic("Tried to create window type %d\n", (int) type); return WIN_ERR; } newid=mar_create_window(type); if(newid == MAXWIN) { panic("No window slots!"); /* NOTREACHED */ } return newid; } void Gem_nhbell() { if (flags.silent) return; putchar('\007'); fflush(stdout); } extern void mar_clear_map(void); void Gem_clear_nhwindow(window) winid window; { if(window == WIN_ERR) panic(winpanicstr, window); switch(mar_hol_win_type(window)) { case NHW_MESSAGE: mar_clear_messagewin(); break; case NHW_MAP: mar_clear_map(); break; case NHW_STATUS: case NHW_MENU: case NHW_TEXT: break; } } extern void mar_more(void); /*ARGSUSED*/ void Gem_display_nhwindow(window, blocking) winid window; boolean blocking; { if(window == WIN_ERR) panic(winpanicstr, window); mar_display_nhwindow(window); switch(mar_hol_win_type(window)){ case NHW_MESSAGE: if(blocking) mar_more(); break; case NHW_MAP: if(blocking) Gem_display_nhwindow(WIN_MESSAGE, TRUE); break; case NHW_STATUS: case NHW_TEXT: case NHW_MENU: default: break; } } void Gem_destroy_nhwindow(window) winid window; { if(window == WIN_ERR) /* MAR -- test existence */ panic(winpanicstr, window); mar_destroy_nhwindow(window); } extern void mar_curs(int,int); /* mar_curs is only for map */ void Gem_curs(window, x, y) winid window; register int x, y; { if(window == WIN_ERR) /* MAR -- test existence */ panic(winpanicstr, window); if(window==WIN_MAP) mar_curs(x-1,y); /*$$$*/ else if(window==WIN_STATUS) curr_status_line=y; } extern void mar_add_status_str(const char *, int); extern void mar_putstr_text(winid, int, const char *); void Gem_putstr(window, attr, str) winid window; int attr; const char *str; { int win_type; if(window == WIN_ERR) { Gem_raw_print(str); return; } if(str == (const char*)0) return; switch((win_type=mar_hol_win_type(window))) { case NHW_MESSAGE: mar_add_message(str); break; case NHW_STATUS: mar_status_dirty(); mar_add_status_str(str,curr_status_line); if(curr_status_line) mar_display_nhwindow(WIN_STATUS); break; case NHW_MAP: if(strcmp(str,".")) Gem_putstr(WIN_MESSAGE,0,str); else mar_map_curs_weiter(); mar_display_nhwindow(WIN_MESSAGE); mar_display_nhwindow(WIN_STATUS); break; case NHW_MENU: mar_change_menu_2_text(window); /* Fallthru */ case NHW_TEXT: mar_putstr_text(window,attr,str); break; } /* endswitch win_type */ } void Gem_display_file(fname, complain) const char *fname; boolean complain; { dlb *f; char buf[BUFSZ]; char *cr; f = dlb_fopen(fname, "r"); if (!f) { if(complain) pline("Cannot open \"%s\".", fname); } else { winid datawin; datawin = Gem_create_nhwindow(NHW_TEXT); while (dlb_fgets(buf, BUFSZ, f)) { if ((cr = index(buf, '\n')) != 0) *cr = 0; if (index(buf, '\t') != 0) (void) tabexpand(buf); Gem_putstr(datawin, 0, buf); } (void) dlb_fclose(f); Gem_display_nhwindow(datawin, FALSE); Gem_destroy_nhwindow(datawin); } } /*ARGSUSED*/ /* * Add a menu item to the beginning of the menu list. This list is reversed * later. */ void Gem_add_menu(window, glyph, identifier, ch, gch, attr, str, preselected) winid window; /* window to use, must be of type NHW_MENU */ int glyph; /* glyph to display with item (unused) */ const anything *identifier; /* what to return if selected */ char ch; /* keyboard accelerator (0 = pick our own) */ char gch; /* group accelerator (0 = no group) */ int attr; /* attribute for string (like Gem_putstr()) */ const char *str; /* menu string */ boolean preselected; /* item is marked as selected */ { Gem_menu_item *G_item; const char *newstr; char buf[QBUFSZ]; if (str == (const char*) 0) return; if (window == WIN_ERR) /* MAR -- test existence */ panic(winpanicstr, window); if (identifier->a_void) Sprintf(buf, "%c - %s", ch ? ch : '?', str); else Sprintf(buf, "%s", str); newstr = buf; G_item = (Gem_menu_item *) alloc(sizeof(Gem_menu_item)); G_item->Gmi_identifier = (long)identifier->a_void; G_item->Gmi_glyph = glyph!=NO_GLYPH ? glyph2tile[glyph] : NO_GLYPH; G_item->Gmi_count = -1L; G_item->Gmi_selected = preselected ? 1 : 0; G_item->Gmi_accelerator = ch; G_item->Gmi_groupacc = gch; G_item->Gmi_attr = attr; G_item->Gmi_str = copy_of(newstr); mar_add_menu(window, G_item); } /* * End a menu in this window, window must a type NHW_MENU. * We assign the keyboard accelerators as needed. */ void Gem_end_menu(window, prompt) winid window; /* menu to use */ const char *prompt; /* prompt to for menu */ { if(window == WIN_ERR || mar_hol_win_type(window) != NHW_MENU) panic(winpanicstr, window); /* Reverse the list so that items are in correct order. */ mar_reverse_menu(); /* Put the prompt at the beginning of the menu. */ mar_set_menu_title(prompt); mar_set_accelerators(); } int Gem_select_menu(window, how, menu_list) winid window; int how; menu_item **menu_list; { Gem_menu_item *Gmit; menu_item *mi; int n; if(window == WIN_ERR || mar_hol_win_type(window) != NHW_MENU) panic(winpanicstr, window); *menu_list = (menu_item *) 0; mar_set_menu_type(how); Gem_display_nhwindow(window, TRUE); for (n = 0, Gmit = mar_hol_inv(); Gmit; Gmit = Gmit->Gmi_next) if (Gmit->Gmi_selected) n++; if (n > 0) { *menu_list = (menu_item *) alloc(n * sizeof(menu_item)); for (mi = *menu_list, Gmit = mar_hol_inv(); Gmit; Gmit = Gmit->Gmi_next) if (Gmit->Gmi_selected) { mi->item = (anything)(genericptr_t)Gmit->Gmi_identifier; mi->count = Gmit->Gmi_count; mi++; } } return n; } void Gem_update_inventory() {} void Gem_mark_synch() { mar_display_nhwindow(WIN_MESSAGE); mar_display_nhwindow(WIN_MAP); mar_display_nhwindow(WIN_STATUS); } void Gem_wait_synch() { mar_display_nhwindow(WIN_MESSAGE); mar_display_nhwindow(WIN_MAP); mar_display_nhwindow(WIN_STATUS); } #ifdef CLIPPING extern void mar_cliparound(void); void Gem_cliparound(x, y) int x, y; { mar_curs(x-1,y); mar_cliparound(); } #endif /* CLIPPING */ /* * Gem_print_glyph * * Print the glyph to the output device. Don't flush the output device. * * Since this is only called from show_glyph(), it is assumed that the * position and glyph are always correct (checked there)! */ void mar_print_gl_char(winid,xchar,xchar,int); #ifdef REINCARNATION extern int mar_set_rogue(int); #endif extern void mar_add_pet_sign(winid,int,int); void Gem_print_glyph(window, x, y, glyph) winid window; xchar x, y; int glyph; { /* Move the cursor. */ Gem_curs(window, x,y); # ifdef REINCARNATION mar_set_rogue(Is_rogue_level(&u.uz) ? TRUE : FALSE); # endif x--; /* MAR -- because x ranges from 1 to COLNO */ if(mar_set_tile_mode(-1)){ mar_print_glyph(window,x,y,glyph2tile[glyph]); if( #ifdef TEXTCOLOR iflags.hilite_pet && #endif glyph_is_pet(glyph) ) mar_add_pet_sign(window,x,y); }else mar_print_gl_char(window,x,y,glyph); } void mar_print_char(winid,xchar,xchar,char,int); void mar_print_gl_char(window, x, y, glyph) winid window; xchar x, y; int glyph; { int ch; int color; unsigned special; /* map glyph to character and color */ mapglyph(glyph, &ch, &color, &special, x, y); #ifdef TEXTCOLOR /* Turn off color if rogue level. */ # ifdef REINCARNATION if (Is_rogue_level(&u.uz)) color = NO_COLOR; # endif #endif /* TEXTCOLOR */ mar_print_char(window,x,y,ch,color); } extern void mar_raw_print(const char *); extern void mar_raw_print_bold(const char *); void Gem_raw_print(str) const char *str; { if(str && *str){ if(iflags.window_inited) mar_raw_print(str); else printf("%s\n",str); } } void Gem_raw_print_bold(str) const char *str; { if(str && *str){ if(iflags.window_inited) mar_raw_print_bold(str); else printf("%s\n",str); } } extern void mar_update_value(void); /* wingem1.c */ int Gem_nhgetch() { int i; mar_update_value(); i = tgetch(); if (!i) i = '\033'; /* map NUL to ESC since nethack doesn't expect NUL */ return i; } /* Get a extended command in windowport specific way. returns index of the ext_cmd or -1. called after '#'. It's a menu with all the possibilities. */ int Gem_get_ext_cmd() { winid wind; int i, count, what,too_much=FALSE; menu_item *selected=NULL; anything any; char accelerator=0, tmp_acc=0; const char *ptr; wind=Gem_create_nhwindow(NHW_MENU); Gem_start_menu(wind); for(i=0;(ptr=extcmdlist[i].ef_txt);i++){ any.a_int=i; accelerator=*ptr; if(tmp_acc==accelerator){ if(too_much) accelerator='&'; /* MAR -- poor choice, anyone? */ else accelerator+='A'-'a'; too_much=TRUE; }else too_much=FALSE; tmp_acc=*ptr; Gem_add_menu(wind,NO_GLYPH,&any,accelerator,0,ATR_NONE,ptr,FALSE); } Gem_end_menu(wind,"What extended command?"); count=Gem_select_menu(wind,PICK_ONE,&selected); what = count ? selected->item.a_int : -1; if(selected) free(selected); Gem_destroy_nhwindow(wind); return(what); } void Gem_number_pad(state) int state; { state=state; } void win_Gem_init() {} #ifdef POSITIONBAR void Gem_update_positionbar(posbar) char *posbar; {} #endif /** Gem_outrip **/ void mar_set_text_to_rip(winid); char** rip_line=0; extern const char *killed_by_prefix[]; void Gem_outrip(w, how) winid w; int how; { /* Code from X11 windowport */ #define STONE_LINE_LEN 15 /* # chars that fit on one line */ #define NAME_LINE 0 /* line # for player name */ #define GOLD_LINE 1 /* line # for amount of gold */ #define DEATH_LINE 2 /* line # for death description */ #define YEAR_LINE 6 /* line # for year */ char buf[BUFSZ]; char *dpx; int line; if (!rip_line) { int i; rip_line= (char **)malloc((YEAR_LINE+1)*sizeof(char *)); for (i=0; i STONE_LINE_LEN) { for(i = STONE_LINE_LEN; ((i0 > STONE_LINE_LEN) && i); i--) if(dpx[i] == ' ') i0 = i; if(!i) i0 = STONE_LINE_LEN; } tmpchar = dpx[i0]; dpx[i0] = 0; strcpy(rip_line[line], dpx); if (tmpchar != ' ') { dpx[i0] = tmpchar; dpx= &dpx[i0]; } else dpx= &dpx[i0+1]; } /* Put year on stone */ Sprintf(rip_line[YEAR_LINE], "%4d", getyear()); mar_set_text_to_rip(w); for(line=0;line<13;line++) putstr(w, 0, ""); } void mar_get_font(type,p_fname,psize) int type; char **p_fname; int *psize; { switch(type){ case NHW_MESSAGE: *p_fname=iflags.wc_font_message; *psize=iflags.wc_fontsiz_message; break; case NHW_MAP: *p_fname=iflags.wc_font_map; *psize=iflags.wc_fontsiz_map; break; case NHW_STATUS: *p_fname=iflags.wc_font_status; *psize=iflags.wc_fontsiz_status; break; case NHW_MENU: *p_fname=iflags.wc_font_menu; *psize=iflags.wc_fontsiz_menu; break; case NHW_TEXT: *p_fname=iflags.wc_font_text; *psize=iflags.wc_fontsiz_text; break; default: break; } } void Gem_preference_update(pref) const char *pref; { if( stricmp( pref, "font_message")==0 || stricmp( pref, "font_size_message")==0 ) { if( iflags.wc_fontsiz_messageNHFONT_SIZE_MAX ) iflags.wc_fontsiz_message = NHFONT_DEFAULT_SIZE; mar_set_font(NHW_MESSAGE,iflags.wc_font_message,iflags.wc_fontsiz_message); return; } if( stricmp( pref, "font_map")==0 || stricmp( pref, "font_size_map")==0 ) { if( iflags.wc_fontsiz_mapNHFONT_SIZE_MAX ) iflags.wc_fontsiz_map = NHFONT_DEFAULT_SIZE; mar_set_font(NHW_MAP,iflags.wc_font_map,iflags.wc_fontsiz_map); return; } if( stricmp( pref, "font_status")==0 || stricmp( pref, "font_size_status")==0 ) { if( iflags.wc_fontsiz_statusNHFONT_SIZE_MAX ) iflags.wc_fontsiz_status = NHFONT_DEFAULT_SIZE; mar_set_font(NHW_STATUS,iflags.wc_font_status,iflags.wc_fontsiz_status); return; } if( stricmp( pref, "font_menu")==0 || stricmp( pref, "font_size_menu")==0 ) { if( iflags.wc_fontsiz_menuNHFONT_SIZE_MAX ) iflags.wc_fontsiz_menu = NHFONT_DEFAULT_SIZE; mar_set_font(NHW_MENU,iflags.wc_font_menu,iflags.wc_fontsiz_menu); return; } if( stricmp( pref, "font_text")==0 || stricmp( pref, "font_size_text")==0 ) { if( iflags.wc_fontsiz_textNHFONT_SIZE_MAX ) iflags.wc_fontsiz_text = NHFONT_DEFAULT_SIZE; mar_set_font(NHW_TEXT,iflags.wc_font_text,iflags.wc_fontsiz_text); return; } if( stricmp( pref, "scroll_margin")==0 ) { mar_set_margin(iflags.wc_scroll_margin); Gem_cliparound(u.ux, u.uy); return; } if( stricmp( pref, "ascii_map")==0 ) { mar_set_tile_mode(!iflags.wc_ascii_map); doredraw(); return; } if( stricmp( pref, "hilite_pet")==0 ){ /* MAR -- works without doing something here. */ return; } if( stricmp( pref, "align_message")==0){ mar_set_msg_align(iflags.wc_align_message-ALIGN_BOTTOM); return; } if(stricmp( pref, "align_status")==0 ){ mar_set_status_align(iflags.wc_align_status-ALIGN_BOTTOM); return; } if( stricmp( pref, "vary_msgcount")==0 ){ mar_set_msg_visible(iflags.wc_vary_msgcount); return; } } /* * Allocate a copy of the given string. If null, return a string of * zero length. * * This is an exact duplicate of copy_of() in X11/winmenu.c. */ static char * copy_of(s) const char *s; { if (!s) s = nullstr; return strcpy((char *) alloc((unsigned) (strlen(s) + 1)), s); } #endif /* GEM_GRAPHICS /*wingem.c*/