/* SCCS Id: @(#)wingem1.c 3.3 1999/12/10 */ /* Copyright (c) Christian Bressler 1999 */ /* NetHack may be freely redistributed. See license for details. */ #define __TCC_COMPAT__ #include #include #include #include #include #include #include "gem_rsc.h" #include "load_img.h" #define genericptr_t void * #include "wintype.h" #undef genericptr_t #define NDECL(f) f(void) #define FDECL(f,p) f p #define CHAR_P char #define SCHAR_P schar #define UCHAR_P uchar #define XCHAR_P xchar #define SHORT_P short #define BOOLEAN_P boolean #define ALIGNTYP_P aligntyp typedef signed char xchar; #include "wingem.h" #undef CHAR_P #undef SCHAR_P #undef UCHAR_P #undef XCHAR_P #undef SHORT_P #undef BOOLEAN_P #undef ALIGNTYP_P #undef NDECL #undef FDECL static char nullstr[]="", md[]="NetHack 3.3.1", strCancel[]="Cancel", strOk[]="Ok", strText[]="Text"; extern winid WIN_MESSAGE, WIN_MAP, WIN_STATUS, WIN_INVEN; #define MAXWIN 20 #define ROWNO 21 #define COLNO 80 #define MAP_GADGETS NAME|MOVER|CLOSER|FULLER|LFARROW|RTARROW|UPARROW|DNARROW|VSLIDE|HSLIDE|SIZER|SMALLER #define DIALOG_MODE AUTO_DIAL|MODAL|NO_ICONIFY /* * Keyboard translation tables. */ #define C(c) (0x1f & (c)) #define M(c) (0x80 | (c)) #define KEYPADLO 0x61 #define KEYPADHI 0x71 #define PADKEYS (KEYPADHI - KEYPADLO + 1) #define iskeypad(x) (KEYPADLO <= (x) && (x) <= KEYPADHI) /* * Keypad keys are translated to the normal values below. * When iflags.BIOS is active, shifted keypad keys are translated to the * shift values below. */ static const struct pad { char normal, shift, cntrl; } keypad[PADKEYS] = { {C('['), 'Q', C('[')}, /* UNDO */ {'?', '/', '?'}, /* HELP */ {'(', 'a', '('}, /* ( */ {')', 'w', ')'}, /* ) */ {'/', '/', '/'}, /* / */ {C('p'), '$', C('p')}, /* * */ {'y', 'Y', C('y')}, /* 7 */ {'k', 'K', C('k')}, /* 8 */ {'u', 'U', C('u')}, /* 9 */ {'h', 'H', C('h')}, /* 4 */ {'.', '.', '.'}, {'l', 'L', C('l')}, /* 6 */ {'b', 'B', C('b')}, /* 1 */ {'j', 'J', C('j')}, /* 2 */ {'n', 'N', C('n')}, /* 3 */ {'i', 'I', C('i')}, /* Ins */ {'.', ':', ':'} /* Del */ }, numpad[PADKEYS] = { {C('['), 'Q', C('[')} , /* UNDO */ {'?', '/', '?'}, /* HELP */ {'(', 'a', '('}, /* ( */ {')', 'w', ')'}, /* ) */ {'/', '/', '/'}, /* / */ {C('p'), '$', C('p')}, /* * */ {'7', M('7'), '7'}, /* 7 */ {'8', M('8'), '8'}, /* 8 */ {'9', M('9'), '9'}, /* 9 */ {'4', M('4'), '4'}, /* 4 */ {'.', '.', '.'}, /* 5 */ {'6', M('6'), '6'}, /* 6 */ {'1', M('1'), '1'}, /* 1 */ {'2', M('2'), '2'}, /* 2 */ {'3', M('3'), '3'}, /* 3 */ {'i', 'I', C('i')}, /* Ins */ {'.', ':', ':'} /* Del */ }; #define TBUFSZ 300 #define BUFSZ 256 extern int yn_number; /* from decl.c */ extern char toplines[TBUFSZ]; /* from decl.c */ extern char mapped_menu_cmds[]; /* from options.c */ extern int mar_iflags_numpad(void); /* from wingem.c */ extern void Gem_raw_print(const char *); /* from wingem.c */ extern int mar_hp_query(void); /* from wingem.c */ extern int mar_get_msg_history(void); /* from wingem.c */ extern int vdi2dev4[]; /* from load_img.c */ static int no_glyph; /* the int indicating there is no glyph */ IMG_header tile_image, titel_image, rip_image; MFDB Tile_bilder, Map_bild, Titel_bild, Rip_bild, Black_bild, Pet_Mark; /* pet_mark Design by Warwick Allison warwick@troll.no */ static int pet_mark_data[]={0x0000,0x3600,0x7F00,0x7F00,0x3E00,0x1C00,0x0800}; static short *normal_palette=NULL; static struct gw{ WIN *gw_window; int gw_type, gw_dirty; GRECT gw_place; } Gem_nhwindow[MAXWIN]; int Fcw, Fch; /*struct gemmapdata {*/ GRECT dirty_map_area={COLNO,ROWNO,0,0}; int map_cursx=0, map_cursy=0, curs_col=WHITE; int draw_cursor=TRUE, map_cell_width=16; SCROLL scroll_map; char **map_glyphs=NULL; /*};*/ /*struct gemstatusdata{*/ char **status_line; int Anz_status_lines, status_w, StFch, StFcw; /*};*/ /*struct gemmessagedata{*/ int mar_message_pause=TRUE; int mar_esc_pressed=FALSE; int messages_pro_zug=0; char **message_line; int *message_age; int msg_pos=0, msg_max=0, msg_anz=0, msg_width=0; /*};*/ /*struct geminvdata {*/ SCROLL scroll_menu; Gem_menu_item *invent_list; int Anz_inv_lines=0, Inv_breite=16; int Inv_how; /*};*/ /*struct gemtextdata{*/ char **text_lines; int Anz_text_lines=0, text_width; /*};*/ static OBJECT *zz_oblist[NHICON+1]; MITEM scroll_keys[]={ /* menu, key, state, mode, msg */ {FAIL,key(CTRLLEFT,0),K_CTRL,PAGE_LEFT,FAIL}, {FAIL,key(CTRLRIGHT,0),K_CTRL,PAGE_RIGHT,FAIL}, {FAIL,key(SCANUP,0),K_SHIFT,PAGE_UP,FAIL}, {FAIL,key(SCANDOWN,0),K_SHIFT,PAGE_DOWN,FAIL}, {FAIL,key(SCANLEFT,0),0,LINE_LEFT,FAIL}, {FAIL,key(SCANRIGHT,0),0,LINE_RIGHT,FAIL}, {FAIL,key(SCANUP,0),0,LINE_UP,FAIL}, {FAIL,key(SCANDOWN,0),0,LINE_DOWN,FAIL}, {FAIL,key(SCANLEFT,0),K_SHIFT,LINE_START,FAIL}, {FAIL,key(SCANRIGHT,0),K_SHIFT,LINE_END,FAIL}, {FAIL,key(SCANUP,0),K_CTRL,WIN_START,FAIL}, {FAIL,key(SCANDOWN,0),K_CTRL,WIN_END,FAIL}, {FAIL,key(SCANHOME,0),K_SHIFT,WIN_END,FAIL}, {FAIL,key(SCANHOME,0),0,WIN_START,FAIL} }; #define SCROLL_KEYS 14 static DIAINFO *Inv_dialog; #define null_free(ptr) free(ptr), (ptr)=NULL #define test_free(ptr) if(ptr) null_free(ptr) static char *Menu_title=NULL; void mar_display_nhwindow(winid); void mar_check_hilight_status(void){} /* to be filled :-) */ static char *mar_copy_of(const char *); extern void panic(const char *, ...); void *m_alloc(size_t amt){ void *ptr; ptr=malloc(amt); if (!ptr) panic("Memory allocation failure; cannot get %lu bytes", amt); return(ptr); } void mar_clear_messagewin(void){ int i, *ptr=message_age; if(WIN_MESSAGE==WIN_ERR) return; for(i=msg_anz;--i>=0;ptr++){ if(*ptr) Gem_nhwindow[WIN_MESSAGE].gw_dirty=TRUE; *ptr=FALSE; } mar_message_pause=FALSE; mar_display_nhwindow(WIN_MESSAGE); } void move_win(WIN *z_win){ GRECT frame=desk; v_set_mode(MD_XOR); v_set_line(BLACK,1,1,0,0); frame.g_w<<=1, frame.g_h<<=1; if(graf_rt_dragbox(FALSE,&z_win->curr,&frame,&z_win->curr.g_x,&z_win->curr.g_y,NULL)) window_size(z_win,&z_win->curr); else window_top(z_win); } void message_handler(int x, int y){ switch(objc_find(zz_oblist[MSGWIN],ROOT,MAX_DEPTH,x,y)){ case UPMSG: if(msg_pos>2){ msg_pos--; Gem_nhwindow[WIN_MESSAGE].gw_dirty=TRUE; mar_display_nhwindow(WIN_MESSAGE); } Event_Timer(50,0,TRUE); break; case DNMSG: if(msg_posob_x=p_w->work.g_x+p_w->work.g_w/2-p_obj->ob_width/2; p_obj->ob_y=p_w->work.g_y+p_w->work.g_h/2-p_obj->ob_height/2; return(DIA_LASTPOS); } return(DIA_CENTERED); } /****************************** set_no_glyph *************************************/ void mar_set_no_glyph(ng) int ng; { no_glyph=ng; } /****************************** userdef_draw *************************************/ void my_color_area(GRECT *area, int col){ int pxy[4]; v_set_fill(col,1,IP_SOLID,0); rc_grect_to_array(area,pxy); v_bar(x_handle,pxy); } void my_clear_area(GRECT *area){ my_color_area(area, WHITE); } int mar_set_tile_mode(int); static void win_draw_map(int first, WIN *win, GRECT *area){ int pla[8], w=area->g_w-1, h=area->g_h-1; int i, x, y, mode, mch; GRECT back=*area; first=first; v_set_mode(MD_REPLACE); mode=S_ONLY; if(!mar_set_tile_mode(FAIL)){ v_set_text(ibm_font_id,ibm_font,WHITE,0,0,NULL); v_set_mode(MD_TRANS); mode=S_OR_D; mch=Fch-1; x=win->work.g_x-scroll_map.px_hpos; y=win->work.g_y-scroll_map.px_vpos; pla[2]=pla[0]=area->g_x-x; pla[3]=pla[1]=0; pla[2]+=w; pla[3]+=mch; /* MAR -- was 16 */ pla[6]=pla[4]=area->g_x; /* x_wert to */ pla[7]=pla[5]=y; /* y_wert to */ pla[6]+=w; pla[7]+=mch; /* MAR -- was 16 */ Vsync(); back.g_h=Fch; /* MAR -- was 16 */ for(i=0;ig_x-win->work.g_x; pla[3]=pla[1]=scroll_map.px_vpos+area->g_y-win->work.g_y; pla[2]+=w; pla[3]+=h; pla[6]=pla[4]=area->g_x; /* x_wert to */ pla[7]=pla[5]=area->g_y; /* y_wert to */ pla[6]+=w; pla[7]+=h; vro_cpyfm(x_handle, mode, pla, &Map_bild, screen); } if(draw_cursor){ v_set_line(curs_col,1,1,0,0); pla[0]=pla[2]=win->work.g_x+scroll_map.px_hline*(map_cursx-scroll_map.hpos); pla[1]=pla[3]=win->work.g_y+scroll_map.px_vline*(map_cursy-scroll_map.vpos); pla[2]+=map_cell_width-1; pla[3]+=mch; v_rect(pla[0],pla[1],pla[2],pla[3]); } } static int draw_titel(PARMBLK *pb){ static int pla[8]; GRECT work=*(GRECT *) &pb->pb_x; if(rc_intersect((GRECT *)&pb->pb_xc,&work)){ pla[0]=pla[1]=0; pla[2]=pb->pb_w-1; pla[3]=pb->pb_h-1; pla[6]=pla[4]=pb->pb_x; /* x_wert to */ pla[7]=pla[5]=pb->pb_y; /* y_wert to */ pla[6]+=pb->pb_w-1; pla[7]+=pb->pb_h-1; vro_cpyfm(x_handle, S_ONLY, pla, &Titel_bild, screen); } return(0); } static int draw_lines(PARMBLK *pb){ GRECT area=*(GRECT *) &pb->pb_x; if(rc_intersect((GRECT *)&pb->pb_xc,&area)){ char **ptr; int x=pb->pb_x,y=pb->pb_y,start_line=(area.g_y-y), chardim[4]; v_set_mode(MD_REPLACE); /* void v_set_text(int font,int height,int color,int effect,int rotate,int out[4]) */ v_set_text(ibm_font_id,ibm_font,BLACK,0,0,chardim); Fch= chardim[3] ? chardim[3] : 1; start_line /= Fch; y+=start_line*Fch; x-=scroll_menu.px_hpos; ptr=&text_lines[start_line+=scroll_menu.vpos]; start_line = min((area.g_y-y+area.g_h+Fch-1)/Fch,Anz_text_lines-start_line); area.g_h=Fch; Vsync(); for(;--start_line>=0;y+=Fch){ area.g_y=y; my_clear_area(&area); if(**ptr-1){ v_set_text(FAIL,0,BLUE,0x01,0,NULL); v_gtext(x_handle,x,y,(*ptr++)+1); v_set_text(FAIL,0,BLACK,0x00,0,NULL); }else v_gtext(x_handle,x,y,(*ptr++)+1); } } return(0); } static int draw_msgline(PARMBLK *pb){ GRECT area=*(GRECT *) &pb->pb_x; if(rc_intersect((GRECT *)&pb->pb_xc,&area)){ int x=pb->pb_x, y=pb->pb_y+2*Fch, foo, i; char **ptr=&message_line[msg_pos]; x=(x+7) & ~7; /* Byte alignment speeds output up */ v_set_mode(MD_REPLACE); /* void v_set_text(int font,int height,int color,int effect,int rotate,int out[4]) */ v_set_text(ibm_font_id,ibm_font,FAIL, FAIL,0,NULL); vst_alignment(x_handle,0,5,&foo,&foo); foo=min(msg_pos,3); /* area.g_h=Fch;*/ Vsync(); for(i=0;ipb_x; if(rc_intersect((GRECT *)&pb->pb_xc,&area)){ char **ptr=status_line; int x=pb->pb_x, y=pb->pb_y, chardim[4], h; /* void v_set_text(int font,int height,int color,int effect,int rotate,int out[4]) */ v_set_mode(MD_REPLACE); if(max_w/Fcw>=COLNO-1) v_set_text(ibm_font_id,ibm_font,BLACK,0,0,chardim); else v_set_text(small_font_id,small_font,BLACK,0,0,chardim); h=chardim[3] ? chardim[3] : 1; x+=2*chardim[2]; Vsync(); my_clear_area(&area); v_gtext(x_handle,x,y, *(ptr++)); v_gtext(x_handle,x,y+h,*ptr); } return(0); } static int draw_inventory(PARMBLK *pb){ GRECT area=*(GRECT *) &pb->pb_x; if(rc_intersect((GRECT *)&pb->pb_xc,&area)){ int gl, i, x=pb->pb_x, y=pb->pb_y,start_line=area.g_y-y; Gem_menu_item *it; v_set_mode(MD_REPLACE); v_set_text(ibm_font_id,ibm_font,BLACK,0,0,NULL); start_line /= Fch; y+=start_line*Fch; x-=scroll_menu.px_hpos; start_line+=scroll_menu.vpos; for(it=invent_list,i=start_line; --i>=0 && it; it=it->Gmi_next); i = min((area.g_y-y+area.g_h+Fch-1)/Fch,Anz_inv_lines-start_line); Vsync(); area.g_h=Fch; for(;(--i>=0) && it;it=it->Gmi_next,y+=Fch){ if(it->Gmi_attr) v_set_text(FAIL,FALSE,BLUE,1,FAIL,NULL); /* Bold */ else v_set_text(FAIL,FALSE,BLACK,0,FAIL,NULL); area.g_y=y; my_clear_area(&area); if((gl=it->Gmi_glyph) != no_glyph){ int pla[8], h=min(Fch,16)-1; pla[0]=pla[2]=(gl%20)*16; /* x_wert from */ pla[1]=pla[3]=(gl/20)*16; /* y_wert from */ pla[4]=pla[6]=x; /* x_wert to */ pla[5]=pla[7]=y; /* y_wert to */ pla[2]+=15; pla[3]+=h; pla[6]+=15; pla[7]+=h; vro_cpyfm(x_handle,S_ONLY,pla,&Tile_bilder,screen); } if(it->Gmi_identifier) it->Gmi_str[2]=it->Gmi_selected ? (it->Gmi_count == -1L ? '+' : '#') : '-'; v_gtext(x_handle,x+16,y,it->Gmi_str); } } return(0); } static int draw_prompt(PARMBLK *pb){ GRECT area=*(GRECT *) &pb->pb_x; if(rc_intersect((GRECT *)&pb->pb_xc,&area)){ char **ptr=(char **)pb->pb_parm; int x=pb->pb_x, y=pb->pb_y, chardim[4], h; /* void v_set_text(int font,int height,int color,int effect,int rotate,int out[4]) */ v_set_mode(MD_TRANS); v_set_text(ibm_font_id,ibm_font,WHITE,0,0,NULL); Vsync(); if(planes<4){ int pxy[4]; v_set_fill(BLACK,2,4,0); rc_grect_to_array(&area,pxy); v_bar(x_handle,pxy); }else my_color_area(&area,LWHITE); v_gtext(x_handle,x,y,*(ptr++)); if(*ptr) v_gtext(x_handle,x,y+Fch,*ptr); } return(0); } static USERBLK ub_lines={draw_lines, 0L}, ub_msg={draw_msgline, 0L}, ub_inventory={draw_inventory, 0L}, ub_titel={draw_titel, 0L}, ub_status={draw_status, 0L}, ub_prompt={draw_prompt, 0L}; /**************************** rsc_funktionen *****************************/ void my_close_dialog(DIAINFO *dialog,boolean shrink_box){ close_dialog(dialog,shrink_box); Event_Timer(0,0,TRUE); } void mar_get_rsc_tree(obj_number, z_ob_obj) int obj_number; OBJECT **z_ob_obj; { rsrc_gaddr( R_TREE, obj_number, z_ob_obj ); fix_objects(*z_ob_obj,SCALING,0,0); } void mar_clear_map(void); void img_error(errnumber) int errnumber; { char buf[BUFSZ]; switch(errnumber){ case ERR_HEADER : sprintf(buf,"%s","[1][ Image Header | corrupt. ][ Oops ]"); break; case ERR_ALLOC : sprintf(buf,"%s","[1][ Not enough | memory for | an image. ][ Oops ]"); break; case ERR_FILE : sprintf(buf,"%s","[1][ The Image-file | is not available ][ Oops ]"); break; case ERR_DEPACK : sprintf(buf,"%s","[1][ The Image-file | is corrupt ][ Oops ]"); break; case ERR_COLOR : sprintf(buf,"%s","[1][ Number of colors | not supported ][ Oops ]"); break; default: sprintf(buf,"[1][ img_error | strange error | number: %i ][ Hmm ]",errnumber); break; } form_alert(1,buf); } void mar_change_button_char(OBJECT *z_ob, int nr, char ch){ *ob_get_text(z_ob,nr,0)=ch; ob_set_hotkey(z_ob,nr,ch); } void mar_set_dir_keys() { static int mi_numpad=FAIL; char mcmd[]="bjnh.lyku", npcmd[]="123456789", *p_cmd; if(mi_numpad!=mar_iflags_numpad()){ OBJECT *z_ob=zz_oblist[DIRECTION]; int i; mi_numpad=mar_iflags_numpad(); ob_set_hotkey(z_ob,DIRDOWN,'>'); ob_set_hotkey(z_ob,DIRUP,'<'); p_cmd= mi_numpad ? npcmd : mcmd; for(i=0;i<9;i++) mar_change_button_char(z_ob,DIR1+2*i,p_cmd[i]); } } int mar_gem_init() { int i, bild_fehler=FALSE, chardim[4]; static MITEM wish_workaround= {FAIL,key(0,'J'),K_CTRL,W_CYCLE,FAIL}; OBJECT *z_ob; if((i=open_rsc("gem_rsc.rsc",NULL,md,md,md,0,0,0))<=0){ graf_mouse(M_OFF,NULL); if(i<0) form_alert(1,"[3][| Fatal Error | File: GEM_RSC.RSC | not found. ][ grumble ]"); else form_alert(1,"[3][| Fatal Error | GEM initialisation | failed. ][ a pity ]"); return(0); } if(planes<1 || planes>8){ form_alert(1,"[3][ Color-depth | not supported, | try 2-256 colors. ][ Ok ]"); return(0); } MouseBee(); for(i=0;i=COLNO-1){ status_w=msg_width; StFch=Fch; StFcw=Fcw; }else{ v_set_text(small_font_id,small_font,BLACK,0,0,chardim); StFch=chardim[3] ? chardim[3] : 1; StFcw=chardim[2] ? chardim[2] : 1; status_w=min(max_w/StFcw-3,100); } if(planes>0 && planes<9) normal_palette=(short *)m_alloc(3*colors*sizeof(short)); get_colors(x_handle,normal_palette, colors); if(planes<4){ bild_fehler=depack_img("NH2.IMG",&tile_image); }else{ bild_fehler=depack_img("NH16.IMG",&tile_image); if(!bild_fehler) img_set_colors(x_handle, tile_image.palette, tile_image.planes); } if(bild_fehler ){ z_ob=zz_oblist[ABOUT]; ob_undraw_dialog(z_ob,0,0,0,0); ob_hide(z_ob,OKABOUT,FALSE); img_error(bild_fehler); return(0); } mfdb(&Tile_bilder, (int *)tile_image.addr, tile_image.img_w, tile_image.img_h, 1, tile_image.planes); transform_img(&Tile_bilder); mfdb(&Map_bild,NULL,COLNO*16, ROWNO*16, 0, planes); Map_bild.fd_addr=(int *)m_alloc(mfdb_size(&Map_bild)); mfdb(&Pet_Mark,pet_mark_data,8, 7, 1, 1); vr_trnfm(x_handle,&Pet_Mark,&Pet_Mark); mfdb(&Black_bild,NULL,8, 16, 1, 1); Black_bild.fd_addr=(int *)m_alloc(mfdb_size(&Black_bild)); memset(Black_bild.fd_addr,255,mfdb_size(&Black_bild)); vr_trnfm(x_handle,&Black_bild,&Black_bild); for(i=0;i=0;) if(Gem_nhwindow[i].gw_type) mar_destroy_nhwindow(i); if(normal_palette){ img_set_colors(x_handle,normal_palette,planes); null_free(normal_palette); } test_free(tile_image.palette); test_free(tile_image.addr); test_free(titel_image.palette); test_free(titel_image.addr); } /************************* mar_curs *******************************/ void mar_curs(x,y) int x, y; { Min(&dirty_map_area.g_x,x); Min(&dirty_map_area.g_y,y); Max(&dirty_map_area.g_w,x); Max(&dirty_map_area.g_h,y); Min(&dirty_map_area.g_x,map_cursx); Min(&dirty_map_area.g_y,map_cursy); Max(&dirty_map_area.g_w,map_cursx); Max(&dirty_map_area.g_h,map_cursy); map_cursx=x; map_cursy=y; if(WIN_MAP!=WIN_ERR) Gem_nhwindow[WIN_MAP].gw_dirty=TRUE; } void mar_map_curs_weiter(void) { mar_curs(map_cursx+1,map_cursy); } /************************* about *******************************/ void mar_about() { xdialog(zz_oblist[ABOUT], md, NULL, NULL, DIA_CENTERED, FALSE, DIALOG_MODE); Event_Timer(0,0,TRUE); } /************************* ask_name *******************************/ char * mar_ask_name() { OBJECT *z_ob=zz_oblist[NAMEGET]; int bild_fehler; char who_are_you[] = "Who are you? "; bild_fehler=depack_img(planes<4 ? "TITLE2.IMG" : "TITLE.IMG", &titel_image); if(bild_fehler ){ /* MAR -- this isn't lethal */ ob_set_text(z_ob,NETHACKPICTURE,"missing title.img."); }else{ mfdb(&Titel_bild, (int *)titel_image.addr, titel_image.img_w, titel_image.img_h, 1, titel_image.planes); transform_img(&Titel_bild); z_ob[NETHACKPICTURE].ob_type=G_USERDEF; z_ob[NETHACKPICTURE].ob_spec.userblk=&ub_titel; } ob_clear_edit(z_ob); xdialog(z_ob,who_are_you, NULL, NULL, DIA_CENTERED, FALSE, DIALOG_MODE); Event_Timer(0,0,TRUE); test_free(titel_image.palette); test_free(titel_image.addr); test_free(Titel_bild.fd_addr); return(ob_get_text(z_ob,PLNAME,0)); } /************************* more *******************************/ void send_key(int key) { int buf[8]; buf[3]=0; /* No Shift/Ctrl/Alt */ buf[4]=key; AvSendMsg(ap_id,AV_SENDKEY,buf); } void send_return() { send_key(key(SCANRET,0)); } int K_Init(xev,availiable) XEVENT *xev; int availiable; { xev=xev; return(MU_KEYBD&availiable); } int KM_Init(xev,availiable) XEVENT *xev; int availiable; { xev=xev; return((MU_KEYBD|MU_MESAG)&availiable); } int M_Init(xev,availiable) XEVENT *xev; int availiable; { xev=xev; return(MU_MESAG&availiable); } #define More_Init K_Init int More_Handler(xev) XEVENT *xev; { int ev=xev->ev_mwich; if(ev&MU_KEYBD){ char ch=(char)(xev->ev_mkreturn&0x00FF); DIAINFO *dinf; WIN *w; switch(ch){ case '\033': /* no more more more */ case ' ': if((w=get_top_window()) && (dinf=(DIAINFO *)w->dialog) && dinf->di_tree==zz_oblist[PAGER]){ if(ch=='\033') mar_esc_pressed=TRUE; send_return(); break; } /* Fall thru */ default: ev &= ~MU_KEYBD; /* unknown key */ break; } } return(ev); } void mar_more() { if(!mar_esc_pressed){ OBJECT *z_ob=zz_oblist[PAGER]; WIN *p_w; Event_Handler(More_Init,More_Handler); dial_colors(7,RED,BLACK,RED,RED,BLACK,BLACK,BLACK,BLACK,WHITE,WHITE,WHITE,WHITE,TRUE,TRUE); if(WIN_MESSAGE!=WIN_ERR && (p_w=Gem_nhwindow[WIN_MESSAGE].gw_window)){ z_ob->ob_x=p_w->work.g_x; z_ob->ob_y=p_w->curr.g_y+p_w->curr.g_h+Fch; } xdialog(z_ob,NULL, NULL, NULL, DIA_LASTPOS, FALSE, DIALOG_MODE); Event_Timer(0,0,TRUE); Event_Handler(NULL,NULL); if(planes<4) dial_colors(4,BLACK,WHITE,RED,RED,WHITE,BLACK,BLACK,BLACK,FAIL,FAIL,FAIL,FAIL,TRUE,TRUE); else dial_colors(7,LWHITE,BLACK,RED,RED,BLACK,BLACK,BLACK,BLACK,WHITE,WHITE,WHITE,WHITE,TRUE,TRUE); } } /************************* Gem_start_menu *******************************/ void Gem_start_menu(win) winid win; { win=win; if(invent_list){ Gem_menu_item *curr, *next; for(curr=invent_list;curr;curr=next){ next=curr->Gmi_next; free(curr->Gmi_str); free(curr); } } invent_list=NULL; Anz_inv_lines=0; Inv_breite=16; } /************************* mar_add_menu *******************************/ void mar_add_menu(win, item) winid win; Gem_menu_item *item; { win=win; item->Gmi_next = invent_list; invent_list = item; Anz_inv_lines++; } void mar_reverse_menu() { Gem_menu_item *next, *head = 0, *curr=invent_list; while (curr) { next = curr->Gmi_next; curr->Gmi_next = head; head = curr; curr = next; } invent_list=head; } void mar_set_accelerators() { char ch='a'; Gem_menu_item *curr; for(curr=invent_list;curr;curr=curr->Gmi_next){ Max(&Inv_breite,Fcw*(strlen(curr->Gmi_str)+1)+16); if(ch && curr->Gmi_accelerator==0 && curr->Gmi_identifier){ curr->Gmi_accelerator=ch; curr->Gmi_str[0]=ch; if(ch=='z') ch='A'; else if(ch=='Z') ch=0; else ch++; } } } Gem_menu_item * mar_hol_inv() { return(invent_list); } /************************* mar_putstr_text *********************/ void mar_raw_print(const char *); void mar_putstr_text(winid window, int attr, const char *str) { static int zeilen_frei=0; int breite; char *ptr; window=window; if(!text_lines){ text_lines=(char **)m_alloc(12*sizeof(char *)); zeilen_frei=12; } if(!zeilen_frei){ text_lines=(char **)realloc(text_lines,(Anz_text_lines+12)*sizeof(char *)); zeilen_frei=12; } if(!text_lines){ mar_raw_print("No room for Text"); } if(str) breite=strlen(str); Min(&breite,80); ptr=text_lines[Anz_text_lines]=(char *)m_alloc(breite*sizeof(char)+2); *ptr=(char)(attr+1); /* avoid 0 */ strncpy(ptr+1,str,breite); ptr[breite+1]=0; Anz_text_lines++; zeilen_frei--; } int mar_set_inv_win(Anzahl, Breite) int Anzahl, Breite; { OBJECT *z_ob=zz_oblist[LINES]; int retval=WIN_DIAL|MODAL|NO_ICONIFY; scroll_menu.vpage= (desk.g_h-3*Fch)/Fch; if(Anzahl>scroll_menu.vpage){ retval |= WD_VSLIDER; if(Breite>max_w-3*Fcw){ retval|=WD_HSLIDER; scroll_menu.hpage=(max_w-3*Fcw)/Fcw; scroll_menu.hpos=0; scroll_menu.hsize=Breite/Fcw; scroll_menu.vpage=(desk.g_h-4*Fch-1)/Fch; } Anzahl=scroll_menu.vpage; }else{ if(Breite>max_w-Fcw){ retval|=WD_HSLIDER; scroll_menu.hpage=(max_w-Fcw)/Fcw; scroll_menu.hpos=0; scroll_menu.hsize=Breite/Fcw; scroll_menu.vpage= (desk.g_h-4*Fch-1)/Fch; if(Anzahl>scroll_menu.vpage){ retval |= WD_VSLIDER; Anzahl=scroll_menu.vpage; } } scroll_menu.vpage=Anzahl; } if((scroll_menu.hmax=scroll_menu.hsize-scroll_menu.hpage)<0) scroll_menu.hmax=0; if((scroll_menu.vmax=scroll_menu.vsize-scroll_menu.vpage)<0) scroll_menu.vmax=0; /* left/right/up 2 pixel border down 2Fch toolbar */ z_ob[ROOT].ob_width=z_ob[LINESLIST].ob_width=Breite; z_ob[ROOT].ob_height= z_ob[QLINE].ob_y= z_ob[LINESLIST].ob_height=Fch*Anzahl; z_ob[QLINE].ob_y+=Fch/2; z_ob[ROOT].ob_width+=4; z_ob[ROOT].ob_height+=2*Fch+2; return(retval); } /************************* mar_status_dirty *******************************/ void mar_status_dirty() { int ccol; if(WIN_STATUS != WIN_ERR) Gem_nhwindow[WIN_STATUS].gw_dirty=TRUE; ccol=mar_hp_query(); if(ccol<2) curs_col=WHITE; /* 50-100% : 0 */ else if(ccol<3) curs_col=YELLOW; /* 33-50% : 6 */ else if(ccol<5) curs_col=LYELLOW; /* 20-33% : 14*/ else if(ccol<10) curs_col=RED; /* 10-20% : 2 */ else curs_col=MAGENTA; /* <10% : 7*/ } /************************* mar_add_message *******************************/ void mar_add_message(str) const char *str; { int i, mesg_hist=mar_get_msg_history(); char *tmp, *rest, buf[TBUFSZ]; if(WIN_MESSAGE == WIN_ERR) return; if(!mar_message_pause){ mar_message_pause=TRUE; messages_pro_zug=0; msg_pos=msg_max; } if(msg_max>mesg_hist-2){ msg_max=mesg_hist-2; msg_pos--; if(msg_pos<0) msg_pos=0; tmp=message_line[0]; for(i=0;i=msg_width){ int pos=msg_width; tmp=toplines+msg_width; while(*tmp!=' ' && pos>=0){ tmp--; pos--; } if(pos<=0) pos=msg_width; /* Mar -- Oops, what a word :-) */ message_age[msg_max]=TRUE; strncpy(message_line[msg_max],toplines,pos); message_line[msg_max][pos]=0; rest=strcpy(buf,toplines+pos); }else{ message_age[msg_max]=TRUE; strcpy(message_line[msg_max],toplines); rest=0; } Gem_nhwindow[WIN_MESSAGE].gw_dirty=TRUE; if(messages_pro_zug>=mesg_hist){ /* MAR -- Greater then should never happen */ messages_pro_zug=mesg_hist; mar_display_nhwindow(WIN_MESSAGE); } if(rest) mar_add_message(rest); } /************************* mar_add_status_str *******************************/ void mar_add_status_str(str,line) const char *str; int line; { strncpy(status_line[line],str,status_w-1); status_line[line][status_w-1]='\0'; } /************************* mar_set_menu_title *******************************/ void mar_set_menu_title(str) const char *str; { test_free(Menu_title); /* just in case */ Menu_title=mar_copy_of(str ? str : nullstr); } /************************* mar_set_menu_type *******************************/ void mar_set_menu_type(how) int how; { Inv_how=how; } /************************* Inventory Utils *******************************/ void set_all_on_page(start, page) int start, page; { Gem_menu_item *curr; if(start<0 || page<0) return; for(curr=invent_list; start--&&curr; curr=curr->Gmi_next); for(; page--&&curr; curr=curr->Gmi_next) if (curr->Gmi_identifier && !curr->Gmi_selected) curr->Gmi_selected = TRUE; } void unset_all_on_page(start, page) int start, page; { Gem_menu_item *curr; if(start<0 || page<0) return; for(curr=invent_list; start--&&curr; curr=curr->Gmi_next); for(; page--&&curr; curr=curr->Gmi_next) if (curr->Gmi_identifier && curr->Gmi_selected) { curr->Gmi_selected = FALSE; curr->Gmi_count = -1L; } } void invert_all_on_page(start, page, acc) int start, page; char acc; { Gem_menu_item *curr; if(start<0 || page<0) return; for(curr=invent_list; start--&&curr; curr=curr->Gmi_next); for(; page--&&curr; curr=curr->Gmi_next) if (curr->Gmi_identifier && (acc == 0 || curr->Gmi_groupacc == acc)) { if (curr->Gmi_selected) { curr->Gmi_selected = FALSE; curr->Gmi_count = -1L; } else curr->Gmi_selected = TRUE; } } /************************* Inv_Handler and Inv_Init *******************************/ int scroll_top_dialog(char ch){ WIN *w; DIAINFO *dinf; if((w=get_top_window()) && (dinf=(DIAINFO *)w->dialog) && dinf->di_tree==zz_oblist[LINES]){ switch(ch){ case ' ': if(scroll_menu.vpos==scroll_menu.vmax){ send_return(); break; } /* Fall thru */ case MENU_NEXT_PAGE: scroll_window(w,PAGE_DOWN,NULL); break; case MENU_PREVIOUS_PAGE: scroll_window(w,PAGE_UP,NULL); break; case MENU_FIRST_PAGE: scroll_window(w,WIN_START,NULL); break; case MENU_LAST_PAGE: scroll_window(w,WIN_END,NULL); break; default: return(FALSE); } return(TRUE); } return(FALSE); } #define Text_Init K_Init int Text_Handler(xev) XEVENT *xev; { int ev=xev->ev_mwich; if(ev&MU_KEYBD){ char ch=(char)(xev->ev_mkreturn&0x00FF); if(!scroll_top_dialog(ch)) switch(ch){ case '\033': send_return(); /* just closes the textwin */ break; default: ev &= ~MU_KEYBD; /* unknown key */ break; } } return(ev); } #define Inv_Init KM_Init int Inv_Handler(xev) XEVENT *xev; { int ev=xev->ev_mwich; Gem_menu_item *it; GRECT area; static long count=0; OBJECT *z_ob=zz_oblist[LINES]; ob_pos(z_ob,LINESLIST,&area); if(ev&MU_MESAG){ int *buf=xev->ev_mmgpbuf, y_wo, i; if(*buf==OBJC_CHANGED && buf[3]==LINESLIST){ ob_undostate(z_ob,LINESLIST,SELECTED); mouse(NULL,&y_wo); y_wo=(y_wo-area.g_y)/Fch+scroll_menu.vpos; for(it=invent_list,i=0;iGmi_next,i++); if(it->Gmi_identifier){ it->Gmi_selected=!it->Gmi_selected; it->Gmi_count= count==0L ? -1L : count; count = 0L; if(Inv_how!=PICK_ANY) my_close_dialog(Inv_dialog,TRUE); else{ area.g_x+=16+2*Fcw; area.g_w=Fcw; area.g_h=Fch; area.g_y+=(y_wo-scroll_menu.vpos)*Fch; ob_draw_chg(Inv_dialog,LINESLIST,&area,FAIL); } /* how != PICK_ANY */ } /* identifier */ }else /* LINESLIST changed */ ev &= ~MU_MESAG; /* unknown message not used */ } /* MU_MESAG */ if(ev&MU_KEYBD){ char ch=(char)(xev->ev_mkreturn&0x00FF); if(!scroll_top_dialog(ch)){ switch(ch){ case '0': /* special 0 is also groupaccelerator for balls */ if(count<=0) goto find_acc; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if(Inv_how==PICK_NONE) goto find_acc; count = (count * 10L) + (long) (ch - '0'); break; case '\033': /* cancel - from counting or loop */ if(count>0L) count=0L; else{ unset_all_on_page(0, (int)scroll_menu.vsize); my_close_dialog(Inv_dialog,TRUE); return(ev); } break; case '\0': /* finished (commit) */ case '\n': case '\r': break; case MENU_SELECT_PAGE: if(Inv_how==PICK_NONE) goto find_acc; if (Inv_how == PICK_ANY) set_all_on_page((int)scroll_menu.vpos, scroll_menu.vpage); break; case MENU_SELECT_ALL: if(Inv_how==PICK_NONE) goto find_acc; if (Inv_how == PICK_ANY) set_all_on_page(0, (int)scroll_menu.vsize); break; case MENU_UNSELECT_PAGE: unset_all_on_page((int)scroll_menu.vpos, scroll_menu.vpage); break; case MENU_UNSELECT_ALL: unset_all_on_page(0, (int)scroll_menu.vsize); break; case MENU_INVERT_PAGE: if(Inv_how==PICK_NONE) goto find_acc; if (Inv_how == PICK_ANY) invert_all_on_page((int)scroll_menu.vpos, scroll_menu.vpage, 0); break; case MENU_INVERT_ALL: if(Inv_how==PICK_NONE) goto find_acc; if (Inv_how == PICK_ANY) invert_all_on_page(0, (int)scroll_menu.vsize, 0); break; case MENU_SEARCH: if(Inv_how!=PICK_NONE){ char buf[BUFSZ]; Gem_getlin("Search for:",buf); if(!*buf || buf[0]=='\033') break; for(it=invent_list;it;it=it->Gmi_next){ if(it->Gmi_identifier && strstr(it->Gmi_str,buf)){ it->Gmi_selected=TRUE; if(Inv_how!=PICK_ANY){ my_close_dialog(Inv_dialog,FALSE); break; } } } } break; default: find_acc: if(Inv_how==PICK_NONE) my_close_dialog(Inv_dialog,TRUE); for(it=invent_list;it;it=it->Gmi_next){ if(it->Gmi_identifier && (it->Gmi_accelerator==ch || it->Gmi_groupacc==ch)){ it->Gmi_selected=!it->Gmi_selected; it->Gmi_count= count==0L ? -1L : count; count = 0L; if(Inv_how!=PICK_ANY) my_close_dialog(Inv_dialog,TRUE); } } break; } /* end switch(ch) */ if(Inv_how==PICK_ANY){ area.g_x+=16+2*Fcw; area.g_w=Fcw; ob_draw_chg(Inv_dialog,LINESLIST,&area,FAIL); } } /* !scroll_Inv_dialog */ } /* MU_KEYBD */ if(Inv_how==PICK_ANY){ ob_set_text(Inv_dialog->di_tree,QLINE,strCancel); for(it=invent_list;it;it=it->Gmi_next) if(it->Gmi_identifier && it->Gmi_selected){ ob_set_text(Inv_dialog->di_tree,QLINE,strOk); break; } ob_draw_chg(Inv_dialog,QLINE,NULL,FAIL); } return(ev); } /************************* draw_window *******************************/ static void mar_draw_window( first, win, area) int first; WIN *win; GRECT *area; { OBJECT *obj=(OBJECT *)win->para; if(obj){ if(first){ obj->ob_x=win->work.g_x; obj->ob_y=win->work.g_y; } if(area==NULL) area=&(win->work); objc_draw(obj, ROOT, MAX_DEPTH, area->g_x, area->g_y, area->g_w, area->g_h); } } /************************* mar_display_nhwindow *******************************/ void mar_menu_set_slider(WIN *p_win){ if(p_win){ SCROLL *sc=p_win->scroll; if(!sc) return; if(p_win->gadgets&HSLIDE){ long hsize=1000l; if(sc->hsize>0 && sc->hpage>0){ hsize *= sc->hpage; hsize /= sc->hsize; } window_slider(p_win,HOR_SLIDER,0,(int)hsize); } if(p_win->gadgets&VSLIDE){ long vsize=1000l; if(sc->vsize>0 && sc->vpage>0){ vsize *= sc->vpage; vsize /= sc->vsize; } window_slider(p_win,VERT_SLIDER,0,(int)vsize); } } } void calc_std_winplace(int which, GRECT *place){ static int todo=TRUE; static GRECT me, ma, st; if(todo){ OBJECT *z_ob; int map_h_off, foo; /* First the messagewin */ z_ob=zz_oblist[MSGWIN]; z_ob[MSGLINES].ob_spec.userblk=&ub_msg; z_ob[MSGLINES].ob_width= z_ob[ROOT].ob_width= (msg_width+3)*Fcw; z_ob[MSGLINES].ob_width-=z_ob[UPMSG].ob_width; window_border(0,0,0,z_ob->ob_width,z_ob->ob_height, &me); /* Now the map */ wind_calc(WC_BORDER,MAP_GADGETS,0,0,16*COLNO,16*ROWNO,&foo,&foo,&foo,&map_h_off); map_h_off-=16*ROWNO; window_border(MAP_GADGETS,0,0,16*COLNO,16*ROWNO, &ma); ma.g_y=desk.g_y+me.g_h; /* Next the statuswin */ z_ob=zz_oblist[STATUSLINE]; z_ob[ROOT].ob_type=G_USERDEF; z_ob[ROOT].ob_spec.userblk=&ub_status; z_ob[ROOT].ob_width=(status_w+2)*StFcw; z_ob[ROOT].ob_height= z_ob[GRABSTATUS].ob_height=2*StFch; z_ob[GRABSTATUS].ob_width=2*StFcw-2; window_border(0,0,0,z_ob->ob_width,z_ob->ob_height,&st); /* And last but not least a final test */ ma.g_h=map_h_off+16*ROWNO; while(me.g_h+ma.g_h+st.g_h>=desk.g_h) ma.g_h-=16; st.g_y=desk.g_y+me.g_h+ma.g_h; todo=FALSE; } switch(which){ case NHW_MESSAGE: *place=me; break; case NHW_MAP: *place=ma; break; case NHW_STATUS: *place=st; break; default: break; } } void mar_display_nhwindow(wind) winid wind; { DIAINFO *dlg_info; OBJECT *z_ob; int d_exit=W_ABANDON, i, breite, mar_di_mode, tmp_magx=magx; GRECT g_mapmax, area; char *tmp_button; struct gw *p_Gw; if(wind == WIN_ERR) return; p_Gw=&Gem_nhwindow[wind]; switch(p_Gw->gw_type){ case NHW_TEXT: if(WIN_MESSAGE != WIN_ERR && Gem_nhwindow[WIN_MESSAGE].gw_window) mar_display_nhwindow(WIN_MESSAGE); z_ob=zz_oblist[LINES]; scroll_menu.vsize=Anz_text_lines; scroll_menu.vpos=0; z_ob[LINESLIST].ob_spec.userblk=&ub_lines; breite=16; for(i=0;idi_win; ptr_win->scroll=&scroll_menu; mar_menu_set_slider(ptr_win); WindowItems(ptr_win,SCROLL_KEYS,scroll_keys); if((d_exit=X_Form_Do(NULL))!=W_ABANDON){ my_close_dialog(dlg_info,FALSE); if(d_exit!=W_CLOSED) ob_undostate(z_ob,d_exit&NO_CLICK,SELECTED); } } Event_Handler(NULL,NULL); ob_set_text(z_ob,QLINE,tmp_button); break; case NHW_MENU: if(WIN_MESSAGE != WIN_ERR && Gem_nhwindow[WIN_MESSAGE].gw_window) mar_display_nhwindow(WIN_MESSAGE); z_ob=zz_oblist[LINES]; scroll_menu.vsize=Anz_inv_lines; scroll_menu.vpos=0; z_ob[LINESLIST].ob_spec.userblk=&ub_inventory; if((Menu_title)&&(wind!=WIN_INVEN)) /* because I sets no Menu_title */ Max(&Inv_breite,Fcw*strlen(Menu_title)+16); mar_di_mode=mar_set_inv_win(Anz_inv_lines, Inv_breite); tmp_button=ob_get_text(z_ob,QLINE,0); ob_set_text(z_ob,QLINE,Inv_how!=PICK_NONE ? strCancel : strOk ); ob_doflag(z_ob,LINESLIST,SELECTABLE); Event_Handler(Inv_Init, Inv_Handler); if((Inv_dialog=open_dialog(z_ob,(wind==WIN_INVEN) ? "Inventory" : (Menu_title ? Menu_title : "Staun"), NULL, NULL, mar_ob_mapcenter(z_ob), FALSE, mar_di_mode, FAIL, NULL, NULL))!=NULL){ WIN *ptr_win=Inv_dialog->di_win; ptr_win->scroll=&scroll_menu; mar_menu_set_slider(ptr_win); WindowItems(ptr_win,SCROLL_KEYS,scroll_keys); if((d_exit=X_Form_Do(NULL))!=W_ABANDON){ my_close_dialog(Inv_dialog,FALSE); if(d_exit!=W_CLOSED) ob_undostate(z_ob,d_exit&NO_CLICK,SELECTED); } } Event_Handler(NULL,NULL); ob_set_text(z_ob,QLINE,tmp_button); break; case NHW_MAP: if(p_Gw->gw_window==NULL){ calc_std_winplace(NHW_MAP,&p_Gw->gw_place); window_border(MAP_GADGETS,0,0,16*COLNO,16*ROWNO, &g_mapmax); p_Gw->gw_window=open_window(md, md, NULL, zz_oblist[NHICON], MAP_GADGETS, TRUE, 128, 128, &g_mapmax, &p_Gw->gw_place, &scroll_map, win_draw_map, NULL, XM_TOP|XM_BOTTOM|XM_SIZE); WindowItems(p_Gw->gw_window,SCROLL_KEYS-1,scroll_keys); /* ClrHome centers on u */ mar_clear_map(); } if(p_Gw->gw_dirty){ area.g_x=p_Gw->gw_window->work.g_x+scroll_map.px_hline*(dirty_map_area.g_x-scroll_map.hpos); area.g_y=p_Gw->gw_window->work.g_y+scroll_map.px_vline*(dirty_map_area.g_y-scroll_map.vpos); area.g_w=(dirty_map_area.g_w-dirty_map_area.g_x+1)*scroll_map.px_hline; area.g_h=(dirty_map_area.g_h-dirty_map_area.g_y+1)*scroll_map.px_vline; redraw_window(p_Gw->gw_window,&area); dirty_map_area.g_x=COLNO; dirty_map_area.g_y=ROWNO; dirty_map_area.g_w= dirty_map_area.g_h=0; } break; case NHW_MESSAGE: if(p_Gw->gw_window==NULL){ calc_std_winplace(NHW_MESSAGE,&p_Gw->gw_place); z_ob=zz_oblist[MSGWIN]; magx=0; /* MAR -- Fake E_GEM to remove Backdropper */ p_Gw->gw_window=open_window(NULL, NULL, NULL, NULL, 0, 0, 0, 0, NULL, &p_Gw->gw_place, NULL, mar_draw_window, z_ob, XM_TOP|XM_BOTTOM|XM_SIZE); magx=tmp_magx; window_size(p_Gw->gw_window,&p_Gw->gw_window->curr); } if(p_Gw->gw_dirty){ while(messages_pro_zug>3){ messages_pro_zug-=3; msg_pos+=3; redraw_window(p_Gw->gw_window,NULL); mar_more(); } msg_pos+=messages_pro_zug; messages_pro_zug=0; if(msg_pos>msg_max) msg_pos=msg_max; redraw_window(p_Gw->gw_window,NULL); mar_message_pause=FALSE; } break; case NHW_STATUS: if(p_Gw->gw_window==NULL){ z_ob=zz_oblist[STATUSLINE]; calc_std_winplace(NHW_STATUS,&p_Gw->gw_place); magx=0; /* MAR -- Fake E_GEM to remove Backdropper */ p_Gw->gw_window=open_window(NULL, NULL, NULL, NULL, 0, FALSE, 0, 0, NULL, &p_Gw->gw_place, NULL, mar_draw_window, z_ob, XM_TOP|XM_BOTTOM|XM_SIZE); magx=tmp_magx; /* Because 2*StFch is smaller then e_gem expects the minimum win_height */ p_Gw->gw_window->min_h=z_ob[ROOT].ob_height; window_size(p_Gw->gw_window,&p_Gw->gw_place); } /* Fall thru */ default: if(p_Gw->gw_dirty) redraw_window(p_Gw->gw_window,NULL); } p_Gw->gw_dirty=FALSE; } /************************* create_window *******************************/ int mar_hol_win_type(window) winid window; { return(Gem_nhwindow[window].gw_type); } winid mar_create_window(type) int type; { winid newid; static char name[]="Gem"; int i; struct gw *p_Gw=&Gem_nhwindow[0]; for(newid = 0; p_Gw->gw_type && newid < MAXWIN; newid++, p_Gw++); switch(type){ case NHW_MESSAGE: message_line=(char **)m_alloc(msg_anz*sizeof(char *)); message_age=(int *)m_alloc(msg_anz*sizeof(int)); for(i=0;igw_window=open_window("Sonst", name, NULL, NULL, NAME|MOVER|CLOSER, 0, 0, 0, NULL, &p_Gw->gw_place, NULL, NULL, NULL, XM_TOP|XM_BOTTOM|XM_SIZE); break; } p_Gw->gw_type=type; return(newid); } void mar_change_menu_2_text(win) winid win; { Gem_nhwindow[win].gw_type=NHW_TEXT; } /************************* mar_clear_map *******************************/ void mar_clear_map() { static int pla[8]={0,0,16*COLNO-1,16*ROWNO-1,0,0,16*COLNO-1,16*ROWNO-1}; int x,y; for(y=0;y= scroll_map.hpos + scroll_map.hpage - breite)){ scroll_map.hpos=map_cursx - 2*breite; adjust_needed=TRUE; } if ((map_cursy < scroll_map.vpos + hoehe) || (map_cursy >= scroll_map.vpos + scroll_map.vpage - hoehe)){ scroll_map.vpos=map_cursy - 2*hoehe; adjust_needed=TRUE; } if(adjust_needed) scroll_window(Gem_nhwindow[WIN_MAP].gw_window,WIN_SCROLL,NULL); } } void mar_update_value() { if(WIN_MESSAGE!=WIN_ERR){ mar_message_pause=FALSE; mar_esc_pressed=FALSE; mar_display_nhwindow(WIN_MESSAGE); } if(WIN_STATUS!=WIN_ERR){ mar_check_hilight_status(); mar_display_nhwindow(WIN_STATUS); } } int Main_Init(xev,availiable) XEVENT *xev; int availiable; { xev->ev_mb1mask= xev->ev_mb1state=1; xev->ev_mb1clicks= xev->ev_mb2clicks= xev->ev_mb2mask= xev->ev_mb2state=2; return((MU_KEYBD|MU_BUTTON1|MU_BUTTON2|MU_MESAG)&availiable); } /* * return a key, or 0, in which case a mouse button was pressed * mouse events should be returned as character postitions in the map window. */ /*ARGSUSED*/ int mar_nh_poskey(x, y, mod) int *x, *y, *mod; { static XEVENT xev; int retval, ev; xev.ev_mflags=Main_Init(&xev,0xFFFF); ev=Event_Multi(&xev); retval=FAIL; if(ev&MU_KEYBD){ char ch = xev.ev_mkreturn&0x00FF; char scan = (xev.ev_mkreturn & 0xff00) >> 8; int shift = xev.ev_mmokstate; const struct pad *kpad; /* Translate keypad keys */ if (iskeypad(scan)) { kpad = mar_iflags_numpad()==1 ? numpad : keypad; if (shift & K_SHIFT) ch = kpad[scan - KEYPADLO].shift; else if (shift & K_CTRL) ch = kpad[scan - KEYPADLO].cntrl; else ch = kpad[scan - KEYPADLO].normal; } if(scan==SCANHOME) mar_cliparound(); else if(scan == SCANF1) retval='h'; else if(scan == SCANF2){ mar_set_tile_mode(!mar_set_tile_mode(FAIL)); retval=C('l'); /* trigger full-redraw */ }else if(scan == SCANF3){ draw_cursor=!draw_cursor; mar_curs(map_cursx,map_cursy); mar_display_nhwindow(WIN_MAP); }else if(!ch && shift&K_CTRL && scan==-57){ /* MAR -- nothing ignore Ctrl-Alt-Clr/Home == MagiC's restore screen */ }else{ if(!ch) ch=(char)M(tolower(scan_2_ascii(xev.ev_mkreturn,shift))); if(((int)ch)==-128) ch='\033'; retval=ch; } } if(ev&MU_BUTTON1 || ev&MU_BUTTON2){ int ex=xev.ev_mmox, ey=xev.ev_mmoy; WIN *akt_win=window_find(ex,ey); if(WIN_MAP != WIN_ERR && akt_win==Gem_nhwindow[WIN_MAP].gw_window){ *x=max(min((ex-akt_win->work.g_x)/scroll_map.px_hline+scroll_map.hpos,COLNO),0)+1; *y=max(min((ey-akt_win->work.g_y)/scroll_map.px_vline+scroll_map.vpos,ROWNO),0); *mod=xev.ev_mmobutton; retval=0; }else if(WIN_STATUS != WIN_ERR && akt_win==Gem_nhwindow[WIN_STATUS].gw_window){ move_win(akt_win); }else if(WIN_MESSAGE != WIN_ERR && akt_win==Gem_nhwindow[WIN_MESSAGE].gw_window){ message_handler(ex,ey); } } if(ev&MU_MESAG){ int *buf=xev.ev_mmgpbuf; char *str; OBJECT *z_ob=zz_oblist[MENU]; switch(*buf) { case MN_SELECTED : menu_tnormal(z_ob,buf[3],TRUE); /* unselect menu header */ str=ob_get_text(z_ob,buf[4],0); str+=strlen(str)-2; switch(*str){ case ' ': /* just that command */ retval=str[1]; break; case '\005': /* Alt command */ case '\007': retval=M(str[1]); break; case '^': /* Ctrl command */ retval=C(str[1]); break; case 'f': /* Func Key */ switch(str[1]){ case '1': retval='h'; break; case '2': mar_set_tile_mode(!mar_set_tile_mode(FAIL)); retval=C('l'); /* trigger full-redraw */ break; case '3': draw_cursor=!draw_cursor; if(WIN_MAP != WIN_ERR && Gem_nhwindow[WIN_MAP].gw_window) redraw_window(Gem_nhwindow[WIN_MAP].gw_window,NULL); break; default: } break; default: mar_about(); break; } break; /* MN_SELECTED */ case WM_CLOSED: WindowHandler(W_ICONIFYALL,NULL,NULL); break; default: break; } } /* MU_MESAG */ if(retval==FAIL) retval=mar_nh_poskey(x,y,mod); return(retval); } int Gem_nh_poskey(x, y, mod) int *x, *y, *mod; { mar_update_value(); return(mar_nh_poskey(x, y, mod)); } void Gem_delay_output() { Event_Timer(50,0,FALSE); /* wait 50ms */ } int Gem_doprev_message() { if(msg_pos>2) msg_pos--; if(WIN_MESSAGE != WIN_ERR) Gem_nhwindow[WIN_MESSAGE].gw_dirty=TRUE; mar_display_nhwindow(WIN_MESSAGE); return(0); } /************************* print_glyph *******************************/ int mar_set_rogue(int); int mar_set_tile_mode(tiles) int tiles; { static int tile_mode=TRUE; static GRECT prev; WIN *z_w=Gem_nhwindow[WIN_MAP].gw_window; if(tiles<0) return(tile_mode); else{ GRECT tmp; if(tile_mode==tiles || (mar_set_rogue(FAIL) && tiles) || !z_w) return(FAIL); tile_mode=tiles; map_cell_width= tiles ? 16 : Fcw; scroll_map.px_hline=map_cell_width; scroll_map.px_vline=tiles ? 16 : Fch; window_border(MAP_GADGETS,0,0,map_cell_width*COLNO,16*ROWNO, &tmp); z_w->max.g_w=tmp.g_w; if(tiles) z_w->curr=prev; else prev=z_w->curr; window_reinit(z_w,md,md,NULL,FALSE,FALSE); } return(FAIL); } int mar_set_rogue(what) int what; { static int rogue=FALSE, prev_mode=TRUE; if(what<0) return(rogue); if(what!=rogue){ rogue=what; if(rogue){ prev_mode=mar_set_tile_mode(FAIL); mar_set_tile_mode(FALSE); }else mar_set_tile_mode(prev_mode); } return(FAIL); } void mar_add_pet_sign(window,x,y) winid window; int x, y; { if(window != WIN_ERR && window==WIN_MAP){ static int pla[8]={0,0,7,7,0,0,0,0}, colindex[2]={RED,WHITE}; pla[4]=pla[6]=scroll_map.px_hline*x; pla[5]=pla[7]=scroll_map.px_vline*y; pla[6]+=7; pla[7]+=6; vrt_cpyfm(x_handle,MD_TRANS,pla,&Pet_Mark,&Map_bild,colindex); } } void mar_print_glyph(window, x, y, gl) winid window; int x, y, gl; { static int pla[8]; if(window != WIN_ERR && window==WIN_MAP){ Min(&dirty_map_area.g_x,x); Min(&dirty_map_area.g_y,y); Max(&dirty_map_area.g_w,x); Max(&dirty_map_area.g_h,y); Gem_nhwindow[window].gw_dirty=TRUE; if(mar_set_tile_mode(FAIL)){ pla[2]=pla[0]=(gl%20)*16; pla[3]=pla[1]=(gl/20)*16; pla[2]+=15; pla[3]+=15; pla[6]=pla[4]=16*x; /* x_wert to */ pla[7]=pla[5]=16*y; /* y_wert to */ pla[6]+=15; pla[7]+=15; vro_cpyfm(x_handle, gl!=-1 ? S_ONLY : ALL_BLACK, pla, &Tile_bilder, &Map_bild); } } } void mar_print_char(window, x, y, ch, col) winid window; int x, y; char ch; int col; { if(window != WIN_ERR && window==WIN_MAP){ static int gem_color[16]={ 9, 2,11,10, 4, 7, 8, 15,0,14, 3, 6, 5, 13,15, 0}; int pla[8], colindex[2]; map_glyphs[y][x]=ch; pla[0]= pla[1]=0; pla[2]=Fcw-1; pla[3]=Fch-1; pla[6]=pla[4]=Fcw*x; pla[7]=pla[5]=Fch*y; pla[6]+=Fcw-1; pla[7]+=Fch-1; colindex[0]=gem_color[col]; colindex[1]=WHITE; vrt_cpyfm(x_handle,MD_REPLACE,pla,&Black_bild,&Map_bild,colindex); } } /************************* getlin *******************************/ void Gem_getlin(ques, input) const char *ques; char *input; { OBJECT *z_ob=zz_oblist[LINEGET]; int d_exit, length; char *pr[2], *tmp; if(WIN_MESSAGE != WIN_ERR && Gem_nhwindow[WIN_MESSAGE].gw_window) mar_display_nhwindow(WIN_MESSAGE); z_ob[LGPROMPT].ob_type=G_USERDEF; z_ob[LGPROMPT].ob_spec.userblk=&ub_prompt; z_ob[LGPROMPT].ob_height=2*Fch; length=z_ob[LGPROMPT].ob_width/Fcw; if(strlen(ques)>length){ tmp=ques+length; while(*tmp!=' ' && tmp>=ques){ tmp--; } if(tmp<=ques) tmp=ques+length; /* Mar -- Oops, what a word :-) */ pr[0]=ques; *tmp=0; pr[1]=++tmp; }else{ pr[0]=ques; pr[1]=NULL; } ub_prompt.ub_parm=(long)pr; ob_clear_edit(z_ob); d_exit=xdialog(z_ob, nullstr, NULL, NULL, mar_ob_mapcenter(z_ob), FALSE, DIALOG_MODE); Event_Timer(0,0,TRUE); if(d_exit==W_CLOSED || d_exit==W_ABANDON || (d_exit&NO_CLICK)==QLG){ *input='\033'; input[1]=0; }else strncpy(input,ob_get_text(z_ob,LGREPLY, 0),length); } /************************* ask_direction *******************************/ #define Dia_Init K_Init int Dia_Handler(xev) XEVENT *xev; { int ev=xev->ev_mwich; char ch=(char)(xev->ev_mkreturn&0x00FF); if(ev&MU_KEYBD){ WIN *w; DIAINFO *dinf; switch(ch){ case 's': send_key((int)(mar_iflags_numpad() ? '5' : '.')); break; case '.': send_key('5'); /* MAR -- '.' is a button if numpad isn't set */ break; case '\033': /*ESC*/ if((w=get_top_window()) && (dinf=(DIAINFO *)w->dialog) && dinf->di_tree==zz_oblist[DIRECTION]){ my_close_dialog(dinf,FALSE); break; } /* Fall thru */ default: ev &= ~MU_KEYBD; /* let the dialog handle it */ break; } } return(ev); } int mar_ask_direction() { int d_exit; OBJECT *z_ob=zz_oblist[DIRECTION]; Event_Handler(Dia_Init,Dia_Handler); mar_set_dir_keys(); d_exit=xdialog(z_ob, nullstr, NULL, NULL, mar_ob_mapcenter(z_ob), FALSE, DIALOG_MODE); Event_Timer(0,0,TRUE); Event_Handler(NULL,NULL); if(d_exit==W_CLOSED || d_exit==W_ABANDON) return('\033'); if((d_exit&NO_CLICK)==DIRDOWN) return('>'); if((d_exit&NO_CLICK)==DIRUP) return('<'); if((d_exit&NO_CLICK)==(DIR1+8)) /* 5 or . */ return('.'); return(*ob_get_text(z_ob,d_exit&NO_CLICK,0)); } /************************* yn_function *******************************/ #define any_init M_Init static int any_handler(xev) XEVENT *xev; { int ev=xev->ev_mwich; if(ev&MU_MESAG){ int *buf=xev->ev_mmgpbuf; if(*buf==OBJC_EDITED) my_close_dialog(*(DIAINFO **)&buf[4], FALSE); else ev &= ~MU_MESAG; } return(ev); } int send_yn_esc(char ch) { static char esc_char=0; if(ch<0){ if(esc_char){ send_key((int)esc_char); return(TRUE); } return(FALSE); }else esc_char=ch; return(TRUE); } #define single_init K_Init static int single_handler(xev) XEVENT *xev; { int ev=xev->ev_mwich; if(ev&MU_KEYBD){ char ch=(char)xev->ev_mkreturn&0x00FF; WIN *w; DIAINFO *dinf; switch(ch){ case ' ': send_return(); break; case '\033': if((w=get_top_window()) && (dinf=(DIAINFO *)w->dialog) && dinf->di_tree==zz_oblist[YNCHOICE]){ if(!send_yn_esc(FAIL)) my_close_dialog(dinf,FALSE); break; } /* Fall thru */ default: ev &= ~MU_MESAG; } } return(ev); } char Gem_yn_function(query,resp, def) const char *query,*resp; char def; { OBJECT *z_ob=zz_oblist[YNCHOICE]; int d_exit, i, len; long anzahl; char *tmp; const char *ptr; if(WIN_MESSAGE != WIN_ERR && Gem_nhwindow[WIN_MESSAGE].gw_window) mar_display_nhwindow(WIN_MESSAGE); /* if query for direction the special dialog */ if(strstr(query,"irect")) return(mar_ask_direction()); len=min(strlen(query),(max_w-8*Fcw)/Fcw); z_ob[ROOT].ob_width=(len+8)*Fcw; z_ob[YNPROMPT].ob_width=Fcw*len+8; tmp=ob_get_text(z_ob,YNPROMPT,0); ob_set_text(z_ob,YNPROMPT,mar_copy_of(query)); if(resp){ /* single inputs */ ob_hide(z_ob,SOMECHARS,FALSE); ob_hide(z_ob,ANYCHAR,TRUE); if(strchr(resp,'q')) send_yn_esc('q'); else if(strchr(resp,'n')) send_yn_esc('n'); else send_yn_esc(def); /* strictly def should be returned, but in trad. I it's 0 */ if(strchr(resp,'#')){ /* count possible */ ob_hide(z_ob,YNOK,FALSE); ob_hide(z_ob,COUNT,FALSE); }else{ /* no count */ ob_hide(z_ob,YNOK,TRUE); ob_hide(z_ob,COUNT,TRUE); } if((anzahl=(long)strchr(resp,'\033'))){ anzahl-=(long)resp; }else{ anzahl=strlen(resp); } for(i=0,ptr=resp;i<2*anzahl;i+=2,ptr++){ ob_hide(z_ob,YN1+i,FALSE); mar_change_button_char(z_ob,YN1+i,*ptr); ob_undoflag(z_ob,YN1+i,DEFAULT); if(*ptr==def) ob_doflag(z_ob,YN1+i,DEFAULT); } z_ob[SOMECHARS].ob_width=z_ob[YN1+i].ob_x+8; z_ob[SOMECHARS].ob_height=z_ob[YN1+i].ob_y+Fch+Fch/2; Max((int *)&z_ob[ROOT].ob_width,z_ob[SOMECHARS].ob_width+4*Fcw); z_ob[ROOT].ob_height=z_ob[SOMECHARS].ob_height+4*Fch; if(strchr(resp,'#')) z_ob[ROOT].ob_height=z_ob[YNOK].ob_y+2*Fch; for(i+=YN1;i<(YNN+1);i+=2){ ob_hide(z_ob,i,TRUE); } Event_Handler(single_init,single_handler); }else{ /* any input */ ob_hide(z_ob,SOMECHARS,TRUE); ob_hide(z_ob,ANYCHAR,FALSE); ob_hide(z_ob,YNOK,TRUE); ob_hide(z_ob,COUNT,TRUE); z_ob[ANYCHAR].ob_height=2*Fch; z_ob[CHOSENCH].ob_y= z_ob[CHOSENCH+1].ob_y=Fch/2; z_ob[ROOT].ob_width=max(z_ob[YNPROMPT].ob_width+z_ob[YNPROMPT].ob_x,z_ob[ANYCHAR].ob_width+z_ob[ANYCHAR].ob_x)+2*Fcw; z_ob[ROOT].ob_height=z_ob[ANYCHAR].ob_height+z_ob[ANYCHAR].ob_y+Fch/2; *ob_get_text(z_ob,CHOSENCH,0)='?'; Event_Handler(any_init,any_handler); } d_exit=xdialog(z_ob, nullstr, NULL, NULL, mar_ob_mapcenter(z_ob), FALSE, DIALOG_MODE); Event_Timer(0,0,TRUE); Event_Handler(NULL,NULL); /* display of count is missing (through the core too) */ free(ob_get_text(z_ob,YNPROMPT,0)); ob_set_text(z_ob,YNPROMPT,tmp); if(resp && (d_exit==W_CLOSED || d_exit==W_ABANDON)) return('\033'); if((d_exit&NO_CLICK)==YNOK){ yn_number=atol(ob_get_text(z_ob,COUNT,0)); return('#'); } if(!resp) return(*ob_get_text(z_ob,CHOSENCH,0)); return(*ob_get_text(z_ob,d_exit&NO_CLICK,0)); } /* * 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 * mar_copy_of(s) const char *s; { if (!s) s = nullstr; return strcpy((char *) m_alloc((unsigned) (strlen(s) + 1)), s); } const char *strRP="raw_print", *strRPB="raw_print_bold"; void mar_raw_print(str) const char *str; { xalert(1,FAIL,X_ICN_INFO,NULL,APPL_MODAL,BUTTONS_CENTERED,TRUE,strRP,str,NULL); } void mar_raw_print_bold(str) const char *str; { char buf[BUFSZ]; sprintf(buf,"!%s",str); xalert(1,FAIL,X_ICN_INFO,NULL,APPL_MODAL,BUTTONS_CENTERED,TRUE,strRPB,buf,NULL); } /*wingem1.c*/