1 /* SCCS Id: @(#)wingem1.c 3.4 1999/12/10 */
2 /* Copyright (c) Christian Bressler 1999 */
3 /* NetHack may be freely redistributed. See license for details. */
19 #define genericptr_t void *
20 typedef signed char schar;
24 #define NDECL(f) f(void)
25 #define FDECL(f,p) f p
31 #define BOOLEAN_P boolean
32 #define ALIGNTYP_P aligntyp
33 typedef signed char xchar;
45 static char nullstr[]="", md[]="NetHack 3.4.3", strCancel[]="Cancel", strOk[]="Ok", strText[]="Text";
47 extern winid WIN_MESSAGE, WIN_MAP, WIN_STATUS, WIN_INVEN;
54 #define MAP_GADGETS NAME|MOVER|CLOSER|FULLER|LFARROW|RTARROW|UPARROW|DNARROW|VSLIDE|HSLIDE|SIZER|SMALLER
55 #define DIALOG_MODE AUTO_DIAL|MODAL|NO_ICONIFY
58 * Keyboard translation tables.
60 #define C(c) (0x1f & (c))
61 #define M(c) (0x80 | (c))
66 #define PADKEYS (KEYPADHI - KEYPADLO + 1)
67 #define iskeypad(x) (KEYPADLO <= (x) && (x) <= KEYPADHI)
70 * Keypad keys are translated to the normal values below.
71 * When iflags.BIOS is active, shifted keypad keys are translated to the
74 static const struct pad {
75 char normal, shift, cntrl;
77 {C('['), 'Q', C('[')}, /* UNDO */
78 {'?', '/', '?'}, /* HELP */
79 {'(', 'a', '('}, /* ( */
80 {')', 'w', ')'}, /* ) */
81 {'/', '/', '/'}, /* / */
82 {C('p'), '$', C('p')}, /* * */
83 {'y', 'Y', C('y')}, /* 7 */
84 {'k', 'K', C('k')}, /* 8 */
85 {'u', 'U', C('u')}, /* 9 */
86 {'h', 'H', C('h')}, /* 4 */
88 {'l', 'L', C('l')}, /* 6 */
89 {'b', 'B', C('b')}, /* 1 */
90 {'j', 'J', C('j')}, /* 2 */
91 {'n', 'N', C('n')}, /* 3 */
92 {'i', 'I', C('i')}, /* Ins */
93 {'.', ':', ':'} /* Del */
94 }, numpad[PADKEYS] = {
95 {C('['), 'Q', C('[')} , /* UNDO */
96 {'?', '/', '?'}, /* HELP */
97 {'(', 'a', '('}, /* ( */
98 {')', 'w', ')'}, /* ) */
99 {'/', '/', '/'}, /* / */
100 {C('p'), '$', C('p')}, /* * */
101 {'7', M('7'), '7'}, /* 7 */
102 {'8', M('8'), '8'}, /* 8 */
103 {'9', M('9'), '9'}, /* 9 */
104 {'4', M('4'), '4'}, /* 4 */
105 {'.', '.', '.'}, /* 5 */
106 {'6', M('6'), '6'}, /* 6 */
107 {'1', M('1'), '1'}, /* 1 */
108 {'2', M('2'), '2'}, /* 2 */
109 {'3', M('3'), '3'}, /* 3 */
110 {'i', 'I', C('i')}, /* Ins */
111 {'.', ':', ':'} /* Del */
116 extern int yn_number; /* from decl.c */
117 extern char toplines[TBUFSZ]; /* from decl.c */
118 extern char mapped_menu_cmds[]; /* from options.c */
119 extern int mar_iflags_numpad(void); /* from wingem.c */
120 extern void Gem_raw_print(const char *); /* from wingem.c */
121 extern int mar_hp_query(void); /* from wingem.c */
122 extern int mar_get_msg_history(void); /* from wingem.c */
123 extern int mar_get_msg_visible(void); /* from wingem.c */
124 extern void mar_get_font(int,char **,int *);/* from wingem.c */
125 extern int vdi2dev4[]; /* from load_img.c */
127 void recalc_msg_win(GRECT*);
128 void recalc_status_win(GRECT*);
129 void calc_std_winplace(int, GRECT *);
130 int (*v_mtext)(int,int,int,char*);
131 static int no_glyph; /* the int indicating there is no glyph */
132 IMG_header tile_image, titel_image, rip_image;
133 MFDB Tile_bilder, Map_bild, Titel_bild, Rip_bild, Black_bild, Pet_Mark, FontCol_Bild;
134 static int Tile_width=16, Tile_heigth=16, Tiles_per_line=20;
136 /* pet_mark Design by Warwick Allison warwick@troll.no */
137 static int pet_mark_data[]={0x0000,0x3600,0x7F00,0x7F00,0x3E00,0x1C00,0x0800};
138 static short *normal_palette=NULL;
142 int gw_type, gw_dirty;
144 } Gem_nhwindow[MAXWIN];
153 /*struct gemmapdata {*/
154 GRECT dirty_map_area={COLNO-1,ROWNO,0,0};
155 int map_cursx=0, map_cursy=0, curs_col=WHITE;
156 int draw_cursor=TRUE, scroll_margin=-1;
159 char **map_glyphs=NULL;
163 /*struct gemstatusdata{*/
165 int Anz_status_lines, status_w, status_align=FALSE;
166 NHGEM_FONT status_font;
170 /*struct gemmessagedata{*/
171 int mar_message_pause=TRUE;
172 int mar_esc_pressed=FALSE;
173 int messages_pro_zug=0;
176 int msg_pos=0, msg_max=0, msg_anz=0, msg_width=0, msg_vis=3, msg_align=TRUE;
181 /*struct geminvdata {*/
183 Gem_menu_item *invent_list;
184 int Anz_inv_lines=0, Inv_breite=16;
185 NHGEM_FONT menu_font;
189 /*struct gemtextdata{*/
191 int Anz_text_lines=0, text_width;
192 NHGEM_FONT text_font;
194 extern char** rip_line;
197 static OBJECT *zz_oblist[NHICON+1];
199 MITEM scroll_keys[]={
200 /* menu, key, state, mode, msg */
201 {FAIL,key(CTRLLEFT,0),K_CTRL,PAGE_LEFT,FAIL},
202 {FAIL,key(CTRLRIGHT,0),K_CTRL,PAGE_RIGHT,FAIL},
203 {FAIL,key(SCANUP,0),K_SHIFT,PAGE_UP,FAIL},
204 {FAIL,key(SCANDOWN,0),K_SHIFT,PAGE_DOWN,FAIL},
205 {FAIL,key(SCANLEFT,0),0,LINE_LEFT,FAIL},
206 {FAIL,key(SCANRIGHT,0),0,LINE_RIGHT,FAIL},
207 {FAIL,key(SCANUP,0),0,LINE_UP,FAIL},
208 {FAIL,key(SCANDOWN,0),0,LINE_DOWN,FAIL},
209 {FAIL,key(SCANLEFT,0),K_SHIFT,LINE_START,FAIL},
210 {FAIL,key(SCANRIGHT,0),K_SHIFT,LINE_END,FAIL},
211 {FAIL,key(SCANUP,0),K_CTRL,WIN_START,FAIL},
212 {FAIL,key(SCANDOWN,0),K_CTRL,WIN_END,FAIL},
213 {FAIL,key(SCANHOME,0),K_SHIFT,WIN_END,FAIL},
214 {FAIL,key(SCANHOME,0),0,WIN_START,FAIL}
216 #define SCROLL_KEYS 14
218 static DIAINFO *Inv_dialog;
220 #define null_free(ptr) free(ptr), (ptr)=NULL
221 #define test_free(ptr) if(ptr) null_free(ptr)
223 static char *Menu_title=NULL;
225 void mar_display_nhwindow(winid);
226 void mar_check_hilight_status(void){} /* to be filled :-) */
227 static char *mar_copy_of(const char *);
229 extern void panic(const char *, ...);
230 void *m_alloc(size_t amt){
234 if (!ptr) panic("Memory allocation failure; cannot get %lu bytes", amt);
238 void mar_clear_messagewin(void){
239 int i, *ptr=message_age;
241 if(WIN_MESSAGE==WIN_ERR) return;
242 for(i=msg_anz;--i>=0;ptr++){
244 Gem_nhwindow[WIN_MESSAGE].gw_dirty=TRUE;
247 mar_message_pause=FALSE;
249 mar_display_nhwindow(WIN_MESSAGE);
252 void clipbrd_save(void *data,int cnt,boolean append,boolean is_inv){
253 char path[MAX_PATH],*text,*crlf="\r\n";
257 if (data && cnt>0 && scrp_path(path,"scrap.txt") && (handle = append ? Fopen(path,1) : Fcreate(path,0))>0){
259 Fseek(0L,(int) handle,SEEK_END);
261 Gem_menu_item *it=(Gem_menu_item *)data;
263 for(;it;it=it->Gmi_next){
265 Fwrite((int) handle,strlen(text),text);
266 Fwrite((int) handle,2L,crlf);
270 text=((char **)data)[i]+1;
271 Fwrite((int) handle,strlen(text),text);
272 Fwrite((int) handle,2L,crlf);
275 Fclose((int) handle);
277 scrp_changed(SCF_TEXT,0x2e545854l); /* .TXT */
281 void move_win(WIN *z_win){
285 v_set_line(BLACK,1,1,0,0);
286 frame.g_w<<=1, frame.g_h<<=1;
287 if(graf_rt_dragbox(FALSE,&z_win->curr,&frame,&z_win->curr.g_x,&z_win->curr.g_y,NULL))
288 window_size(z_win,&z_win->curr);
293 void message_handler(int x, int y){
294 switch(objc_find(zz_oblist[MSGWIN],ROOT,MAX_DEPTH,x,y)){
296 if(msg_pos>msg_vis-1){
298 Gem_nhwindow[WIN_MESSAGE].gw_dirty=TRUE;
299 mar_display_nhwindow(WIN_MESSAGE);
301 Event_Timer(50,0,TRUE);
306 Gem_nhwindow[WIN_MESSAGE].gw_dirty=TRUE;
307 mar_display_nhwindow(WIN_MESSAGE);
309 Event_Timer(50,0,TRUE);
313 move_win(Gem_nhwindow[WIN_MESSAGE].gw_window);
320 int mar_ob_mapcenter(OBJECT *p_obj){
321 WIN *p_w= WIN_MAP!=WIN_ERR ? Gem_nhwindow[WIN_MAP].gw_window : NULL;
324 p_obj->ob_x=p_w->work.g_x+p_w->work.g_w/2-p_obj->ob_width/2;
325 p_obj->ob_y=p_w->work.g_y+p_w->work.g_h/2-p_obj->ob_height/2;
328 return(DIA_CENTERED);
331 /****************************** set_no_glyph *************************************/
341 mar_set_tilefile(name)
362 /****************************** userdef_draw *************************************/
364 void rearrange_windows(void);
365 void mar_set_status_align(int sa){
366 if(status_align!=sa){
371 void mar_set_msg_align(int ma){
377 void mar_set_msg_visible(int mv){
380 Min(&mv,min(msg_anz,20));
381 Min(&mv,desk.g_h/msg_font.ch/2);
386 /* size<0 cellheight; size>0 points */
387 void mar_set_fontbyid(int type, int id, int size){
391 if((size>-3 && size<3) || size<-20 || size>20)
393 /* MAR -- 17.Mar 2002 For now allow FNT_PROP only with NHW_TEXT */
394 if(type!=NHW_TEXT && (FontInfo(id)->type & (FNT_PROP|FNT_ASCII)))
398 if(msg_font.size==-size && msg_font.id==id)
402 msg_font.prop=FontInfo(id)->type & (FNT_PROP|FNT_ASCII);
403 v_set_text(msg_font.id,msg_font.size,BLACK,0,0,chardim);
404 msg_font.ch=chardim[3] ? chardim[3] : 1;
405 msg_font.cw=chardim[2] ? chardim[2] : 1;
406 msg_width=min(max_w/msg_font.cw-3,MSGLEN);
410 if(map_font.size!=-size || map_font.id!=id){
414 map_font.prop=FontInfo(id)->type & (FNT_PROP|FNT_ASCII);
415 v_set_text(map_font.id,map_font.size,BLACK,0,0,chardim);
416 map_font.ch=chardim[3] ? chardim[3] : 1;
417 map_font.cw=chardim[2] ? chardim[2] : 1;
418 mfdb(&mtmp,NULL,(COLNO-1)*map_font.cw, ROWNO*map_font.ch, 0, planes);
419 if(mfdb_size(&mtmp)>mfdb_size(&FontCol_Bild) && mfdb_size(&mtmp)>mfdb_size(&Map_bild)){
420 FontCol_Bild.fd_addr=Map_bild.fd_addr=(int *)realloc(Map_bild.fd_addr,mfdb_size(&mtmp));
421 if(!Map_bild.fd_addr) /* FIXME -- Not really neccessary since the former space is still valid */
422 panic("Not enough Space for the map.");
424 mfdb(&FontCol_Bild,FontCol_Bild.fd_addr,(COLNO-1)*map_font.cw, ROWNO*map_font.ch, 0, planes);
429 if(status_font.size==-size && status_font.id==id)
431 status_font.size=-size;
433 status_font.prop=FontInfo(id)->type & (FNT_PROP|FNT_ASCII);
434 v_set_text(status_font.id,status_font.size,BLACK,0,0,chardim);
435 status_font.ch=chardim[3] ? chardim[3] : 1;
436 status_font.cw=chardim[2] ? chardim[2] : 1;
440 if(menu_font.size==-size && menu_font.id==id)
442 menu_font.size=-size;
444 menu_font.prop=FontInfo(id)->type & (FNT_PROP|FNT_ASCII);
445 v_set_text(menu_font.id,menu_font.size,BLACK,0,0,chardim);
446 menu_font.ch=chardim[3] ? chardim[3] : 1;
447 menu_font.cw=chardim[2] ? chardim[2] : 1;
450 if(text_font.size==-size && text_font.id==id)
452 text_font.size=-size;
454 text_font.prop=FontInfo(id)->type & (FNT_PROP|FNT_ASCII);
455 v_set_text(text_font.id,text_font.size,BLACK,0,0,chardim);
456 text_font.ch=chardim[3] ? chardim[3] : 1;
457 text_font.cw=chardim[2] ? chardim[2] : 1;
463 void mar_set_font(int type, const char *font_name, int size){
465 /* MAR -- 17.Mar 2002 usual Gem behavior, use the Font-ID */
466 if(font_name && *font_name){
471 for(i=fonts_loaded;--i>=0;){
472 tid=vqt_name(x_handle,i,name);
473 if(!stricmp(name,font_name)){
480 mar_set_fontbyid(type,id,size);
482 void rearrange_windows(void){
485 if(WIN_MAP != WIN_ERR && Gem_nhwindow[WIN_MAP].gw_window){
486 scroll_map.px_hline=mar_set_tile_mode(FAIL)?Tile_width:map_font.cw;
487 scroll_map.px_vline=mar_set_tile_mode(FAIL)?Tile_heigth:map_font.ch;
489 calc_std_winplace(FAIL,&area);
492 calc_std_winplace(NHW_MAP,&area);
493 Gem_nhwindow[WIN_MAP].gw_window->max.g_w=area.g_w;
494 Gem_nhwindow[WIN_MAP].gw_window->max.g_h=area.g_h;
495 Gem_nhwindow[WIN_MAP].gw_window->max.g_w=area.g_w;
496 window_reinit(Gem_nhwindow[WIN_MAP].gw_window,md,md,NULL,FALSE,FALSE);
501 AvSendMsg(ap_id,AV_SENDKEY,buf);
504 if(WIN_MESSAGE != WIN_ERR && Gem_nhwindow[WIN_MESSAGE].gw_window){
506 calc_std_winplace(FAIL,&area);
509 calc_std_winplace(NHW_MESSAGE,&area);
510 Gem_nhwindow[WIN_MESSAGE].gw_window->min_h=area.g_h;
511 window_size(Gem_nhwindow[WIN_MESSAGE].gw_window,&area);
512 redraw_window(Gem_nhwindow[WIN_MESSAGE].gw_window,NULL);
514 if(WIN_STATUS != WIN_ERR && Gem_nhwindow[WIN_STATUS].gw_window){
516 calc_std_winplace(FAIL,&area);
519 calc_std_winplace(NHW_STATUS,&area);
520 Gem_nhwindow[WIN_STATUS].gw_window->min_h=area.g_h;
521 window_size(Gem_nhwindow[WIN_STATUS].gw_window,&area);
522 redraw_window(Gem_nhwindow[WIN_STATUS].gw_window,NULL);
525 void my_color_area(GRECT *area, int col){
528 v_set_fill(col,1,IP_SOLID,0);
529 rc_grect_to_array(area,pxy);
533 void my_clear_area(GRECT *area){
534 my_color_area(area, WHITE);
537 int mar_set_tile_mode(int);
539 static void win_draw_map(int first, WIN *win, GRECT *area){
540 int pla[8], w=area->g_w-1, h=area->g_h-1;
546 if(!mar_set_tile_mode(FAIL)){
547 int start=(area->g_x-win->work.g_x)/map_font.cw+scroll_map.hpos;
548 int stop=(area->g_x+area->g_w+map_font.cw-1-win->work.g_x)/map_font.cw+scroll_map.hpos;
549 int starty=(area->g_y-win->work.g_y)/map_font.ch+scroll_map.vpos;
550 int stopy=min((area->g_y+area->g_h+map_font.ch-1-win->work.g_y)/map_font.ch+scroll_map.vpos,ROWNO);
552 v_set_text(map_font.id,map_font.size,WHITE,0,0,NULL);
553 v_set_mode(MD_TRANS);
555 x=win->work.g_x-scroll_map.px_hpos+start*map_font.cw;
556 y=win->work.g_y-scroll_map.px_vpos+starty*map_font.ch;
557 pla[2]=pla[0]=scroll_map.px_hpos+area->g_x-win->work.g_x;
558 pla[3]=pla[1]=starty*map_font.ch;
560 pla[3]+=map_font.ch-1;
561 pla[6]=pla[4]=area->g_x; /* x_wert to */
562 pla[7]=pla[5]=y; /* y_wert to */
564 pla[7]+=map_font.ch-1;
565 back.g_h=map_font.ch;
566 for(i=starty;i<stopy;i++,y+=map_font.ch,pla[1]+=map_font.ch,pla[3]+=map_font.ch,pla[5]+=map_font.ch,pla[7]+=map_font.ch){
568 my_color_area(&back,BLACK);
569 tmp=map_glyphs[i][stop];
570 map_glyphs[i][stop]=0;
571 (*v_mtext)(x_handle,x,y,&map_glyphs[i][start]);
572 map_glyphs[i][stop]=tmp;
573 vro_cpyfm(x_handle, S_OR_D, pla, &FontCol_Bild, screen);
576 v_set_mode(MD_REPLACE);
577 pla[2]=pla[0]=scroll_map.px_hpos+area->g_x-win->work.g_x;
578 pla[3]=pla[1]=scroll_map.px_vpos+area->g_y-win->work.g_y;
581 pla[6]=pla[4]=area->g_x; /* x_wert to */
582 pla[7]=pla[5]=area->g_y; /* y_wert to */
585 vro_cpyfm(x_handle, S_ONLY, pla, &Map_bild, screen);
589 v_set_line(curs_col,1,1,0,0);
590 pla[0]=pla[2]=win->work.g_x+scroll_map.px_hline*(map_cursx-scroll_map.hpos);
591 pla[1]=pla[3]=win->work.g_y+scroll_map.px_vline*(map_cursy-scroll_map.vpos);
592 pla[2]+=scroll_map.px_hline-1;
593 pla[3]+=scroll_map.px_vline-1;
594 v_rect(pla[0],pla[1],pla[2],pla[3]);
598 static int draw_titel(PARMBLK *pb){
600 GRECT work=*(GRECT *) &pb->pb_x;
602 if(rc_intersect((GRECT *)&pb->pb_xc,&work)){
606 pla[6]=pla[4]=pb->pb_x; /* x_wert to */
607 pla[7]=pla[5]=pb->pb_y; /* y_wert to */
611 vro_cpyfm(x_handle, S_ONLY, pla, &Titel_bild, screen);
617 static int draw_lines(PARMBLK *pb){
618 GRECT area=*(GRECT *) &pb->pb_x;
620 if(rc_intersect((GRECT *)&pb->pb_xc,&area)){
622 int x=pb->pb_x,y=pb->pb_y,start_line=(area.g_y-y);
624 v_set_mode((text_font.cw&7)==0 && text_font.prop==0 ? MD_REPLACE : MD_TRANS);
626 /* void v_set_text(int font,int height,int color,int effect,int rotate,int out[4]) */
627 v_set_text(text_font.id,text_font.size,BLACK,0,0,NULL);
628 start_line /= text_font.ch;
629 y+=start_line*text_font.ch;
630 x-=(int)scroll_menu.px_hpos;
631 ptr=&text_lines[start_line+=scroll_menu.vpos];
632 start_line = min((area.g_y-y+area.g_h+text_font.ch-1)/text_font.ch,Anz_text_lines-start_line);
633 area.g_h=text_font.ch;
636 for(;--start_line>=0;y+=text_font.ch){
638 my_clear_area(&area);
640 v_set_text(FAIL,0,BLUE,0x01,0,NULL);
641 (*v_mtext)(x_handle,x,y,(*ptr++)+1);
642 v_set_text(FAIL,0,BLACK,0x00,0,NULL);
644 (*v_mtext)(x_handle,x,y,(*ptr++)+1);
650 static int draw_rip(PARMBLK *pb){
651 GRECT area=*(GRECT *) &pb->pb_x;
652 if(rc_intersect((GRECT *)&pb->pb_xc,&area)){
654 int x=pb->pb_x,y=pb->pb_y,start_line=(area.g_y-y), chardim[4], pla[8],i;
655 v_set_mode(MD_REPLACE);
656 /* void v_set_text(int font,int height,int color,int effect,int rotate,int out[4]) */
657 v_set_text(text_font.id,text_font.size,BLACK,0,0,chardim);
658 start_line /= text_font.ch;
659 y+=start_line*text_font.ch;
660 x-=scroll_menu.px_hpos;
661 ptr=&text_lines[start_line+=scroll_menu.vpos];
662 start_line = min((area.g_y-y+area.g_h+text_font.ch-1)/text_font.ch,Anz_text_lines-start_line);
663 area.g_h=text_font.ch;
666 for(;--start_line>=0;y+=text_font.ch){
668 my_clear_area(&area);
670 v_set_text(FAIL,0,BLUE,0x01,0,NULL);
671 (*v_mtext)(x_handle,x,y,(*ptr++)+1);
672 v_set_text(FAIL,0,BLACK,0x00,0,NULL);
674 (*v_mtext)(x_handle,x,y,(*ptr++)+1);
677 pla[2]=min(pb->pb_w-1,Rip_bild.fd_w-1);
678 pla[3]=min(pb->pb_h-1,Rip_bild.fd_h-1);
679 pla[6]=pla[4]=pb->pb_x+(pb->pb_w-Rip_bild.fd_w)/2; /* x_wert to */
680 pla[7]=pla[5]=pb->pb_y; /* y_wert to */
683 vro_cpyfm(x_handle, S_ONLY, pla, &Rip_bild, screen);
684 v_set_mode(MD_TRANS);
685 vst_alignment(x_handle,1,5,&i,&i);
687 for(i=0;i<7;i++,pla[5]+=chardim[3]){
688 v_set_text(text_font.id,(i==0 || i==6) ? text_font.size : 12,WHITE,1,0,chardim);
689 (*v_mtext)(x_handle,pla[4]+157,pla[5],rip_line[i]);
690 v_set_text(text_font.id,(i==0 || i==6) ? text_font.size : 12,BLACK,0,0,chardim);
691 (*v_mtext)(x_handle,pla[4]+157,pla[5],rip_line[i]);
693 vst_alignment(x_handle,0,5,&i,&i);
698 static int draw_msgline(PARMBLK *pb){
699 GRECT area=*(GRECT *) &pb->pb_x;
701 if(rc_intersect((GRECT *)&pb->pb_xc,&area)){
702 int x=pb->pb_x, y=pb->pb_y+(msg_vis-1)*msg_font.ch, foo, i;
703 char **ptr=&message_line[msg_pos], tmp;
704 int startx, stopx, starty, stopy;
706 x=(x+7) & ~7; /* Byte alignment speeds output up */
708 v_set_mode(MD_REPLACE);
710 /* void v_set_text(int font,int height,int color,int effect,int rotate,int out[4]) */
711 v_set_text(msg_font.id,msg_font.size,FAIL, FAIL,0,NULL);
712 vst_alignment(x_handle,0,5,&foo,&foo);
713 stopy=min(msg_pos,msg_vis);
715 startx=(area.g_x-x)/msg_font.cw-1; /* MAR 06.02.2001 -- because italic covers the next char */
717 stopx=(area.g_x+area.g_w+msg_font.cw-x-1)/msg_font.cw;
718 x+=startx*msg_font.cw;
719 for(i=0;i<stopy;i++,y-=msg_font.ch,ptr--){
720 if(message_age[msg_pos-i])
721 v_set_text(FAIL,0,BLACK,0,0,NULL);
723 v_set_text(FAIL,0,LBLACK,4,0,NULL);
726 (*v_mtext)(x_handle,x,y,&(*ptr)[startx]);
733 static int draw_status(PARMBLK *pb){
734 GRECT area=*(GRECT *) &pb->pb_x;
736 area.g_x+=2*status_font.cw-2;
737 area.g_w-=2*status_font.cw-2;
738 if(rc_intersect((GRECT *)&pb->pb_xc,&area)){
739 int x=pb->pb_x, y=pb->pb_y, startx, stopx, starty, stopy, i;
742 /* void v_set_text(int font,int height,int color,int effect,int rotate,int out[4]) */
743 v_set_mode(MD_REPLACE);
744 v_set_text(status_font.id,status_font.size,BLACK,0,0,NULL);
745 x = (x+2*status_font.cw+6) & ~7;
747 startx=(area.g_x-x)/status_font.cw;
748 starty=(area.g_y-y)/status_font.ch;
749 stopx=(area.g_x+area.g_w+status_font.ch-1-x)/status_font.cw;
750 stopy=(area.g_y+area.g_h+status_font.ch-1-y)/status_font.ch;
751 Max(&startx,0); /* MAR -- Hmm, area.g_x could end up 1 below x */
753 x+=startx*status_font.cw;
754 y+=starty*status_font.ch;
756 area.g_h=status_font.ch;
757 for(i=starty;i<min(2,stopy);i++,area.g_y+=status_font.ch,y+=status_font.ch){
758 my_clear_area(&area);
759 tmp=status_line[i][stopx];
760 status_line[i][stopx]=0;
761 (*v_mtext)(x_handle,x,y,&status_line[i][startx]);
762 status_line[i][stopx]=tmp;
768 static int draw_inventory(PARMBLK *pb){
769 GRECT area=*(GRECT *) &pb->pb_x;
771 if(rc_intersect((GRECT *)&pb->pb_xc,&area)){
772 int gl, i, x=pb->pb_x, y=pb->pb_y,start_line=area.g_y-y;
775 v_set_mode(MD_REPLACE);
776 v_set_text(menu_font.id,menu_font.size,BLACK,0,0,NULL);
778 start_line /= menu_font.ch;
779 y+=start_line*menu_font.ch;
780 x-=scroll_menu.px_hpos;
781 start_line+=scroll_menu.vpos;
783 for(it=invent_list,i=start_line; --i>=0 && it; it=it->Gmi_next);
785 i = min((area.g_y-y+area.g_h+menu_font.ch-1)/menu_font.ch,Anz_inv_lines-start_line);
788 area.g_h=menu_font.ch;
790 for(;(--i>=0) && it;it=it->Gmi_next,y+=menu_font.ch){
792 v_set_text(FAIL,FALSE,BLUE,1,FAIL,NULL); /* Bold */
794 v_set_text(FAIL,FALSE,BLACK,0,FAIL,NULL);
797 my_clear_area(&area);
798 if((gl=it->Gmi_glyph) != no_glyph){
799 int pla[8], h=min(menu_font.ch,Tile_heigth)-1;
801 pla[0]=pla[2]=(gl%Tiles_per_line)*Tile_width; /* x_wert from */
802 pla[1]=pla[3]=(gl/Tiles_per_line)*Tile_heigth; /* y_wert from */
803 pla[4]=pla[6]=x; /* x_wert to */
804 pla[5]=pla[7]=y; /* y_wert to */
805 pla[2]+=Tile_width-1;
807 pla[6]+=Tile_heigth-1;
810 vro_cpyfm(x_handle,S_ONLY,pla,&Tile_bilder,screen);
812 if(it->Gmi_identifier)
813 it->Gmi_str[2]=it->Gmi_selected ? (it->Gmi_count == -1L ? '+' : '#') : '-';
814 (*v_mtext)(x_handle,(x+23) & ~7,y,it->Gmi_str);
820 static int draw_prompt(PARMBLK *pb){
821 GRECT area=*(GRECT *) &pb->pb_x;
823 if(rc_intersect((GRECT *)&pb->pb_xc,&area)){
824 char **ptr=(char **)pb->pb_parm;
825 int x=pb->pb_x, y=pb->pb_y, chardim[4];
827 /* void v_set_text(int font,int height,int color,int effect,int rotate,int out[4]) */
828 v_set_mode(MD_TRANS);
829 v_set_text(ibm_font_id,ibm_font,WHITE,0,0,chardim);
833 v_set_fill(BLACK,2,4,0);
834 rc_grect_to_array(&area,pxy);
837 my_color_area(&area,LWHITE);
838 (*v_mtext)(x_handle,x,y,*(ptr++));
840 (*v_mtext)(x_handle,x,y+chardim[3],*ptr);
845 static USERBLK ub_lines={draw_lines, 0L}, ub_msg={draw_msgline, 0L},
846 ub_inventory={draw_inventory, 0L}, ub_titel={draw_titel, 0L},
847 ub_status={draw_status, 0L}, ub_prompt={draw_prompt, 0L};
849 /**************************** rsc_funktionen *****************************/
851 void my_close_dialog(DIAINFO *dialog,boolean shrink_box){
852 close_dialog(dialog,shrink_box);
853 Event_Timer(0,0,TRUE);
857 mar_get_rsc_tree(obj_number, z_ob_obj)
861 rsrc_gaddr( R_TREE, obj_number, z_ob_obj );
862 fix_objects(*z_ob_obj,SCALING,0,0);
865 void mar_clear_map(void);
875 sprintf(buf,"%s","[1][ Image Header | corrupt. ][ Oops ]");
878 sprintf(buf,"%s","[1][ Not enough | memory for | an image. ][ Oops ]");
881 sprintf(buf,"%s","[1][ The Image-file | is not available ][ Oops ]");
884 sprintf(buf,"%s","[1][ The Image-file | is corrupt ][ Oops ]");
887 sprintf(buf,"%s","[1][ Number of colors | not supported ][ Oops ]");
890 sprintf(buf,"[1][ img_error | strange error | number: %i ][ Hmm ]",errnumber);
896 void mar_change_button_char(OBJECT *z_ob, int nr, char ch){
897 *ob_get_text(z_ob,nr,0)=ch;
898 ob_set_hotkey(z_ob,nr,ch);
904 static int mi_numpad=FAIL;
905 char mcmd[]="bjnh.lyku", npcmd[]="123456789", *p_cmd;
907 if(mi_numpad!=mar_iflags_numpad()){
908 OBJECT *z_ob=zz_oblist[DIRECTION];
910 mi_numpad=mar_iflags_numpad();
911 ob_set_hotkey(z_ob,DIRDOWN,'>');
912 ob_set_hotkey(z_ob,DIRUP,'<');
913 p_cmd= mi_numpad ? npcmd : mcmd;
915 mar_change_button_char(z_ob,DIR1+2*i,p_cmd[i]);
919 extern int total_tiles_used; /* tile.c */
924 int i, bild_fehler=FALSE, fsize;
926 static MITEM wish_workaround= {FAIL,key(0,'J'),K_CTRL,W_CYCLE,FAIL};
929 if((i=open_rsc("gem_rsc.rsc",NULL,md,md,md,0,0,0))<=0){
930 graf_mouse(M_OFF,NULL);
932 form_alert(1,"[3][| Fatal Error | File: GEM_RSC.RSC | not found. ][ grumble ]");
934 form_alert(1,"[3][| Fatal Error | GEM initialisation | failed. ][ a pity ]");
937 if(planes<1 || planes>8){
938 form_alert(1,"[3][ Color-depth | not supported, | try 2-256 colors. ][ Ok ]");
943 /* MAR -- 17.Mar 2002 NVDI 3.0 or better uses v_ftext */
944 v_mtext= speedo==3 ? &v_ftext : &v_gtext;
945 for(i=0;i<NHICON;i++)
946 mar_get_rsc_tree(i, &zz_oblist[i]);
948 z_ob=zz_oblist[ABOUT];
949 ob_hide(z_ob,OKABOUT,TRUE);
950 ob_draw_dialog(z_ob,0,0,0,0);
952 mar_get_font(NHW_MESSAGE,&fname,&fsize);
953 mar_set_font(NHW_MESSAGE,fname,fsize);
954 mar_get_font(NHW_MAP,&fname,&fsize);
955 mar_set_font(NHW_MAP,fname,fsize);
956 mar_get_font(NHW_STATUS,&fname,&fsize);
957 mar_set_font(NHW_STATUS,fname,fsize);
958 mar_get_font(NHW_MENU,&fname,&fsize);
959 mar_set_font(NHW_MENU,fname,fsize);
960 mar_get_font(NHW_TEXT,&fname,&fsize);
961 mar_set_font(NHW_TEXT,fname,fsize);
962 msg_anz=mar_get_msg_history();
963 mar_set_msg_visible(mar_get_msg_visible());
964 msg_width=min(max_w/msg_font.cw-3,MSGLEN);
966 if(max_w/status_font.cw<COLNO-1)
967 mar_set_fontbyid(NHW_STATUS,small_font_id,-small_font);
968 status_w=min(max_w/status_font.cw-3,MSGLEN);
970 if(planes>0 && planes<9){
971 normal_palette=(short *)m_alloc(3*colors*sizeof(short));
972 get_colors(x_handle,normal_palette, colors);
976 bild_fehler=depack_img(Tilefile?Tilefile:(planes>=4)?"NH16.IMG":"NH2.IMG",&tile_image);
978 z_ob=zz_oblist[ABOUT];
979 ob_undraw_dialog(z_ob,0,0,0,0);
980 ob_hide(z_ob,OKABOUT,FALSE);
981 img_error(bild_fehler);
984 if(tile_image.img_w%Tile_width || tile_image.img_h%Tile_heigth){
986 Tile_width=Tile_heigth=16;
987 printf("size didn't match.\n");
990 if((tile_image.img_w/Tile_width)*(tile_image.img_h/Tile_heigth)<total_tiles_used){
992 Tile_width=Tile_heigth=16;
993 printf("Too few Tiles in Image.\n");
996 Tiles_per_line=tile_image.img_w/Tile_width;
999 if(tile_image.planes>1)
1000 img_set_colors(x_handle, tile_image.palette, tile_image.planes);
1004 img_set_colors(x_handle, mypalette, 4);
1009 mfdb(&Tile_bilder, (int *)tile_image.addr, tile_image.img_w, tile_image.img_h, 1, tile_image.planes);
1010 transform_img(&Tile_bilder);
1012 mfdb(&Map_bild,NULL,(COLNO-1)*Tile_width, ROWNO*Tile_heigth, 0, planes);
1013 mfdb(&FontCol_Bild,NULL,(COLNO-1)*map_font.cw, ROWNO*map_font.ch, 0, planes);
1014 Map_bild.fd_addr=(int *)m_alloc(mfdb_size(&Map_bild)>mfdb_size(&FontCol_Bild)?mfdb_size(&Map_bild):mfdb_size(&FontCol_Bild));
1015 FontCol_Bild.fd_addr=Map_bild.fd_addr;
1017 mfdb(&Pet_Mark,pet_mark_data,8, 7, 1, 1);
1018 vr_trnfm(x_handle,&Pet_Mark,&Pet_Mark);
1020 mfdb(&Black_bild,NULL,16, 32, 1, 1); /* MAR -- 17.Mar 2002 that should cover the biggest map-font */
1021 Black_bild.fd_addr=(int *)m_alloc(mfdb_size(&Black_bild));
1022 memset(Black_bild.fd_addr,255,mfdb_size(&Black_bild));
1023 vr_trnfm(x_handle,&Black_bild,&Black_bild);
1025 for(i=0;i<MAXWIN;i++){
1026 Gem_nhwindow[i].gw_window=NULL;
1027 Gem_nhwindow[i].gw_type=0;
1028 Gem_nhwindow[i].gw_dirty=TRUE;
1031 memset(&scroll_menu,0,sizeof(scroll_menu));
1032 scroll_menu.scroll=AUTO_SCROLL;
1033 scroll_menu.obj=LINESLIST;
1034 scroll_menu.px_hline=menu_font.cw;
1035 scroll_menu.px_vline=menu_font.ch;
1036 scroll_menu.hscroll=
1037 scroll_menu.vscroll=1;
1038 scroll_menu.tbar_d=2*gr_ch-2;
1042 memset(&scroll_map,0,sizeof(scroll_map));
1043 scroll_map.scroll=AUTO_SCROLL;
1044 scroll_map.obj=ROOT;
1045 scroll_map.px_hline=mar_set_tile_mode(FAIL)?Tile_width:map_font.cw;
1046 scroll_map.px_vline=mar_set_tile_mode(FAIL)?Tile_heigth:map_font.ch;
1047 scroll_map.hsize=COLNO-1;
1048 scroll_map.vsize=ROWNO;
1051 scroll_map.hscroll=1;
1052 scroll_map.vscroll=1;
1054 /* dial_options( round, niceline, standard, return_default, background, nonselectable,
1055 always_keys, toMouse, clipboard, hz); */
1056 dial_options(TRUE,TRUE,FALSE,RETURN_DEFAULT,AES_BACK,TRUE,KEY_ALWAYS,FALSE,TRUE,3);
1057 /* dial_colors( dial_pattern, dial_color, dial_frame, hotkey, alert, cycle_button,
1058 check_box, radio_button, arrow, cycle_backgrnd, check_backgrnd, radio_backgrnd,
1059 arrow_backgrnd, edit_3d, draw_3d) */
1061 dial_colors(4,BLACK,WHITE,RED,RED,WHITE,BLACK,BLACK,BLACK,FAIL,FAIL,FAIL,FAIL,TRUE,TRUE);
1063 dial_colors(7,LWHITE,BLACK,RED,RED,BLACK,BLACK,BLACK,BLACK,WHITE,WHITE,WHITE,WHITE,TRUE,TRUE);
1065 /* void MenuItems(MITEM *close,MITEM *closeall,MITEM *cycle,MITEM *invcycle,
1066 MITEM *globcycle,MITEM *full,MITEM *bottom,MITEM *iconify,MITEM *iconify_all,
1067 MITEM *menu,int menu_cnt) */
1068 /* Ctrl-W ist normaly bound to cycle */
1069 MenuItems(NULL,NULL,&wish_workaround,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0);
1071 menu_install(zz_oblist[MENU],TRUE);
1073 z_ob=zz_oblist[ABOUT];
1074 ob_undraw_dialog(z_ob,0,0,0,0);
1075 ob_hide(z_ob,OKABOUT,FALSE);
1080 /************************* mar_exit_nhwindows *******************************/
1083 mar_exit_nhwindows()
1087 for(i=MAXWIN;--i>=0;)
1088 if(Gem_nhwindow[i].gw_type)
1089 mar_destroy_nhwindow(i);
1092 img_set_colors(x_handle,normal_palette,tile_image.planes);
1093 null_free(normal_palette);
1095 test_free(tile_image.palette);
1096 test_free(tile_image.addr);
1097 test_free(titel_image.palette);
1098 test_free(titel_image.addr);
1101 /************************* mar_curs *******************************/
1107 Min(&dirty_map_area.g_x,x);
1108 Min(&dirty_map_area.g_y,y);
1109 Max(&dirty_map_area.g_w,x);
1110 Max(&dirty_map_area.g_h,y);
1111 Min(&dirty_map_area.g_x,map_cursx);
1112 Min(&dirty_map_area.g_y,map_cursy);
1113 Max(&dirty_map_area.g_w,map_cursx);
1114 Max(&dirty_map_area.g_h,map_cursy);
1119 if(WIN_MAP!=WIN_ERR)
1120 Gem_nhwindow[WIN_MAP].gw_dirty=TRUE;
1123 void mar_cliparound(void);
1124 void mar_map_curs_weiter(void)
1126 static int once=TRUE;
1129 redraw_window(Gem_nhwindow[WIN_STATUS].gw_window,NULL);
1130 redraw_window(Gem_nhwindow[WIN_MESSAGE].gw_window,NULL);
1133 mar_curs(map_cursx+1,map_cursy);
1137 /************************* about *******************************/
1142 xdialog(zz_oblist[ABOUT], md, NULL, NULL, DIA_CENTERED, FALSE, DIALOG_MODE);
1143 Event_Timer(0,0,TRUE);
1146 /************************* ask_name *******************************/
1151 OBJECT *z_ob=zz_oblist[NAMEGET];
1153 char who_are_you[] = "Who are you? ";
1155 bild_fehler=depack_img(planes<4 ? "TITLE2.IMG" : "TITLE.IMG", &titel_image);
1156 if(bild_fehler ){ /* MAR -- this isn't lethal */
1157 ob_set_text(z_ob,NETHACKPICTURE,"missing title.img.");
1159 mfdb(&Titel_bild, (int *)titel_image.addr, titel_image.img_w, titel_image.img_h, 1, titel_image.planes);
1160 transform_img(&Titel_bild);
1161 z_ob[NETHACKPICTURE].ob_type=G_USERDEF;
1162 z_ob[NETHACKPICTURE].ob_spec.userblk=&ub_titel;
1165 ob_clear_edit(z_ob);
1166 xdialog(z_ob,who_are_you, NULL, NULL, DIA_CENTERED, FALSE, DIALOG_MODE);
1167 Event_Timer(0,0,TRUE);
1169 test_free(titel_image.palette);
1170 test_free(titel_image.addr);
1171 test_free(Titel_bild.fd_addr);
1172 return(ob_get_text(z_ob,PLNAME,0));
1175 /************************* more *******************************/
1182 buf[3]=0; /* No Shift/Ctrl/Alt */
1184 AvSendMsg(ap_id,AV_SENDKEY,buf);
1190 send_key(key(SCANRET,0));
1194 K_Init(xev,availiable)
1199 return(MU_KEYBD&availiable);
1203 KM_Init(xev,availiable)
1208 return((MU_KEYBD|MU_MESAG)&availiable);
1212 M_Init(xev,availiable)
1217 return(MU_MESAG&availiable);
1220 #define More_Init K_Init
1226 int ev=xev->ev_mwich;
1229 char ch=(char)(xev->ev_mkreturn&0x00FF);
1234 case '\033': /* no more more more */
1236 if((w=get_top_window()) && (dinf=(DIAINFO *)w->dialog) && dinf->di_tree==zz_oblist[PAGER]){
1238 mar_esc_pressed=TRUE;
1244 ev &= ~MU_KEYBD; /* unknown key */
1254 if(!mar_esc_pressed){
1255 OBJECT *z_ob=zz_oblist[PAGER];
1258 Event_Handler(More_Init,More_Handler);
1259 dial_colors(7,RED,BLACK,RED,RED,BLACK,BLACK,BLACK,BLACK,WHITE,WHITE,WHITE,WHITE,TRUE,TRUE);
1260 if(WIN_MESSAGE!=WIN_ERR && (p_w=Gem_nhwindow[WIN_MESSAGE].gw_window)){
1261 z_ob->ob_x=p_w->work.g_x;
1262 z_ob->ob_y=p_w->curr.g_y+p_w->curr.g_h+gr_ch;
1264 xdialog(z_ob,NULL, NULL, NULL, DIA_LASTPOS, FALSE, DIALOG_MODE);
1265 Event_Timer(0,0,TRUE);
1266 Event_Handler(NULL,NULL);
1269 dial_colors(4,BLACK,WHITE,RED,RED,WHITE,BLACK,BLACK,BLACK,FAIL,FAIL,FAIL,FAIL,TRUE,TRUE);
1271 dial_colors(7,LWHITE,BLACK,RED,RED,BLACK,BLACK,BLACK,BLACK,WHITE,WHITE,WHITE,WHITE,TRUE,TRUE);
1275 /************************* Gem_start_menu *******************************/
1282 Gem_menu_item *curr, *next;
1284 for(curr=invent_list;curr;curr=next){
1285 next=curr->Gmi_next;
1286 free(curr->Gmi_str);
1295 /************************* mar_add_menu *******************************/
1298 mar_add_menu(win, item)
1300 Gem_menu_item *item;
1303 item->Gmi_next = invent_list;
1311 Gem_menu_item *next, *head = 0, *curr=invent_list;
1314 next = curr->Gmi_next;
1315 curr->Gmi_next = head;
1323 mar_set_accelerators()
1326 Gem_menu_item *curr;
1328 for(curr=invent_list;curr;curr=curr->Gmi_next){
1330 v_set_text(menu_font.id,menu_font.size,BLACK,0,0,NULL);
1331 vqt_extent(x_handle,curr->Gmi_str,extent);
1332 Max(&Inv_breite,extent[4]+Tile_width+menu_font.cw);
1333 if(ch && curr->Gmi_accelerator==0 && curr->Gmi_identifier){
1334 curr->Gmi_accelerator=ch;
1335 curr->Gmi_str[0]=ch;
1337 else if(ch=='Z') ch=0;
1346 return(invent_list);
1349 /************************* mar_putstr_text *********************/
1351 void mar_raw_print(const char *);
1353 void mar_set_text_to_rip(winid w){
1357 mar_putstr_text(winid window, int attr, const char *str)
1359 static int zeilen_frei=0;
1365 text_lines=(char **)m_alloc(12*sizeof(char *));
1369 text_lines=(char **)realloc(text_lines,(Anz_text_lines+12)*sizeof(char *));
1373 mar_raw_print("No room for Text");
1380 ptr=text_lines[Anz_text_lines]=(char *)m_alloc(breite*sizeof(char)+2);
1381 *ptr=(char)(attr+1); /* avoid 0 */
1382 strncpy(ptr+1,str,breite);
1389 mar_set_inv_win(Anzahl, Breite)
1392 OBJECT *z_ob=zz_oblist[LINES];
1393 int retval=WIN_DIAL|MODAL|NO_ICONIFY;
1395 scroll_menu.hsize=0;
1396 scroll_menu.vpage= (desk.g_h-3*gr_ch)/scroll_menu.px_vline;
1397 if(Anzahl>scroll_menu.vpage){
1398 retval |= WD_VSLIDER;
1399 if(Breite>max_w-3*scroll_menu.px_hline){
1401 scroll_menu.hpage=(max_w-3*scroll_menu.px_hline)/scroll_menu.px_hline;
1403 scroll_menu.hsize=Breite/scroll_menu.px_hline;
1404 scroll_menu.vpage=(desk.g_h-4*gr_ch-1)/scroll_menu.px_vline;
1406 Anzahl=scroll_menu.vpage;
1408 if(Breite>max_w-scroll_menu.px_hline){
1410 scroll_menu.hpage=(max_w-scroll_menu.px_hline)/scroll_menu.px_hline;
1412 scroll_menu.hsize=Breite/scroll_menu.px_hline;
1413 scroll_menu.vpage= (desk.g_h-4*gr_ch-1)/scroll_menu.px_vline;
1414 if(Anzahl>scroll_menu.vpage){
1415 retval |= WD_VSLIDER;
1416 Anzahl=scroll_menu.vpage;
1419 scroll_menu.vpage=Anzahl;
1421 if((scroll_menu.hmax=scroll_menu.hsize-scroll_menu.hpage)<0)
1423 if((scroll_menu.vmax=scroll_menu.vsize-scroll_menu.vpage)<0)
1426 /* left/right/up 2 pixel border down 2gr_ch toolbar */
1427 z_ob[ROOT].ob_width=z_ob[LINESLIST].ob_width=Breite;
1428 z_ob[ROOT].ob_height=
1430 z_ob[LINESLIST].ob_height=scroll_menu.px_vline*Anzahl;
1431 z_ob[QLINE].ob_y+=gr_ch/2;
1432 z_ob[ROOT].ob_width+=4;
1433 z_ob[ROOT].ob_height+=2*gr_ch+2;
1438 /************************* mar_status_dirty *******************************/
1445 ccol=mar_hp_query();
1447 if(ccol<2) curs_col=WHITE; /* 50-100% : 0 */
1448 else if(ccol<3) curs_col=YELLOW; /* 33-50% : 6 */
1449 else if(ccol<5) curs_col=LYELLOW; /* 20-33% : 14*/
1450 else if(ccol<10) curs_col=RED; /* 10-20% : 2 */
1451 else curs_col=MAGENTA; /* <10% : 7*/
1454 /************************* mar_add_message *******************************/
1457 mar_add_message(str)
1460 int i, mesg_hist=mar_get_msg_history();
1461 char *tmp, *rest, buf[TBUFSZ];
1463 if(WIN_MESSAGE == WIN_ERR)
1466 if(!mar_message_pause){
1467 mar_message_pause=TRUE;
1472 if(msg_max>mesg_hist-2){
1473 msg_max=mesg_hist-2;
1475 if(msg_pos<0) msg_pos=0;
1476 tmp=message_line[0];
1477 for(i=0;i<mesg_hist-1;i++){
1478 message_line[i]=message_line[i+1];
1479 message_age[i]=message_age[i+1];
1481 message_line[mesg_hist-1]=tmp;
1483 strcpy(toplines,str);
1487 if((int)strlen(toplines)>=msg_width){
1489 tmp=toplines+msg_width;
1490 while(*tmp!=' ' && pos>=0){
1494 if(pos<=0) pos=msg_width; /* Mar -- Oops, what a word :-) */
1495 message_age[msg_max]=TRUE;
1496 strncpy(message_line[msg_max],toplines,pos);
1497 message_line[msg_max][pos]=0;
1498 rest=strcpy(buf,toplines+pos);
1500 message_age[msg_max]=TRUE;
1501 strncpy(message_line[msg_max],toplines,msg_width);
1505 Gem_nhwindow[WIN_MESSAGE].gw_dirty=TRUE;
1506 if(messages_pro_zug>=mesg_hist){ /* MAR -- Greater then should never happen */
1507 messages_pro_zug=mesg_hist;
1508 mar_display_nhwindow(WIN_MESSAGE);
1512 mar_add_message(rest);
1515 /************************* mar_add_status_str *******************************/
1518 mar_add_status_str(str,line)
1523 GRECT area={0,line*status_font.ch,status_font.cw,status_font.ch};
1524 for(i=0;(i<status_w-2) && str[i];i++)
1525 if(str[i]!=status_line[line][i]){
1526 if(last_diff==-1) area.g_x=i*status_font.cw;
1527 else area.g_w+=status_font.cw;
1529 status_line[line][i]=str[i];
1530 }else if(last_diff>=0){
1531 add_dirty_rect(dr_stat,&area);
1533 area.g_w=status_font.cw;
1535 for(;i<status_w-1;i++){
1536 if(status_line[line][i]){
1537 if(last_diff==-1) area.g_x=i*status_font.cw;
1538 else area.g_w+=status_font.cw;
1541 status_line[line][i]=0;
1544 add_dirty_rect(dr_stat,&area);
1547 /************************* mar_set_menu_title *******************************/
1550 mar_set_menu_title(str)
1553 test_free(Menu_title); /* just in case */
1554 Menu_title=mar_copy_of(str ? str : nullstr);
1557 /************************* mar_set_menu_type *******************************/
1560 mar_set_menu_type(how)
1566 /************************* Inventory Utils *******************************/
1569 set_all_on_page(start, page)
1572 Gem_menu_item *curr;
1574 if(start<0 || page<0)
1577 for(curr=invent_list; start--&&curr; curr=curr->Gmi_next);
1578 for(; page--&&curr; curr=curr->Gmi_next)
1579 if (curr->Gmi_identifier && !curr->Gmi_selected)
1580 curr->Gmi_selected = TRUE;
1584 unset_all_on_page(start, page)
1587 Gem_menu_item *curr;
1589 if(start<0 || page<0)
1592 for(curr=invent_list; start--&&curr; curr=curr->Gmi_next);
1593 for(; page--&&curr; curr=curr->Gmi_next)
1594 if (curr->Gmi_identifier && curr->Gmi_selected) {
1595 curr->Gmi_selected = FALSE;
1596 curr->Gmi_count = -1L;
1601 invert_all_on_page(start, page, acc)
1605 Gem_menu_item *curr;
1607 if(start<0 || page<0)
1610 for(curr=invent_list; start--&&curr; curr=curr->Gmi_next);
1611 for(; page--&&curr; curr=curr->Gmi_next)
1612 if (curr->Gmi_identifier && (acc == 0 || curr->Gmi_groupacc == acc)) {
1613 if (curr->Gmi_selected) {
1614 curr->Gmi_selected = FALSE;
1615 curr->Gmi_count = -1L;
1617 curr->Gmi_selected = TRUE;
1621 /************************* Inv_Handler and Inv_Init *******************************/
1623 int scroll_top_dialog(char ch){
1627 if((w=get_top_window()) && (dinf=(DIAINFO *)w->dialog) && dinf->di_tree==zz_oblist[LINES]){
1630 if(scroll_menu.vpos==scroll_menu.vmax){
1635 case MENU_NEXT_PAGE:
1636 scroll_window(w,PAGE_DOWN,NULL);
1638 case MENU_PREVIOUS_PAGE:
1639 scroll_window(w,PAGE_UP,NULL);
1641 case MENU_FIRST_PAGE:
1642 scroll_window(w,WIN_START,NULL);
1644 case MENU_LAST_PAGE:
1645 scroll_window(w,WIN_END,NULL);
1655 #define Text_Init KM_Init
1661 int ev=xev->ev_mwich;
1664 int *buf=xev->ev_mmgpbuf, y_wo, i;
1665 if(*buf==FONT_CHANGED){
1667 mar_set_fontbyid(NHW_TEXT,buf[4],buf[5]);
1673 char ch=(char)(xev->ev_mkreturn&0x00FF);
1675 if(!scroll_top_dialog(ch))
1678 send_return(); /* just closes the textwin */
1681 clipbrd_save(text_lines,Anz_text_lines,xev->ev_mmokstate&K_SHIFT,FALSE);
1684 ev &= ~MU_KEYBD; /* unknown key */
1691 #define Inv_Init KM_Init
1693 static long count=0;
1698 int ev=xev->ev_mwich;
1701 OBJECT *z_ob=zz_oblist[LINES];
1703 ob_pos(z_ob,LINESLIST,&area);
1705 int *buf=xev->ev_mmgpbuf, y_wo, i;
1707 if(*buf==FONT_CHANGED){
1709 mar_set_fontbyid(NHW_MENU,buf[4],buf[5]);
1713 if(*buf==OBJC_CHANGED && buf[3]==LINESLIST){
1714 ob_undostate(z_ob,LINESLIST,SELECTED);
1716 y_wo=(y_wo-area.g_y)/menu_font.ch+scroll_menu.vpos;
1717 for(it=invent_list,i=0;i<y_wo && it;it=it->Gmi_next,i++);
1718 if(it->Gmi_identifier){
1719 it->Gmi_selected=!it->Gmi_selected;
1720 it->Gmi_count= count==0L ? -1L : count;
1722 if(Inv_how!=PICK_ANY){
1723 /*my_close_dialog(Inv_dialog,TRUE);*/
1726 area.g_x=(area.g_x+23+2*menu_font.cw) & ~7;
1727 area.g_w=menu_font.cw;
1728 area.g_h=menu_font.ch;
1729 area.g_y+=(y_wo-scroll_menu.vpos)*menu_font.ch;
1730 ob_draw_chg(Inv_dialog,LINESLIST,&area,FAIL);
1731 } /* how != PICK_ANY */
1733 }else /* LINESLIST changed */
1734 ev &= ~MU_MESAG; /* unknown message not used */
1738 char ch=(char)(xev->ev_mkreturn&0x00FF);
1740 if(!scroll_top_dialog(ch)){
1742 case '0': /* special 0 is also groupaccelerator for balls */
1745 case '1': case '2': case '3': case '4':
1746 case '5': case '6': case '7': case '8': case '9':
1747 if(Inv_how==PICK_NONE)
1749 count = (count * 10L) + (long) (ch - '0');
1751 case '\033': /* cancel - from counting or loop */
1755 unset_all_on_page(0, (int)scroll_menu.vsize);
1756 my_close_dialog(Inv_dialog,TRUE);
1760 case '\0': /* finished (commit) */
1764 case MENU_SELECT_PAGE:
1765 if(Inv_how==PICK_NONE)
1767 if (Inv_how == PICK_ANY)
1768 set_all_on_page((int)scroll_menu.vpos, scroll_menu.vpage);
1770 case MENU_SELECT_ALL:
1771 if(Inv_how==PICK_NONE)
1773 if (Inv_how == PICK_ANY)
1774 set_all_on_page(0, (int)scroll_menu.vsize);
1776 case MENU_UNSELECT_PAGE:
1777 unset_all_on_page((int)scroll_menu.vpos, scroll_menu.vpage);
1779 case MENU_UNSELECT_ALL:
1780 unset_all_on_page(0, (int)scroll_menu.vsize);
1782 case MENU_INVERT_PAGE:
1783 if(Inv_how==PICK_NONE)
1785 if (Inv_how == PICK_ANY)
1786 invert_all_on_page((int)scroll_menu.vpos, scroll_menu.vpage, 0);
1788 case MENU_INVERT_ALL:
1789 if(Inv_how==PICK_NONE)
1791 if (Inv_how == PICK_ANY)
1792 invert_all_on_page(0, (int)scroll_menu.vsize, 0);
1795 if(Inv_how!=PICK_NONE){
1797 Gem_getlin("Search for:",buf);
1798 if(!*buf || buf[0]=='\033')
1800 for(it=invent_list;it;it=it->Gmi_next){
1801 if(it->Gmi_identifier && strstr(it->Gmi_str,buf)){
1802 it->Gmi_selected=TRUE;
1803 if(Inv_how!=PICK_ANY){
1804 my_close_dialog(Inv_dialog,FALSE);
1812 clipbrd_save(invent_list,Anz_inv_lines,xev->ev_mmokstate&K_SHIFT,TRUE);
1816 if(Inv_how==PICK_NONE)
1817 my_close_dialog(Inv_dialog,TRUE);
1819 for(it=invent_list;it;it=it->Gmi_next){
1820 if(it->Gmi_identifier && (it->Gmi_accelerator==ch || it->Gmi_groupacc==ch)){
1821 it->Gmi_selected=!it->Gmi_selected;
1822 it->Gmi_count= count==0L ? -1L : count;
1824 if(Inv_how!=PICK_ANY)
1825 my_close_dialog(Inv_dialog,TRUE);
1829 } /* end switch(ch) */
1830 if(Inv_how==PICK_ANY){
1831 area.g_x=(area.g_x+23+2*menu_font.cw) & ~7;
1832 area.g_w=menu_font.cw;
1833 ob_draw_chg(Inv_dialog,LINESLIST,&area,FAIL);
1835 } /* !scroll_Inv_dialog */
1838 if(Inv_how==PICK_ANY){
1839 ob_set_text(Inv_dialog->di_tree,QLINE,strCancel);
1840 for(it=invent_list;it;it=it->Gmi_next)
1841 if(it->Gmi_identifier && it->Gmi_selected){
1842 ob_set_text(Inv_dialog->di_tree,QLINE,strOk);
1845 ob_draw_chg(Inv_dialog,QLINE,NULL,FAIL);
1850 /************************* draw_window *******************************/
1853 mar_draw_window( first, win, area)
1858 OBJECT *obj=(OBJECT *)win->para;
1862 obj->ob_x=win->work.g_x;
1863 obj->ob_y=win->work.g_y;
1867 objc_draw(obj, ROOT, MAX_DEPTH, area->g_x, area->g_y, area->g_w, area->g_h);
1871 /************************* mar_display_nhwindow *******************************/
1873 void redraw_winwork(WIN *w,GRECT *area){
1874 area->g_x+=w->work.g_x;
1875 area->g_y+=w->work.g_y;
1876 redraw_window(w,area);
1878 void mar_menu_set_slider(WIN *p_win){
1880 SCROLL *sc=p_win->scroll;
1885 if(p_win->gadgets&HSLIDE){
1888 if(sc->hsize>0 && sc->hpage>0){
1892 window_slider(p_win,HOR_SLIDER,0,(int)hsize);
1894 if(p_win->gadgets&VSLIDE){
1897 if(sc->vsize>0 && sc->vpage>0){
1901 window_slider(p_win,VERT_SLIDER,0,(int)vsize);
1906 void recalc_msg_win(GRECT *area){
1908 z_ob=zz_oblist[MSGWIN];
1909 z_ob[MSGLINES].ob_spec.userblk=&ub_msg;
1910 z_ob[MSGLINES].ob_width=
1911 z_ob[ROOT].ob_width= (msg_width+3)*msg_font.cw;
1912 z_ob[MSGLINES].ob_width-=z_ob[UPMSG].ob_width;
1913 z_ob[ROOT].ob_height=
1914 z_ob[GRABMSGWIN].ob_height=
1915 z_ob[MSGLINES].ob_height=msg_vis*msg_font.ch;
1916 z_ob[DNMSG].ob_y=z_ob[GRABMSGWIN].ob_height-z_ob[DNMSG].ob_height;
1917 window_border(0,0,0,z_ob->ob_width,z_ob->ob_height, area);
1919 void recalc_status_win(GRECT *area){
1921 z_ob=zz_oblist[STATUSLINE];
1922 z_ob[ROOT].ob_type=G_USERDEF;
1923 z_ob[ROOT].ob_spec.userblk=&ub_status;
1924 z_ob[ROOT].ob_width=(status_w+2)*status_font.cw;
1925 z_ob[ROOT].ob_height=
1926 z_ob[GRABSTATUS].ob_height=2*status_font.ch;
1927 z_ob[GRABSTATUS].ob_width=2*status_font.cw-2;
1928 window_border(0,0,0,z_ob->ob_width,z_ob->ob_height,area);
1930 void calc_std_winplace(int which, GRECT *place){
1931 static int todo=TRUE;
1932 static GRECT me, ma, st;
1934 if(todo || which<0){
1938 /* First the messagewin */
1939 recalc_msg_win(&me);
1942 wind_calc(WC_BORDER,MAP_GADGETS,0,0,scroll_map.px_hline*(COLNO-1),scroll_map.px_vline*ROWNO,&foo,&foo,&foo,&map_h_off);
1943 map_h_off-=scroll_map.px_vline*ROWNO;
1944 window_border(MAP_GADGETS,0,0,scroll_map.px_hline*(COLNO-1),scroll_map.px_vline*ROWNO, &ma);
1946 /* Next the statuswin */
1947 recalc_status_win(&st);
1949 /* And last but not least a final test */
1950 ma.g_h=map_h_off+scroll_map.px_vline*ROWNO;
1951 while(me.g_h+ma.g_h+st.g_h>=desk.g_h)
1952 ma.g_h-=scroll_map.px_vline;
1953 /* stack the windows */
1954 ma.g_y=me.g_y=st.g_y=desk.g_y;
1961 me.g_y+=st.g_h+ma.g_h;
1969 st.g_y+=me.g_h+ma.g_h;
1972 if(which) todo=FALSE;
1990 mar_display_nhwindow(wind)
1995 int d_exit=W_ABANDON, i, breite, mar_di_mode, tmp_magx=magx;
1996 GRECT g_mapmax, area;
2000 if(wind == WIN_ERR) return;
2002 p_Gw=&Gem_nhwindow[wind];
2003 switch(p_Gw->gw_type){
2005 if(WIN_MESSAGE != WIN_ERR && Gem_nhwindow[WIN_MESSAGE].gw_window)
2006 mar_display_nhwindow(WIN_MESSAGE);
2007 z_ob=zz_oblist[LINES];
2008 scroll_menu.vsize=Anz_text_lines;
2011 if(!depack_img(planes<4 ? "RIP2.IMG" : "RIP.IMG", &rip_image)){
2012 mfdb(&Rip_bild, (int *)rip_image.addr, rip_image.img_w, rip_image.img_h, 1, rip_image.planes);
2013 transform_img(&Rip_bild);
2015 ub_lines.ub_code=draw_rip;
2017 ub_lines.ub_code=draw_lines;
2018 z_ob[LINESLIST].ob_spec.userblk=&ub_lines;
2020 v_set_text(text_font.id,text_font.size,BLACK,0,0,NULL);
2021 for(i=0;i<Anz_text_lines;i++){
2023 vqt_extent(x_handle,text_lines[i],eout);
2024 Max(&breite,eout[4]);
2026 scroll_menu.px_vline=text_font.ch;
2027 scroll_menu.px_hline=text_font.cw;
2028 mar_di_mode=mar_set_inv_win(Anz_text_lines, breite);
2029 tmp_button=ob_get_text(z_ob,QLINE,0);
2030 ob_set_text(z_ob,QLINE,strOk);
2031 ob_undoflag(z_ob,LINESLIST,TOUCHEXIT);
2032 Event_Handler(Text_Init,Text_Handler);
2033 if((dlg_info=open_dialog(z_ob,strText, NULL, NULL, mar_ob_mapcenter(z_ob), FALSE, mar_di_mode, FAIL, NULL, NULL))!=NULL){
2034 WIN *ptr_win=dlg_info->di_win;
2036 ptr_win->scroll=&scroll_menu;
2037 mar_menu_set_slider(ptr_win);
2038 WindowItems(ptr_win,SCROLL_KEYS,scroll_keys);
2039 if((d_exit=X_Form_Do(NULL))!=W_ABANDON){
2040 my_close_dialog(dlg_info,FALSE);
2041 if(d_exit!=W_CLOSED)
2042 ob_undostate(z_ob,d_exit&NO_CLICK,SELECTED);
2045 Event_Handler(NULL,NULL);
2046 ob_set_text(z_ob,QLINE,tmp_button);
2049 if(WIN_MESSAGE != WIN_ERR && Gem_nhwindow[WIN_MESSAGE].gw_window)
2050 mar_display_nhwindow(WIN_MESSAGE);
2051 z_ob=zz_oblist[LINES];
2052 scroll_menu.vsize=Anz_inv_lines;
2054 z_ob[LINESLIST].ob_spec.userblk=&ub_inventory;
2055 if((Menu_title)&&(wind!=WIN_INVEN)) /* because I sets no Menu_title */
2056 Max(&Inv_breite,gr_cw*strlen(Menu_title)+16);
2057 scroll_menu.px_vline=menu_font.ch;
2058 scroll_menu.px_hline=menu_font.cw;
2059 mar_di_mode=mar_set_inv_win(Anz_inv_lines, Inv_breite, NHW_MENU);
2060 tmp_button=ob_get_text(z_ob,QLINE,0);
2061 ob_set_text(z_ob,QLINE,Inv_how!=PICK_NONE ? strCancel : strOk );
2062 ob_doflag(z_ob,LINESLIST,TOUCHEXIT);
2063 Event_Handler(Inv_Init, Inv_Handler);
2064 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){
2065 WIN *ptr_win=Inv_dialog->di_win;
2067 ptr_win->scroll=&scroll_menu;
2068 mar_menu_set_slider(ptr_win);
2069 WindowItems(ptr_win,SCROLL_KEYS,scroll_keys);
2071 int y_wo,x_wo,ru_w=1,ru_h=1;
2074 d_exit=X_Form_Do(NULL);
2075 if((d_exit&NO_CLICK)==LINESLIST){
2076 ob_pos(z_ob,LINESLIST,&oarea);
2077 if(mouse(&x_wo,&y_wo) && Inv_how==PICK_ANY){
2078 graf_rt_rubberbox(FALSE,x_wo,y_wo,FAIL,FAIL,&oarea,&ru_w,&ru_h,NULL);
2079 invert_all_on_page((int)((y_wo-oarea.g_y)/menu_font.ch+scroll_menu.vpos),(ru_h+menu_font.ch-1)/menu_font.ch,0);
2081 for(it=invent_list,i=0;i<((y_wo-oarea.g_y)/menu_font.ch+scroll_menu.vpos) && it;it=it->Gmi_next,i++);
2082 if(it && it->Gmi_identifier){
2083 it->Gmi_selected=!it->Gmi_selected;
2084 it->Gmi_count= count==0L ? -1L : count;
2086 if(Inv_how!=PICK_ANY)
2090 oarea.g_x=(oarea.g_x+23+2*menu_font.cw) & ~7;
2091 oarea.g_y=y_wo-(y_wo-oarea.g_y)%menu_font.ch;
2092 oarea.g_w=menu_font.cw;
2093 oarea.g_h=((ru_h+menu_font.ch-1)/menu_font.ch)*menu_font.ch;
2094 ob_draw_chg(Inv_dialog,LINESLIST,&oarea,FAIL);
2096 if(Inv_how==PICK_ANY){
2097 ob_set_text(Inv_dialog->di_tree,QLINE,strCancel);
2098 for(it=invent_list;it;it=it->Gmi_next)
2099 if(it->Gmi_identifier && it->Gmi_selected){
2100 ob_set_text(Inv_dialog->di_tree,QLINE,strOk);
2103 ob_draw_chg(Inv_dialog,QLINE,NULL,FAIL);
2105 }while((d_exit&NO_CLICK)==LINESLIST);
2106 if(d_exit!=W_ABANDON){
2107 my_close_dialog(Inv_dialog,FALSE);
2108 if(d_exit!=W_CLOSED)
2109 ob_undostate(z_ob,d_exit&NO_CLICK,SELECTED);
2112 Event_Handler(NULL,NULL);
2113 ob_set_text(z_ob,QLINE,tmp_button);
2116 if(p_Gw->gw_window==NULL){
2117 calc_std_winplace(NHW_MAP,&p_Gw->gw_place);
2118 window_border(MAP_GADGETS,0,0,Tile_width*(COLNO-1),Tile_heigth*ROWNO, &g_mapmax);
2119 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);
2120 WindowItems(p_Gw->gw_window,SCROLL_KEYS-1,scroll_keys); /* ClrHome centers on u */
2124 area.g_x=p_Gw->gw_window->work.g_x+scroll_map.px_hline*(dirty_map_area.g_x-scroll_map.hpos);
2125 area.g_y=p_Gw->gw_window->work.g_y+scroll_map.px_vline*(dirty_map_area.g_y-scroll_map.vpos);
2126 area.g_w=(dirty_map_area.g_w-dirty_map_area.g_x+1)*scroll_map.px_hline;
2127 area.g_h=(dirty_map_area.g_h-dirty_map_area.g_y+1)*scroll_map.px_vline;
2129 redraw_window(p_Gw->gw_window,&area);
2131 dirty_map_area.g_x=COLNO-1;
2132 dirty_map_area.g_y=ROWNO;
2134 dirty_map_area.g_h=0;
2138 if(p_Gw->gw_window==NULL){
2139 calc_std_winplace(NHW_MESSAGE,&p_Gw->gw_place);
2140 z_ob=zz_oblist[MSGWIN];
2141 magx=0; /* MAR -- Fake E_GEM to remove Backdropper */
2142 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);
2144 window_size(p_Gw->gw_window,&p_Gw->gw_window->curr);
2145 p_Gw->gw_dirty=TRUE;
2149 ob_pos(zz_oblist[MSGWIN],MSGLINES,&area);
2150 while(messages_pro_zug>3){
2151 messages_pro_zug-=3;
2153 redraw_window(p_Gw->gw_window,&area);
2156 msg_pos+=messages_pro_zug;
2158 if(msg_pos>msg_max) msg_pos=msg_max;
2159 redraw_window(p_Gw->gw_window,&area);
2160 mar_message_pause=FALSE;
2164 if(p_Gw->gw_window==NULL){
2165 z_ob=zz_oblist[STATUSLINE];
2166 calc_std_winplace(NHW_STATUS,&p_Gw->gw_place);
2167 magx=0; /* MAR -- Fake E_GEM to remove Backdropper */
2168 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);
2170 /* Because 2*status_font.ch is smaller then e_gem expects the minimum win_height */
2171 p_Gw->gw_window->min_h=z_ob[ROOT].ob_height;
2172 window_size(p_Gw->gw_window,&p_Gw->gw_place);
2173 p_Gw->gw_dirty=TRUE;
2174 add_dirty_rect(dr_stat,&p_Gw->gw_place);
2176 while(get_dirty_rect(dr_stat,&area)){
2177 area.g_x=(area.g_x+p_Gw->gw_window->work.g_x+2*status_font.cw+6)&~7;
2178 area.g_y+=p_Gw->gw_window->work.g_y;
2179 redraw_window(p_Gw->gw_window,&area);
2184 redraw_window(p_Gw->gw_window,NULL);
2186 p_Gw->gw_dirty=FALSE;
2189 /************************* create_window *******************************/
2191 int mar_hol_win_type(window)
2194 return(Gem_nhwindow[window].gw_type);
2198 mar_create_window(type)
2202 static char name[]="Gem";
2204 struct gw *p_Gw=&Gem_nhwindow[0];
2206 for(newid = 0; p_Gw->gw_type && newid < MAXWIN; newid++, p_Gw++);
2210 message_line=(char **)m_alloc(msg_anz*sizeof(char *));
2211 message_age=(int *)m_alloc(msg_anz*sizeof(int));
2212 for(i=0;i<msg_anz;i++){
2213 message_age[i]=FALSE;
2214 message_line[i]=(char *)m_alloc((MSGLEN+1)*sizeof(char));
2217 dr_msg=new_dirty_rect(10);
2218 if (!dr_msg) panic("Memory allocation failure (dr_msg)");
2221 status_line=(char **)m_alloc(2*sizeof(char *));
2223 status_line[i]=(char *)m_alloc(status_w*sizeof(char));
2224 memset(status_line[i],0,status_w);
2226 dr_stat=new_dirty_rect(10);
2227 if (!dr_stat) panic("Memory allocation failure (dr_stat)");
2230 map_glyphs=(char **)m_alloc((long)ROWNO*sizeof(char *));
2231 for(i=0;i<ROWNO;i++){
2232 map_glyphs[i]=(char *)m_alloc((long)COLNO*sizeof(char));
2233 *map_glyphs[i]=map_glyphs[i][COLNO-1]=0;
2235 dr_map=new_dirty_rect(10);
2236 if (!dr_map) panic("Memory allocation failure (dr_map)");
2241 case NHW_TEXT: /* They are no more treated as dialog */
2244 p_Gw->gw_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);
2254 mar_change_menu_2_text(win)
2257 Gem_nhwindow[win].gw_type=NHW_TEXT;
2260 /************************* mar_clear_map *******************************/
2268 pla[0]=pla[1]=pla[4]=pla[5]=0;
2269 pla[2]=pla[6]=scroll_map.px_hline*(COLNO-1)-1;
2270 pla[3]=pla[7]=scroll_map.px_vline*ROWNO-1;
2271 for(y=0;y<ROWNO;y++) for(x=0;x<COLNO-1;x++)
2272 map_glyphs[y][x]=' ';
2273 vro_cpyfm(x_handle, ALL_BLACK,pla,&Tile_bilder,&Map_bild); /* MAR -- 17.Mar 2002 Hmm, what if FontCol_Bild is bigger? */
2274 if(WIN_MAP != WIN_ERR && Gem_nhwindow[WIN_MAP].gw_window)
2275 redraw_window(Gem_nhwindow[WIN_MAP].gw_window,NULL);
2278 /************************* destroy_window *******************************/
2281 mar_destroy_nhwindow(window)
2286 switch(Gem_nhwindow[window].gw_type){
2288 for(i=0;i<Anz_text_lines;i++)
2289 free(text_lines[i]);
2290 null_free(text_lines);
2295 Gem_start_menu(window); /* delete invent_list */
2296 test_free(Menu_title);
2298 case 0: /* No window available, probably an error message? */
2301 close_window( Gem_nhwindow[window].gw_window, 0 );
2304 Gem_nhwindow[window].gw_window=NULL;
2305 Gem_nhwindow[window].gw_type=0;
2306 Gem_nhwindow[window].gw_dirty=FALSE;
2308 if(window==WIN_MAP){
2309 for(i=0;i<ROWNO;i++){
2310 free(map_glyphs[i]);
2312 null_free(map_glyphs);
2315 if(window==WIN_STATUS){
2317 free(status_line[i]);
2318 null_free(status_line);
2321 if(window==WIN_MESSAGE){
2322 for(i=0;i<msg_anz;i++)
2323 free(message_line[i]);
2324 null_free(message_line);
2325 null_free(message_age);
2326 WIN_MESSAGE=WIN_ERR;
2328 if(window==WIN_INVEN)
2332 /************************* nh_poskey *******************************/
2334 void mar_set_margin(int m){
2336 Min(&m,min(ROWNO,COLNO)); /* MAR 16.Mar 2002 -- the larger the less sense */
2342 if(WIN_MAP!=WIN_ERR && Gem_nhwindow[WIN_MAP].gw_window){
2343 int breite=scroll_margin>0 ? scroll_margin : max(scroll_map.hpage/4,1),
2344 hoehe=scroll_margin>0 ? scroll_margin : max(scroll_map.vpage/4,1),
2346 adjust_needed=FALSE;
2347 if ((map_cursx < scroll_map.hpos + breite) || (map_cursx >= scroll_map.hpos + scroll_map.hpage - breite)){
2348 scroll_map.hpos=map_cursx - scroll_map.hpage/2;
2351 if ((map_cursy < scroll_map.vpos + hoehe) || (map_cursy >= scroll_map.vpos + scroll_map.vpage - hoehe)){
2352 scroll_map.vpos=map_cursy - scroll_map.vpage/2;
2356 scroll_window(Gem_nhwindow[WIN_MAP].gw_window,WIN_SCROLL,NULL);
2363 if(WIN_MESSAGE!=WIN_ERR){
2364 mar_message_pause=FALSE;
2365 mar_esc_pressed=FALSE;
2366 mar_display_nhwindow(WIN_MESSAGE);
2369 if(WIN_MAP!=WIN_ERR)
2372 if(WIN_STATUS!=WIN_ERR){
2373 mar_check_hilight_status();
2374 mar_display_nhwindow(WIN_STATUS);
2379 Main_Init(xev,availiable)
2389 return((MU_KEYBD|MU_BUTTON1|MU_BUTTON2|MU_MESAG)&availiable);
2393 * return a key, or 0, in which case a mouse button was pressed
2394 * mouse events should be returned as character postitions in the map window.
2398 mar_nh_poskey(x, y, mod)
2404 xev.ev_mflags=Main_Init(&xev,0xFFFF);
2405 ev=Event_Multi(&xev);
2410 char ch = xev.ev_mkreturn&0x00FF;
2411 char scan = (xev.ev_mkreturn & 0xff00) >> 8;
2412 int shift = xev.ev_mmokstate;
2413 const struct pad *kpad;
2415 /* Translate keypad keys */
2416 if (iskeypad(scan)) {
2417 kpad = mar_iflags_numpad()==1 ? numpad : keypad;
2418 if (shift & K_SHIFT)
2419 ch = kpad[scan - KEYPADLO].shift;
2420 else if (shift & K_CTRL){
2421 if(scan>=0x67 && scan<=0x6f && scan!=0x6b){
2422 send_key(kpad[scan - KEYPADLO].normal);
2425 ch = kpad[scan - KEYPADLO].cntrl;
2428 ch = kpad[scan - KEYPADLO].normal;
2432 else if(scan == SCANF1)
2434 else if(scan == SCANF2){
2435 mar_set_tile_mode(!mar_set_tile_mode(FAIL));
2436 retval=C('l'); /* trigger full-redraw */
2437 }else if(scan == SCANF3){
2438 draw_cursor=!draw_cursor;
2439 mar_curs(map_cursx,map_cursy);
2440 mar_display_nhwindow(WIN_MAP);
2441 }else if(scan == SCANF4){ /* Font-Selector */
2442 if(!CallFontSelector(0,FAIL,FAIL,FAIL,FAIL)){
2443 xalert(1,1,X_ICN_ALERT,NULL,SYS_MODAL,BUTTONS_RIGHT,TRUE,"Hello","Fontselector not available!",NULL);
2445 }else if(!ch && shift&K_CTRL && scan==-57){
2446 /* MAR -- nothing ignore Ctrl-Alt-Clr/Home == MagiC's restore screen */
2449 ch=(char)M(tolower(scan_2_ascii(xev.ev_mkreturn,shift)));
2456 if(ev&MU_BUTTON1 || ev&MU_BUTTON2){
2457 int ex=xev.ev_mmox, ey=xev.ev_mmoy;
2458 WIN *akt_win=window_find(ex,ey);
2460 if(WIN_MAP != WIN_ERR && akt_win==Gem_nhwindow[WIN_MAP].gw_window){
2461 *x=max(min((ex-akt_win->work.g_x)/scroll_map.px_hline+scroll_map.hpos,COLNO-1),0)+1;
2462 *y=max(min((ey-akt_win->work.g_y)/scroll_map.px_vline+scroll_map.vpos,ROWNO),0);
2463 *mod=xev.ev_mmobutton;
2465 }else if(WIN_STATUS != WIN_ERR && akt_win==Gem_nhwindow[WIN_STATUS].gw_window){
2467 }else if(WIN_MESSAGE != WIN_ERR && akt_win==Gem_nhwindow[WIN_MESSAGE].gw_window){
2468 message_handler(ex,ey);
2473 int *buf=xev.ev_mmgpbuf;
2475 OBJECT *z_ob=zz_oblist[MENU];
2479 menu_tnormal(z_ob,buf[3],TRUE); /* unselect menu header */
2480 str=ob_get_text(z_ob,buf[4],0);
2483 case ' ': /* just that command */
2486 case '\005': /* Alt command */
2490 case '^': /* Ctrl command */
2493 case 'f': /* Func Key */
2499 mar_set_tile_mode(!mar_set_tile_mode(FAIL));
2500 retval=C('l'); /* trigger full-redraw */
2503 draw_cursor=!draw_cursor;
2504 mar_curs(map_cursx,map_cursy);
2505 mar_display_nhwindow(WIN_MAP);
2514 break; /* MN_SELECTED */
2516 WindowHandler(W_ICONIFYALL,NULL,NULL);
2523 if(buf[3]==Gem_nhwindow[WIN_MESSAGE].gw_window->handle){
2524 mar_set_fontbyid(NHW_MESSAGE,buf[4],buf[5]);
2525 mar_display_nhwindow(WIN_MESSAGE);
2526 }else if(buf[3]==Gem_nhwindow[WIN_MAP].gw_window->handle){
2527 mar_set_fontbyid(NHW_MAP,buf[4],buf[5]);
2528 mar_display_nhwindow(WIN_MAP);
2529 }else if(buf[3]==Gem_nhwindow[WIN_STATUS].gw_window->handle){
2530 mar_set_fontbyid(NHW_STATUS,buf[4],buf[5]);
2531 mar_display_nhwindow(WIN_STATUS);
2542 retval=mar_nh_poskey(x,y,mod);
2548 Gem_nh_poskey(x, y, mod)
2552 return(mar_nh_poskey(x, y, mod));
2558 Event_Timer(50,0,FALSE); /* wait 50ms */
2562 Gem_doprev_message()
2566 if(WIN_MESSAGE != WIN_ERR)
2567 Gem_nhwindow[WIN_MESSAGE].gw_dirty=TRUE;
2568 mar_display_nhwindow(WIN_MESSAGE);
2573 /************************* print_glyph *******************************/
2575 int mar_set_rogue(int);
2578 mar_set_tile_mode(tiles)
2581 static int tile_mode=TRUE;
2583 WIN *z_w=WIN_MAP!=WIN_ERR ? Gem_nhwindow[WIN_MAP].gw_window : NULL;
2589 else if(tile_mode==tiles || (mar_set_rogue(FAIL) && tiles))
2595 scroll_map.px_hline= tiles ? Tile_width : map_font.cw;
2596 scroll_map.px_vline= tiles ? Tile_heigth : map_font.ch;
2597 window_border(MAP_GADGETS,0,0,scroll_map.px_hline*(COLNO-1),scroll_map.px_vline*ROWNO, &tmp);
2598 z_w->max.g_w=tmp.g_w;
2599 z_w->max.g_h=tmp.g_h;
2605 window_reinit(z_w,md,md,NULL,FALSE,FALSE);
2614 static int rogue=FALSE, prev_mode=TRUE;
2616 if(what<0) return(rogue);
2620 prev_mode=mar_set_tile_mode(FAIL);
2621 mar_set_tile_mode(FALSE);
2623 mar_set_tile_mode(prev_mode);
2629 mar_add_pet_sign(window,x,y)
2633 if(window != WIN_ERR && window==WIN_MAP){
2634 static int pla[8]={0,0,7,7,0,0,0,0}, colindex[2]={RED,WHITE};
2636 pla[4]=pla[6]=scroll_map.px_hline*x;
2637 pla[5]=pla[7]=scroll_map.px_vline*y;
2640 vrt_cpyfm(x_handle,MD_TRANS,pla,&Pet_Mark,&Map_bild,colindex);
2645 mar_print_glyph(window, x, y, gl)
2649 if(window != WIN_ERR && window==WIN_MAP){
2652 pla[2]=pla[0]=(gl%Tiles_per_line)*Tile_width;
2653 pla[3]=pla[1]=(gl/Tiles_per_line)*Tile_heigth;
2654 pla[2]+=Tile_width-1;
2655 pla[3]+=Tile_heigth-1;
2656 pla[6]=pla[4]=Tile_width*x; /* x_wert to */
2657 pla[7]=pla[5]=Tile_heigth*y; /* y_wert to */
2658 pla[6]+=Tile_width-1;
2659 pla[7]+=Tile_heigth-1;
2661 vro_cpyfm(x_handle, gl!=-1 ? S_ONLY : ALL_BLACK, pla, &Tile_bilder, &Map_bild);
2666 mar_print_char(window, x, y, ch, col)
2672 if(window != WIN_ERR && window==WIN_MAP){
2673 static int gem_color[16]={ 9, 2,11,10, 4, 7, 8, 15,0,14, 3, 6, 5, 13,15, 0};
2674 int pla[8], colindex[2];
2676 map_glyphs[y][x]=ch;
2680 pla[2]=map_font.cw-1;
2681 pla[3]=map_font.ch-1;
2682 pla[6]=pla[4]=map_font.cw*x;
2683 pla[7]=pla[5]=map_font.ch*y;
2684 pla[6]+=map_font.cw-1;
2685 pla[7]+=map_font.ch-1;
2686 colindex[0]=gem_color[col];
2688 vrt_cpyfm(x_handle,MD_REPLACE,pla,&Black_bild,&FontCol_Bild,colindex);
2692 /************************* getlin *******************************/
2695 Gem_getlin(ques, input)
2699 OBJECT *z_ob=zz_oblist[LINEGET];
2703 if(WIN_MESSAGE != WIN_ERR && Gem_nhwindow[WIN_MESSAGE].gw_window)
2704 mar_display_nhwindow(WIN_MESSAGE);
2706 z_ob[LGPROMPT].ob_type=G_USERDEF;
2707 z_ob[LGPROMPT].ob_spec.userblk=&ub_prompt;
2708 z_ob[LGPROMPT].ob_height=2*gr_ch;
2710 length=z_ob[LGPROMPT].ob_width/gr_cw;
2711 if(strlen(ques)>length){
2713 while(*tmp!=' ' && tmp>=ques){
2716 if(tmp<=ques) tmp=ques+length; /* Mar -- Oops, what a word :-) */
2724 ub_prompt.ub_parm=(long)pr;
2726 ob_clear_edit(z_ob);
2727 d_exit=xdialog(z_ob, nullstr, NULL, NULL, mar_ob_mapcenter(z_ob), FALSE, DIALOG_MODE);
2728 Event_Timer(0,0,TRUE);
2730 if(d_exit==W_CLOSED || d_exit==W_ABANDON || (d_exit&NO_CLICK)==QLG){
2734 strncpy(input,ob_get_text(z_ob,LGREPLY, 0),length);
2737 /************************* ask_direction *******************************/
2739 #define Dia_Init K_Init
2745 int ev=xev->ev_mwich;
2746 char ch=(char)(xev->ev_mkreturn&0x00FF);
2754 send_key((int)(mar_iflags_numpad() ? '5' : '.'));
2757 send_key('5'); /* MAR -- '.' is a button if numpad isn't set */
2759 case '\033': /*ESC*/
2760 if((w=get_top_window()) && (dinf=(DIAINFO *)w->dialog) && dinf->di_tree==zz_oblist[DIRECTION]){
2761 my_close_dialog(dinf,FALSE);
2766 ev &= ~MU_KEYBD; /* let the dialog handle it */
2777 OBJECT *z_ob=zz_oblist[DIRECTION];
2779 Event_Handler(Dia_Init,Dia_Handler);
2781 d_exit=xdialog(z_ob, nullstr, NULL, NULL, mar_ob_mapcenter(z_ob), FALSE, DIALOG_MODE);
2782 Event_Timer(0,0,TRUE);
2783 Event_Handler(NULL,NULL);
2785 if(d_exit==W_CLOSED || d_exit==W_ABANDON)
2787 if((d_exit&NO_CLICK)==DIRDOWN)
2789 if((d_exit&NO_CLICK)==DIRUP)
2791 if((d_exit&NO_CLICK)==(DIR1+8)) /* 5 or . */
2793 return(*ob_get_text(z_ob,d_exit&NO_CLICK,0));
2796 /************************* yn_function *******************************/
2799 #define any_init M_Init
2805 int ev=xev->ev_mwich;
2808 int *buf=xev->ev_mmgpbuf;
2810 if(*buf==OBJC_EDITED)
2811 my_close_dialog(*(DIAINFO **)&buf[4], FALSE);
2819 send_yn_esc(char ch)
2821 static char esc_char=0;
2825 send_key((int)esc_char);
2834 #define single_init K_Init
2840 int ev=xev->ev_mwich;
2843 char ch=(char)xev->ev_mkreturn&0x00FF;
2852 if((w=get_top_window()) && (dinf=(DIAINFO *)w->dialog) && dinf->di_tree==zz_oblist[YNCHOICE]){
2853 if(!send_yn_esc(FAIL))
2854 my_close_dialog(dinf,FALSE);
2866 Gem_yn_function(query,resp, def)
2867 const char *query,*resp;
2870 OBJECT *z_ob=zz_oblist[YNCHOICE];
2876 if(WIN_MESSAGE != WIN_ERR && Gem_nhwindow[WIN_MESSAGE].gw_window)
2877 mar_display_nhwindow(WIN_MESSAGE);
2879 /* if query for direction the special dialog */
2880 if(strstr(query,"irect"))
2881 return(mar_ask_direction());
2883 len=min(strlen(query),(max_w-8*gr_cw)/gr_cw);
2884 z_ob[ROOT].ob_width=(len+8)*gr_cw;
2885 z_ob[YNPROMPT].ob_width=gr_cw*len+8;
2886 tmp=ob_get_text(z_ob,YNPROMPT,0);
2887 ob_set_text(z_ob,YNPROMPT,mar_copy_of(query));
2889 if(resp){ /* single inputs */
2890 ob_hide(z_ob,SOMECHARS,FALSE);
2891 ob_hide(z_ob,ANYCHAR,TRUE);
2893 if(strchr(resp,'q')) send_yn_esc('q');
2894 else if(strchr(resp,'n')) send_yn_esc('n');
2895 else send_yn_esc(def); /* strictly def should be returned, but in trad. I it's 0 */
2897 if(strchr(resp,'#')){ /* count possible */
2898 ob_hide(z_ob,YNOK,FALSE);
2899 ob_hide(z_ob,COUNT,FALSE);
2900 }else{ /* no count */
2901 ob_hide(z_ob,YNOK,TRUE);
2902 ob_hide(z_ob,COUNT,TRUE);
2905 if((anzahl=(long)strchr(resp,'\033'))){
2908 anzahl=strlen(resp);
2910 for(i=0,ptr=resp;i<2*anzahl;i+=2,ptr++){
2911 ob_hide(z_ob,YN1+i,FALSE);
2912 mar_change_button_char(z_ob,YN1+i,*ptr);
2913 ob_undoflag(z_ob,YN1+i,DEFAULT);
2915 ob_doflag(z_ob,YN1+i,DEFAULT);
2918 z_ob[SOMECHARS].ob_width=z_ob[YN1+i].ob_x+8;
2919 z_ob[SOMECHARS].ob_height=z_ob[YN1+i].ob_y+gr_ch+gr_ch/2;
2920 Max((int *)&z_ob[ROOT].ob_width,z_ob[SOMECHARS].ob_width+4*gr_cw);
2921 z_ob[ROOT].ob_height=z_ob[SOMECHARS].ob_height+4*gr_ch;
2922 if(strchr(resp,'#'))
2923 z_ob[ROOT].ob_height=z_ob[YNOK].ob_y+2*gr_ch;
2925 for(i+=YN1;i<(YNN+1);i+=2){
2926 ob_hide(z_ob,i,TRUE);
2928 Event_Handler(single_init,single_handler);
2929 }else{ /* any input */
2930 ob_hide(z_ob,SOMECHARS,TRUE);
2931 ob_hide(z_ob,ANYCHAR,FALSE);
2932 ob_hide(z_ob,YNOK,TRUE);
2933 ob_hide(z_ob,COUNT,TRUE);
2934 z_ob[ANYCHAR].ob_height=2*gr_ch;
2935 z_ob[CHOSENCH].ob_y=
2936 z_ob[CHOSENCH+1].ob_y=gr_ch/2;
2937 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*gr_cw;
2938 z_ob[ROOT].ob_height=z_ob[ANYCHAR].ob_height+z_ob[ANYCHAR].ob_y+gr_ch/2;
2939 *ob_get_text(z_ob,CHOSENCH,0)='?';
2940 Event_Handler(any_init,any_handler);
2943 d_exit=xdialog(z_ob, nullstr, NULL, NULL, mar_ob_mapcenter(z_ob), FALSE, DIALOG_MODE);
2944 Event_Timer(0,0,TRUE);
2945 Event_Handler(NULL,NULL);
2946 /* display of count is missing (through the core too) */
2948 free(ob_get_text(z_ob,YNPROMPT,0));
2949 ob_set_text(z_ob,YNPROMPT,tmp);
2951 if(resp && (d_exit==W_CLOSED || d_exit==W_ABANDON))
2953 if((d_exit&NO_CLICK)==YNOK){
2954 yn_number=atol(ob_get_text(z_ob,COUNT,0));
2958 return(*ob_get_text(z_ob,CHOSENCH,0));
2959 return(*ob_get_text(z_ob,d_exit&NO_CLICK,0));
2963 * Allocate a copy of the given string. If null, return a string of
2966 * This is an exact duplicate of copy_of() in X11/winmenu.c.
2972 if (!s) s = nullstr;
2973 return strcpy((char *) m_alloc((unsigned) (strlen(s) + 1)), s);
2976 const char *strRP="raw_print", *strRPB="raw_print_bold";
2982 xalert(1,FAIL,X_ICN_INFO,NULL,APPL_MODAL,BUTTONS_CENTERED,TRUE,strRP,str,NULL);
2986 mar_raw_print_bold(str)
2991 sprintf(buf,"!%s",str);
2992 xalert(1,FAIL,X_ICN_INFO,NULL,APPL_MODAL,BUTTONS_CENTERED,TRUE,strRPB,buf,NULL);