/* NetHack 3.6 wingem1.c $NHDT-Date: 1433806613 2015/06/08 23:36:53 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ */ /* Copyright (c) Christian Bressler 1999 */ /* NetHack may be freely redistributed. See license for details. */ #define __TCC_COMPAT__ #include #include #include #include #include #include #include #include "gem_rsc.h" #include "load_img.h" #include "gr_rect.h" #define genericptr_t void * typedef signed char schar; #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.6.0", 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 MSGLEN 100 #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 mar_get_msg_visible(void); /* from wingem.c */ extern void mar_get_font(int, char **, int *); /* from wingem.c */ extern int vdi2dev4[]; /* from load_img.c */ void recalc_msg_win(GRECT *); void recalc_status_win(GRECT *); void calc_std_winplace(int, GRECT *); int (*v_mtext)(int, int, int, char *); 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, FontCol_Bild; static int Tile_width = 16, Tile_heigth = 16, Tiles_per_line = 20; char *Tilefile = NULL; /* 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]; typedef struct { int id; int size; int cw, ch; int prop; } NHGEM_FONT; /*struct gemmapdata {*/ GRECT dirty_map_area = { COLNO - 1, ROWNO, 0, 0 }; int map_cursx = 0, map_cursy = 0, curs_col = WHITE; int draw_cursor = TRUE, scroll_margin = -1; NHGEM_FONT map_font; SCROLL scroll_map; char **map_glyphs = NULL; dirty_rect *dr_map; /*};*/ /*struct gemstatusdata{*/ char **status_line; int Anz_status_lines, status_w, status_align = FALSE; NHGEM_FONT status_font; dirty_rect *dr_stat; /*};*/ /*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, msg_vis = 3, msg_align = TRUE; NHGEM_FONT msg_font; dirty_rect *dr_msg; /*};*/ /*struct geminvdata {*/ SCROLL scroll_menu; Gem_menu_item *invent_list; int Anz_inv_lines = 0, Inv_breite = 16; NHGEM_FONT menu_font; int Inv_how; /*};*/ /*struct gemtextdata{*/ char **text_lines; int Anz_text_lines = 0, text_width; NHGEM_FONT text_font; int use_rip = FALSE; extern char **rip_line; /*};*/ 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 clipbrd_save(void *data, int cnt, boolean append, boolean is_inv) { char path[MAX_PATH], *text, *crlf = "\r\n"; long handle; int i; if (data && cnt > 0 && scrp_path(path, "scrap.txt") && (handle = append ? Fopen(path, 1) : Fcreate(path, 0)) > 0) { if (append) Fseek(0L, (int) handle, SEEK_END); if (is_inv) { Gem_menu_item *it = (Gem_menu_item *) data; for (; it; it = it->Gmi_next) { text = it->Gmi_str; Fwrite((int) handle, strlen(text), text); Fwrite((int) handle, 2L, crlf); } } else { for (i = 0; i < cnt; i++) { text = ((char **) data)[i] + 1; Fwrite((int) handle, strlen(text), text); Fwrite((int) handle, 2L, crlf); } } Fclose((int) handle); scrp_changed(SCF_TEXT, 0x2e545854l); /* .TXT */ } } 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 > msg_vis - 1) { msg_pos--; Gem_nhwindow[WIN_MESSAGE].gw_dirty = TRUE; mar_display_nhwindow(WIN_MESSAGE); } Event_Timer(50, 0, TRUE); break; case DNMSG: if (msg_pos < msg_max) { msg_pos++; Gem_nhwindow[WIN_MESSAGE].gw_dirty = TRUE; mar_display_nhwindow(WIN_MESSAGE); } Event_Timer(50, 0, TRUE); break; case GRABMSGWIN: default: move_win(Gem_nhwindow[WIN_MESSAGE].gw_window); break; case -1: break; } } int mar_ob_mapcenter(OBJECT *p_obj) { WIN *p_w = WIN_MAP != WIN_ERR ? Gem_nhwindow[WIN_MAP].gw_window : NULL; if (p_obj && p_w) { p_obj->ob_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; } void mar_set_tilefile(name) char *name; { Tilefile = name; } void mar_set_tilex(value) int value; { Min(&value, 32); Max(&value, 1); Tile_width = value; } void mar_set_tiley(value) int value; { Min(&value, 32); Max(&value, 1); Tile_heigth = value; } /****************************** userdef_draw * *************************************/ void rearrange_windows(void); void mar_set_status_align(int sa) { if (status_align != sa) { status_align = sa; rearrange_windows(); } } void mar_set_msg_align(int ma) { if (msg_align != ma) { msg_align = ma; rearrange_windows(); } } void mar_set_msg_visible(int mv) { if (mv != msg_vis) { Max(&mv, 1); Min(&mv, min(msg_anz, 20)); Min(&mv, desk.g_h / msg_font.ch / 2); msg_vis = mv; rearrange_windows(); } } /* size<0 cellheight; size>0 points */ void mar_set_fontbyid(int type, int id, int size) { int chardim[4]; if (id <= 0) id = ibm_font_id; if ((size > -3 && size < 3) || size < -20 || size > 20) size = -ibm_font; /* MAR -- 17.Mar 2002 For now allow FNT_PROP only with NHW_TEXT */ if (type != NHW_TEXT && (FontInfo(id)->type & (FNT_PROP | FNT_ASCII))) id = ibm_font_id; switch (type) { case NHW_MESSAGE: if (msg_font.size == -size && msg_font.id == id) break; msg_font.size = -size; msg_font.id = id; msg_font.prop = FontInfo(id)->type & (FNT_PROP | FNT_ASCII); v_set_text(msg_font.id, msg_font.size, BLACK, 0, 0, chardim); msg_font.ch = chardim[3] ? chardim[3] : 1; msg_font.cw = chardim[2] ? chardim[2] : 1; msg_width = min(max_w / msg_font.cw - 3, MSGLEN); rearrange_windows(); break; case NHW_MAP: if (map_font.size != -size || map_font.id != id) { MFDB mtmp; map_font.size = -size; map_font.id = id; map_font.prop = FontInfo(id)->type & (FNT_PROP | FNT_ASCII); v_set_text(map_font.id, map_font.size, BLACK, 0, 0, chardim); map_font.ch = chardim[3] ? chardim[3] : 1; map_font.cw = chardim[2] ? chardim[2] : 1; mfdb(&mtmp, NULL, (COLNO - 1) * map_font.cw, ROWNO * map_font.ch, 0, planes); if (mfdb_size(&mtmp) > mfdb_size(&FontCol_Bild) && mfdb_size(&mtmp) > mfdb_size(&Map_bild)) { FontCol_Bild.fd_addr = Map_bild.fd_addr = (int *) realloc(Map_bild.fd_addr, mfdb_size(&mtmp)); if (!Map_bild.fd_addr) /* FIXME -- Not really neccessary since the former space is still valid */ panic("Not enough Space for the map."); } mfdb(&FontCol_Bild, FontCol_Bild.fd_addr, (COLNO - 1) * map_font.cw, ROWNO * map_font.ch, 0, planes); rearrange_windows(); } break; case NHW_STATUS: if (status_font.size == -size && status_font.id == id) break; status_font.size = -size; status_font.id = id; status_font.prop = FontInfo(id)->type & (FNT_PROP | FNT_ASCII); v_set_text(status_font.id, status_font.size, BLACK, 0, 0, chardim); status_font.ch = chardim[3] ? chardim[3] : 1; status_font.cw = chardim[2] ? chardim[2] : 1; rearrange_windows(); break; case NHW_MENU: if (menu_font.size == -size && menu_font.id == id) break; menu_font.size = -size; menu_font.id = id; menu_font.prop = FontInfo(id)->type & (FNT_PROP | FNT_ASCII); v_set_text(menu_font.id, menu_font.size, BLACK, 0, 0, chardim); menu_font.ch = chardim[3] ? chardim[3] : 1; menu_font.cw = chardim[2] ? chardim[2] : 1; break; case NHW_TEXT: if (text_font.size == -size && text_font.id == id) break; text_font.size = -size; text_font.id = id; text_font.prop = FontInfo(id)->type & (FNT_PROP | FNT_ASCII); v_set_text(text_font.id, text_font.size, BLACK, 0, 0, chardim); text_font.ch = chardim[3] ? chardim[3] : 1; text_font.cw = chardim[2] ? chardim[2] : 1; break; default: break; } } void mar_set_font(int type, const char *font_name, int size) { int id = 0; /* MAR -- 17.Mar 2002 usual Gem behavior, use the Font-ID */ if (font_name && *font_name) { id = atoi(font_name); if (id <= 0) { int i, tid; char name[32]; for (i = fonts_loaded; --i >= 0;) { tid = vqt_name(x_handle, i, name); if (!stricmp(name, font_name)) { id = tid; break; } } } } mar_set_fontbyid(type, id, size); } void rearrange_windows(void) { GRECT area; int todo = TRUE; if (WIN_MAP != WIN_ERR && Gem_nhwindow[WIN_MAP].gw_window) { scroll_map.px_hline = mar_set_tile_mode(FAIL) ? Tile_width : map_font.cw; scroll_map.px_vline = mar_set_tile_mode(FAIL) ? Tile_heigth : map_font.ch; if (todo) { calc_std_winplace(FAIL, &area); todo = FALSE; } calc_std_winplace(NHW_MAP, &area); Gem_nhwindow[WIN_MAP].gw_window->max.g_w = area.g_w; Gem_nhwindow[WIN_MAP].gw_window->max.g_h = area.g_h; Gem_nhwindow[WIN_MAP].gw_window->max.g_w = area.g_w; window_reinit(Gem_nhwindow[WIN_MAP].gw_window, md, md, NULL, FALSE, FALSE); { int buf[8]; buf[3] = K_CTRL; buf[4] = C('L'); AvSendMsg(ap_id, AV_SENDKEY, buf); } } if (WIN_MESSAGE != WIN_ERR && Gem_nhwindow[WIN_MESSAGE].gw_window) { if (todo) { calc_std_winplace(FAIL, &area); todo = FALSE; } calc_std_winplace(NHW_MESSAGE, &area); Gem_nhwindow[WIN_MESSAGE].gw_window->min_h = area.g_h; window_size(Gem_nhwindow[WIN_MESSAGE].gw_window, &area); redraw_window(Gem_nhwindow[WIN_MESSAGE].gw_window, NULL); } if (WIN_STATUS != WIN_ERR && Gem_nhwindow[WIN_STATUS].gw_window) { if (todo) { calc_std_winplace(FAIL, &area); todo = FALSE; } calc_std_winplace(NHW_STATUS, &area); Gem_nhwindow[WIN_STATUS].gw_window->min_h = area.g_h; window_size(Gem_nhwindow[WIN_STATUS].gw_window, &area); redraw_window(Gem_nhwindow[WIN_STATUS].gw_window, NULL); } } 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; GRECT back = *area; first = first; if (!mar_set_tile_mode(FAIL)) { int start = (area->g_x - win->work.g_x) / map_font.cw + scroll_map.hpos; int stop = (area->g_x + area->g_w + map_font.cw - 1 - win->work.g_x) / map_font.cw + scroll_map.hpos; int starty = (area->g_y - win->work.g_y) / map_font.ch + scroll_map.vpos; int stopy = min((area->g_y + area->g_h + map_font.ch - 1 - win->work.g_y) / map_font.ch + scroll_map.vpos, ROWNO); char tmp; v_set_text(map_font.id, map_font.size, WHITE, 0, 0, NULL); v_set_mode(MD_TRANS); x = win->work.g_x - scroll_map.px_hpos + start * map_font.cw; y = win->work.g_y - scroll_map.px_vpos + starty * map_font.ch; pla[2] = pla[0] = scroll_map.px_hpos + area->g_x - win->work.g_x; pla[3] = pla[1] = starty * map_font.ch; pla[2] += w; pla[3] += map_font.ch - 1; pla[6] = pla[4] = area->g_x; /* x_wert to */ pla[7] = pla[5] = y; /* y_wert to */ pla[6] += w; pla[7] += map_font.ch - 1; back.g_h = map_font.ch; 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) { back.g_y = y; my_color_area(&back, BLACK); tmp = map_glyphs[i][stop]; map_glyphs[i][stop] = 0; (*v_mtext)(x_handle, x, y, &map_glyphs[i][start]); map_glyphs[i][stop] = tmp; vro_cpyfm(x_handle, S_OR_D, pla, &FontCol_Bild, screen); } } else { v_set_mode(MD_REPLACE); pla[2] = pla[0] = scroll_map.px_hpos + area->g_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, S_ONLY, 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] += scroll_map.px_hline - 1; pla[3] += scroll_map.px_vline - 1; 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); v_set_mode((text_font.cw & 7) == 0 && text_font.prop == 0 ? MD_REPLACE : MD_TRANS); /* void v_set_text(int font,int height,int color,int effect,int * rotate,int out[4]) */ v_set_text(text_font.id, text_font.size, BLACK, 0, 0, NULL); start_line /= text_font.ch; y += start_line * text_font.ch; x -= (int) scroll_menu.px_hpos; ptr = &text_lines[start_line += scroll_menu.vpos]; start_line = min((area.g_y - y + area.g_h + text_font.ch - 1) / text_font.ch, Anz_text_lines - start_line); area.g_h = text_font.ch; Vsync(); /* x=(x+7) & ~7;*/ for (; --start_line >= 0; y += text_font.ch) { area.g_y = y; my_clear_area(&area); if (**ptr - 1) { v_set_text(FAIL, 0, BLUE, 0x01, 0, NULL); (*v_mtext)(x_handle, x, y, (*ptr++) + 1); v_set_text(FAIL, 0, BLACK, 0x00, 0, NULL); } else (*v_mtext)(x_handle, x, y, (*ptr++) + 1); } } return (0); } static int draw_rip(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], pla[8], i; 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(text_font.id, text_font.size, BLACK, 0, 0, chardim); start_line /= text_font.ch; y += start_line * text_font.ch; x -= scroll_menu.px_hpos; ptr = &text_lines[start_line += scroll_menu.vpos]; start_line = min((area.g_y - y + area.g_h + text_font.ch - 1) / text_font.ch, Anz_text_lines - start_line); area.g_h = text_font.ch; Vsync(); x = (x + 7) & ~7; for (; --start_line >= 0; y += text_font.ch) { area.g_y = y; my_clear_area(&area); if (**ptr - 1) { v_set_text(FAIL, 0, BLUE, 0x01, 0, NULL); (*v_mtext)(x_handle, x, y, (*ptr++) + 1); v_set_text(FAIL, 0, BLACK, 0x00, 0, NULL); } else (*v_mtext)(x_handle, x, y, (*ptr++) + 1); } pla[0] = pla[1] = 0; pla[2] = min(pb->pb_w - 1, Rip_bild.fd_w - 1); pla[3] = min(pb->pb_h - 1, Rip_bild.fd_h - 1); pla[6] = pla[4] = pb->pb_x + (pb->pb_w - Rip_bild.fd_w) / 2; /* x_wert to */ pla[7] = pla[5] = pb->pb_y; /* y_wert to */ pla[6] += pla[2]; pla[7] += pla[3]; vro_cpyfm(x_handle, S_ONLY, pla, &Rip_bild, screen); v_set_mode(MD_TRANS); vst_alignment(x_handle, 1, 5, &i, &i); pla[5] += 64; for (i = 0; i < 7; i++, pla[5] += chardim[3]) { v_set_text(text_font.id, (i == 0 || i == 6) ? text_font.size : 12, WHITE, 1, 0, chardim); (*v_mtext)(x_handle, pla[4] + 157, pla[5], rip_line[i]); v_set_text(text_font.id, (i == 0 || i == 6) ? text_font.size : 12, BLACK, 0, 0, chardim); (*v_mtext)(x_handle, pla[4] + 157, pla[5], rip_line[i]); } vst_alignment(x_handle, 0, 5, &i, &i); } 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 + (msg_vis - 1) * msg_font.ch, foo, i; char **ptr = &message_line[msg_pos], tmp; int startx, stopx, starty, stopy; 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(msg_font.id, msg_font.size, FAIL, FAIL, 0, NULL); vst_alignment(x_handle, 0, 5, &foo, &foo); stopy = min(msg_pos, msg_vis); /* Vsync();*/ startx = (area.g_x - x) / msg_font.cw - 1; /* MAR 06.02.2001 -- because italic covers the next char */ Max(&startx, 0); stopx = (area.g_x + area.g_w + msg_font.cw - x - 1) / msg_font.cw; x += startx * msg_font.cw; for (i = 0; i < stopy; i++, y -= msg_font.ch, ptr--) { if (message_age[msg_pos - i]) v_set_text(FAIL, 0, BLACK, 0, 0, NULL); else v_set_text(FAIL, 0, LBLACK, 4, 0, NULL); tmp = (*ptr)[stopx]; (*ptr)[stopx] = 0; (*v_mtext)(x_handle, x, y, &(*ptr)[startx]); (*ptr)[stopx] = tmp; } } return (0); } static int draw_status(PARMBLK *pb) { GRECT area = *(GRECT *) &pb->pb_x; area.g_x += 2 * status_font.cw - 2; area.g_w -= 2 * status_font.cw - 2; if (rc_intersect((GRECT *) &pb->pb_xc, &area)) { int x = pb->pb_x, y = pb->pb_y, startx, stopx, starty, stopy, i; char tmp; /* void v_set_text(int font,int height,int color,int effect,int * rotate,int out[4]) */ v_set_mode(MD_REPLACE); v_set_text(status_font.id, status_font.size, BLACK, 0, 0, NULL); x = (x + 2 * status_font.cw + 6) & ~7; startx = (area.g_x - x) / status_font.cw; starty = (area.g_y - y) / status_font.ch; stopx = (area.g_x + area.g_w + status_font.ch - 1 - x) / status_font.cw; stopy = (area.g_y + area.g_h + status_font.ch - 1 - y) / status_font.ch; Max(&startx, 0); /* MAR -- Hmm, area.g_x could end up 1 below x */ Max(&stopx, 0); x += startx * status_font.cw; y += starty * status_font.ch; /* Vsync();*/ area.g_h = status_font.ch; for (i = starty; i < min(2, stopy); i++, area.g_y += status_font.ch, y += status_font.ch) { my_clear_area(&area); tmp = status_line[i][stopx]; status_line[i][stopx] = 0; (*v_mtext)(x_handle, x, y, &status_line[i][startx]); status_line[i][stopx] = tmp; } } 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(menu_font.id, menu_font.size, BLACK, 0, 0, NULL); start_line /= menu_font.ch; y += start_line * menu_font.ch; 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 + menu_font.ch - 1) / menu_font.ch, Anz_inv_lines - start_line); Vsync(); area.g_h = menu_font.ch; for (; (--i >= 0) && it; it = it->Gmi_next, y += menu_font.ch) { 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(menu_font.ch, Tile_heigth) - 1; pla[0] = pla[2] = (gl % Tiles_per_line) * Tile_width; /* x_wert from */ pla[1] = pla[3] = (gl / Tiles_per_line) * Tile_heigth; /* y_wert from */ pla[4] = pla[6] = x; /* x_wert to */ pla[5] = pla[7] = y; /* y_wert to */ pla[2] += Tile_width - 1; pla[3] += h; pla[6] += Tile_heigth - 1; 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_mtext)(x_handle, (x + 23) & ~7, 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]; /* 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, chardim); 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_mtext)(x_handle, x, y, *(ptr++)); if (*ptr) (*v_mtext)(x_handle, x, y + chardim[3], *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]); } } extern int total_tiles_used; /* tile.c */ int mar_gem_init() { int i, bild_fehler = FALSE, fsize; char *fname; 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(); /* MAR -- 17.Mar 2002 NVDI 3.0 or better uses v_ftext */ v_mtext = speedo == 3 ? &v_ftext : &v_gtext; for (i = 0; i < NHICON; i++) mar_get_rsc_tree(i, &zz_oblist[i]); z_ob = zz_oblist[ABOUT]; ob_hide(z_ob, OKABOUT, TRUE); ob_draw_dialog(z_ob, 0, 0, 0, 0); mar_get_font(NHW_MESSAGE, &fname, &fsize); mar_set_font(NHW_MESSAGE, fname, fsize); mar_get_font(NHW_MAP, &fname, &fsize); mar_set_font(NHW_MAP, fname, fsize); mar_get_font(NHW_STATUS, &fname, &fsize); mar_set_font(NHW_STATUS, fname, fsize); mar_get_font(NHW_MENU, &fname, &fsize); mar_set_font(NHW_MENU, fname, fsize); mar_get_font(NHW_TEXT, &fname, &fsize); mar_set_font(NHW_TEXT, fname, fsize); msg_anz = mar_get_msg_history(); mar_set_msg_visible(mar_get_msg_visible()); msg_width = min(max_w / msg_font.cw - 3, MSGLEN); if (max_w / status_font.cw < COLNO - 1) mar_set_fontbyid(NHW_STATUS, small_font_id, -small_font); status_w = min(max_w / status_font.cw - 3, MSGLEN); if (planes > 0 && planes < 9) { normal_palette = (short *) m_alloc(3 * colors * sizeof(short)); get_colors(x_handle, normal_palette, colors); } loadimg: bild_fehler = depack_img(Tilefile ? Tilefile : (planes >= 4) ? "NH16.IMG" : "NH2.IMG", &tile_image); 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); } if (tile_image.img_w % Tile_width || tile_image.img_h % Tile_heigth) { Tilefile = NULL; Tile_width = Tile_heigth = 16; printf("size didn't match.\n"); goto loadimg; } if ((tile_image.img_w / Tile_width) * (tile_image.img_h / Tile_heigth) < total_tiles_used) { Tilefile = NULL; Tile_width = Tile_heigth = 16; printf("Too few Tiles in Image.\n"); goto loadimg; } Tiles_per_line = tile_image.img_w / Tile_width; if (planes >= 4) { if (tile_image.planes > 1) img_set_colors(x_handle, tile_image.palette, tile_image.planes); #if 0 else{ int mypalette[]={}; img_set_colors(x_handle, mypalette, 4); } #endif } 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 - 1) * Tile_width, ROWNO * Tile_heigth, 0, planes); mfdb(&FontCol_Bild, NULL, (COLNO - 1) * map_font.cw, ROWNO * map_font.ch, 0, planes); Map_bild.fd_addr = (int *) m_alloc(mfdb_size(&Map_bild) > mfdb_size(&FontCol_Bild) ? mfdb_size(&Map_bild) : mfdb_size(&FontCol_Bild)); FontCol_Bild.fd_addr = Map_bild.fd_addr; mfdb(&Pet_Mark, pet_mark_data, 8, 7, 1, 1); vr_trnfm(x_handle, &Pet_Mark, &Pet_Mark); mfdb(&Black_bild, NULL, 16, 32, 1, 1); /* MAR -- 17.Mar 2002 that should cover the biggest map-font */ 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 < MAXWIN; i++) { Gem_nhwindow[i].gw_window = NULL; Gem_nhwindow[i].gw_type = 0; Gem_nhwindow[i].gw_dirty = TRUE; } memset(&scroll_menu, 0, sizeof(scroll_menu)); scroll_menu.scroll = AUTO_SCROLL; scroll_menu.obj = LINESLIST; scroll_menu.px_hline = menu_font.cw; scroll_menu.px_vline = menu_font.ch; scroll_menu.hscroll = scroll_menu.vscroll = 1; scroll_menu.tbar_d = 2 * gr_ch - 2; mar_set_dir_keys(); memset(&scroll_map, 0, sizeof(scroll_map)); scroll_map.scroll = AUTO_SCROLL; scroll_map.obj = ROOT; scroll_map.px_hline = mar_set_tile_mode(FAIL) ? Tile_width : map_font.cw; scroll_map.px_vline = mar_set_tile_mode(FAIL) ? Tile_heigth : map_font.ch; scroll_map.hsize = COLNO - 1; scroll_map.vsize = ROWNO; scroll_map.hpage = 8; scroll_map.vpage = 8; scroll_map.hscroll = 1; scroll_map.vscroll = 1; /* dial_options( round, niceline, standard, return_default, background, nonselectable, always_keys, toMouse, clipboard, hz); */ dial_options(TRUE, TRUE, FALSE, RETURN_DEFAULT, AES_BACK, TRUE, KEY_ALWAYS, FALSE, TRUE, 3); /* dial_colors( dial_pattern, dial_color, dial_frame, hotkey, alert, cycle_button, check_box, radio_button, arrow, cycle_backgrnd, check_backgrnd, radio_backgrnd, arrow_backgrnd, edit_3d, draw_3d) */ 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); /* void MenuItems(MITEM *close,MITEM *closeall,MITEM *cycle,MITEM *invcycle, MITEM *globcycle,MITEM *full,MITEM *bottom,MITEM *iconify,MITEM *iconify_all, MITEM *menu,int menu_cnt) */ /* Ctrl-W ist normaly bound to cycle */ MenuItems(NULL, NULL, &wish_workaround, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0); menu_install(zz_oblist[MENU], TRUE); z_ob = zz_oblist[ABOUT]; ob_undraw_dialog(z_ob, 0, 0, 0, 0); ob_hide(z_ob, OKABOUT, FALSE); return (1); } /************************* mar_exit_nhwindows *******************************/ void mar_exit_nhwindows() { int i; for (i = MAXWIN; --i >= 0;) if (Gem_nhwindow[i].gw_type) mar_destroy_nhwindow(i); if (normal_palette) { img_set_colors(x_handle, normal_palette, tile_image.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_cliparound(void); void mar_map_curs_weiter(void) { static int once = TRUE; if (once) { redraw_window(Gem_nhwindow[WIN_STATUS].gw_window, NULL); redraw_window(Gem_nhwindow[WIN_MESSAGE].gw_window, NULL); once = FALSE; } mar_curs(map_cursx + 1, map_cursy); mar_cliparound(); } /************************* 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 + gr_ch; } 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) { int extent[8]; v_set_text(menu_font.id, menu_font.size, BLACK, 0, 0, NULL); vqt_extent(x_handle, curr->Gmi_str, extent); Max(&Inv_breite, extent[4] + Tile_width + menu_font.cw); 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_set_text_to_rip(winid w) { use_rip = TRUE; } 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"); return; } 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.hsize = 0; scroll_menu.vpage = (desk.g_h - 3 * gr_ch) / scroll_menu.px_vline; if (Anzahl > scroll_menu.vpage) { retval |= WD_VSLIDER; if (Breite > max_w - 3 * scroll_menu.px_hline) { retval |= WD_HSLIDER; scroll_menu.hpage = (max_w - 3 * scroll_menu.px_hline) / scroll_menu.px_hline; scroll_menu.hpos = 0; scroll_menu.hsize = Breite / scroll_menu.px_hline; scroll_menu.vpage = (desk.g_h - 4 * gr_ch - 1) / scroll_menu.px_vline; } Anzahl = scroll_menu.vpage; } else { if (Breite > max_w - scroll_menu.px_hline) { retval |= WD_HSLIDER; scroll_menu.hpage = (max_w - scroll_menu.px_hline) / scroll_menu.px_hline; scroll_menu.hpos = 0; scroll_menu.hsize = Breite / scroll_menu.px_hline; scroll_menu.vpage = (desk.g_h - 4 * gr_ch - 1) / scroll_menu.px_vline; 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 2gr_ch 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 = scroll_menu.px_vline * Anzahl; z_ob[QLINE].ob_y += gr_ch / 2; z_ob[ROOT].ob_width += 4; z_ob[ROOT].ob_height += 2 * gr_ch + 2; return (retval); } /************************* mar_status_dirty *******************************/ void mar_status_dirty() { int ccol; 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 < mesg_hist - 1; i++) { message_line[i] = message_line[i + 1]; message_age[i] = message_age[i + 1]; } message_line[mesg_hist - 1] = tmp; } strcpy(toplines, str); messages_pro_zug++; msg_max++; if ((int) strlen(toplines) >= 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; strncpy(message_line[msg_max], toplines, msg_width); 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; { int i, last_diff = -1; GRECT area = { 0, line * status_font.ch, status_font.cw, status_font.ch }; for (i = 0; (i < status_w - 2) && str[i]; i++) if (str[i] != status_line[line][i]) { if (last_diff == -1) area.g_x = i * status_font.cw; else area.g_w += status_font.cw; last_diff = i; status_line[line][i] = str[i]; } else if (last_diff >= 0) { add_dirty_rect(dr_stat, &area); last_diff = -1; area.g_w = status_font.cw; } for (; i < status_w - 1; i++) { if (status_line[line][i]) { if (last_diff == -1) area.g_x = i * status_font.cw; else area.g_w += status_font.cw; last_diff = i; } status_line[line][i] = 0; } if (last_diff >= 0) add_dirty_rect(dr_stat, &area); } /************************* 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 KM_Init int Text_Handler(xev) XEVENT *xev; { int ev = xev->ev_mwich; if (ev & MU_MESAG) { int *buf = xev->ev_mmgpbuf, y_wo, i; if (*buf == FONT_CHANGED) { if (buf[3] >= 0) { mar_set_fontbyid(NHW_TEXT, buf[4], buf[5]); FontAck(buf[1], 1); } } } 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; case C('c'): clipbrd_save(text_lines, Anz_text_lines, xev->ev_mmokstate & K_SHIFT, FALSE); break; default: ev &= ~MU_KEYBD; /* unknown key */ break; } } return (ev); } #define Inv_Init KM_Init static long count = 0; int Inv_Handler(xev) XEVENT *xev; { int ev = xev->ev_mwich; Gem_menu_item *it; GRECT area; 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 == FONT_CHANGED) { if (buf[3] >= 0) { mar_set_fontbyid(NHW_MENU, buf[4], buf[5]); FontAck(buf[1], 1); } } else if (*buf == OBJC_CHANGED && buf[3] == LINESLIST) { ob_undostate(z_ob, LINESLIST, SELECTED); mouse(NULL, &y_wo); y_wo = (y_wo - area.g_y) / menu_font.ch + scroll_menu.vpos; for (it = invent_list, i = 0; i < y_wo && it; it = it->Gmi_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);*/ send_return(); } else { area.g_x = (area.g_x + 23 + 2 * menu_font.cw) & ~7; area.g_w = menu_font.cw; area.g_h = menu_font.ch; area.g_y += (y_wo - scroll_menu.vpos) * menu_font.ch; 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; case C('c'): clipbrd_save(invent_list, Anz_inv_lines, xev->ev_mmokstate & K_SHIFT, TRUE); break; default: find_acc: if (Inv_how == PICK_NONE) my_close_dialog(Inv_dialog, TRUE); else 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 = (area.g_x + 23 + 2 * menu_font.cw) & ~7; area.g_w = menu_font.cw; 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 redraw_winwork(WIN *w, GRECT *area) { area->g_x += w->work.g_x; area->g_y += w->work.g_y; redraw_window(w, area); } 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 recalc_msg_win(GRECT *area) { OBJECT *z_ob; 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) * msg_font.cw; z_ob[MSGLINES].ob_width -= z_ob[UPMSG].ob_width; z_ob[ROOT].ob_height = z_ob[GRABMSGWIN].ob_height = z_ob[MSGLINES].ob_height = msg_vis * msg_font.ch; z_ob[DNMSG].ob_y = z_ob[GRABMSGWIN].ob_height - z_ob[DNMSG].ob_height; window_border(0, 0, 0, z_ob->ob_width, z_ob->ob_height, area); } void recalc_status_win(GRECT *area) { OBJECT *z_ob; 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) * status_font.cw; z_ob[ROOT].ob_height = z_ob[GRABSTATUS].ob_height = 2 * status_font.ch; z_ob[GRABSTATUS].ob_width = 2 * status_font.cw - 2; window_border(0, 0, 0, z_ob->ob_width, z_ob->ob_height, area); } void calc_std_winplace(int which, GRECT *place) { static int todo = TRUE; static GRECT me, ma, st; if (todo || which < 0) { OBJECT *z_ob; int map_h_off, foo; /* First the messagewin */ recalc_msg_win(&me); /* Now the map */ 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); map_h_off -= scroll_map.px_vline * ROWNO; window_border(MAP_GADGETS, 0, 0, scroll_map.px_hline * (COLNO - 1), scroll_map.px_vline * ROWNO, &ma); /* Next the statuswin */ recalc_status_win(&st); /* And last but not least a final test */ ma.g_h = map_h_off + scroll_map.px_vline * ROWNO; while (me.g_h + ma.g_h + st.g_h >= desk.g_h) ma.g_h -= scroll_map.px_vline; /* stack the windows */ ma.g_y = me.g_y = st.g_y = desk.g_y; if (status_align) { ma.g_y += st.g_h; if (msg_align) { st.g_y += me.g_h; ma.g_y += me.g_h; } else { me.g_y += st.g_h + ma.g_h; } } else { if (msg_align) { ma.g_y += me.g_h; } else { me.g_y += ma.g_h; } st.g_y += me.g_h + ma.g_h; } if (which) 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; if (use_rip) { if (!depack_img(planes < 4 ? "RIP2.IMG" : "RIP.IMG", &rip_image)) { mfdb(&Rip_bild, (int *) rip_image.addr, rip_image.img_w, rip_image.img_h, 1, rip_image.planes); transform_img(&Rip_bild); } ub_lines.ub_code = draw_rip; } else ub_lines.ub_code = draw_lines; z_ob[LINESLIST].ob_spec.userblk = &ub_lines; breite = 16; v_set_text(text_font.id, text_font.size, BLACK, 0, 0, NULL); for (i = 0; i < Anz_text_lines; i++) { int eout[8]; vqt_extent(x_handle, text_lines[i], eout); Max(&breite, eout[4]); } scroll_menu.px_vline = text_font.ch; scroll_menu.px_hline = text_font.cw; mar_di_mode = mar_set_inv_win(Anz_text_lines, breite); tmp_button = ob_get_text(z_ob, QLINE, 0); ob_set_text(z_ob, QLINE, strOk); ob_undoflag(z_ob, LINESLIST, TOUCHEXIT); Event_Handler(Text_Init, Text_Handler); if ((dlg_info = open_dialog(z_ob, strText, NULL, NULL, mar_ob_mapcenter(z_ob), FALSE, mar_di_mode, FAIL, NULL, NULL)) != NULL) { WIN *ptr_win = dlg_info->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(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, gr_cw * strlen(Menu_title) + 16); scroll_menu.px_vline = menu_font.ch; scroll_menu.px_hline = menu_font.cw; mar_di_mode = mar_set_inv_win(Anz_inv_lines, Inv_breite, NHW_MENU); 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, TOUCHEXIT); 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); do { int y_wo, x_wo, ru_w = 1, ru_h = 1; GRECT oarea; Gem_menu_item *it; d_exit = X_Form_Do(NULL); if ((d_exit & NO_CLICK) == LINESLIST) { ob_pos(z_ob, LINESLIST, &oarea); if (mouse(&x_wo, &y_wo) && Inv_how == PICK_ANY) { graf_rt_rubberbox(FALSE, x_wo, y_wo, FAIL, FAIL, &oarea, &ru_w, &ru_h, NULL); 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); } else { for (it = invent_list, i = 0; i < ((y_wo - oarea.g_y) / menu_font.ch + scroll_menu.vpos) && it; it = it->Gmi_next, i++) ; if (it && it->Gmi_identifier) { it->Gmi_selected = !it->Gmi_selected; it->Gmi_count = count == 0L ? -1L : count; count = 0L; if (Inv_how != PICK_ANY) break; } /* identifier */ } oarea.g_x = (oarea.g_x + 23 + 2 * menu_font.cw) & ~7; oarea.g_y = y_wo - (y_wo - oarea.g_y) % menu_font.ch; oarea.g_w = menu_font.cw; oarea.g_h = ((ru_h + menu_font.ch - 1) / menu_font.ch) * menu_font.ch; ob_draw_chg(Inv_dialog, LINESLIST, &oarea, FAIL); } 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); } } while ((d_exit & NO_CLICK) == LINESLIST); if (d_exit != 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, Tile_width * (COLNO - 1), Tile_heigth * 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 - 1; 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); p_Gw->gw_dirty = TRUE; } if (p_Gw->gw_dirty) { ob_pos(zz_oblist[MSGWIN], MSGLINES, &area); while (messages_pro_zug > 3) { messages_pro_zug -= 3; msg_pos += 3; redraw_window(p_Gw->gw_window, &area); 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, &area); 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*status_font.ch 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); p_Gw->gw_dirty = TRUE; add_dirty_rect(dr_stat, &p_Gw->gw_place); } while (get_dirty_rect(dr_stat, &area)) { area.g_x = (area.g_x + p_Gw->gw_window->work.g_x + 2 * status_font.cw + 6) & ~7; area.g_y += p_Gw->gw_window->work.g_y; redraw_window(p_Gw->gw_window, &area); } break; 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; i < msg_anz; i++) { message_age[i] = FALSE; message_line[i] = (char *) m_alloc((MSGLEN + 1) * sizeof(char)); *message_line[i] = 0; } dr_msg = new_dirty_rect(10); if (!dr_msg) panic("Memory allocation failure (dr_msg)"); break; case NHW_STATUS: status_line = (char **) m_alloc(2 * sizeof(char *)); for (i = 0; i < 2; i++) { status_line[i] = (char *) m_alloc(status_w * sizeof(char)); memset(status_line[i], 0, status_w); } dr_stat = new_dirty_rect(10); if (!dr_stat) panic("Memory allocation failure (dr_stat)"); break; case NHW_MAP: map_glyphs = (char **) m_alloc((long) ROWNO * sizeof(char *)); for (i = 0; i < ROWNO; i++) { map_glyphs[i] = (char *) m_alloc((long) COLNO * sizeof(char)); *map_glyphs[i] = map_glyphs[i][COLNO - 1] = 0; } dr_map = new_dirty_rect(10); if (!dr_map) panic("Memory allocation failure (dr_map)"); mar_clear_map(); break; case NHW_MENU: case NHW_TEXT: /* They are no more treated as dialog */ break; default: 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); 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() { int pla[8]; int x, y; pla[0] = pla[1] = pla[4] = pla[5] = 0; pla[2] = pla[6] = scroll_map.px_hline * (COLNO - 1) - 1; pla[3] = pla[7] = scroll_map.px_vline * ROWNO - 1; for (y = 0; y < ROWNO; y++) for (x = 0; x < COLNO - 1; x++) map_glyphs[y][x] = ' '; vro_cpyfm(x_handle, ALL_BLACK, pla, &Tile_bilder, &Map_bild); /* MAR -- 17.Mar 2002 Hmm, what if FontCol_Bild is bigger? */ if (WIN_MAP != WIN_ERR && Gem_nhwindow[WIN_MAP].gw_window) redraw_window(Gem_nhwindow[WIN_MAP].gw_window, NULL); } /************************* destroy_window *******************************/ void mar_destroy_nhwindow(window) winid window; { int i; switch (Gem_nhwindow[window].gw_type) { case NHW_TEXT: for (i = 0; i < Anz_text_lines; i++) free(text_lines[i]); null_free(text_lines); Anz_text_lines = 0; use_rip = FALSE; break; case NHW_MENU: Gem_start_menu(window); /* delete invent_list */ test_free(Menu_title); break; case 0: /* No window available, probably an error message? */ break; default: close_window(Gem_nhwindow[window].gw_window, 0); break; } Gem_nhwindow[window].gw_window = NULL; Gem_nhwindow[window].gw_type = 0; Gem_nhwindow[window].gw_dirty = FALSE; if (window == WIN_MAP) { for (i = 0; i < ROWNO; i++) { free(map_glyphs[i]); } null_free(map_glyphs); WIN_MAP = WIN_ERR; } if (window == WIN_STATUS) { for (i = 0; i < 2; i++) free(status_line[i]); null_free(status_line); WIN_STATUS = WIN_ERR; } if (window == WIN_MESSAGE) { for (i = 0; i < msg_anz; i++) free(message_line[i]); null_free(message_line); null_free(message_age); WIN_MESSAGE = WIN_ERR; } if (window == WIN_INVEN) WIN_INVEN = WIN_ERR; } /************************* nh_poskey *******************************/ void mar_set_margin(int m) { Max(&m, 0); Min(&m, min(ROWNO, COLNO)); /* MAR 16.Mar 2002 -- the larger the less sense */ scroll_margin = m; } void mar_cliparound() { if (WIN_MAP != WIN_ERR && Gem_nhwindow[WIN_MAP].gw_window) { int breite = scroll_margin > 0 ? scroll_margin : max(scroll_map.hpage / 4, 1), hoehe = scroll_margin > 0 ? scroll_margin : max(scroll_map.vpage / 4, 1), adjust_needed; adjust_needed = FALSE; if ((map_cursx < scroll_map.hpos + breite) || (map_cursx >= scroll_map.hpos + scroll_map.hpage - breite)) { scroll_map.hpos = map_cursx - scroll_map.hpage / 2; adjust_needed = TRUE; } if ((map_cursy < scroll_map.vpos + hoehe) || (map_cursy >= scroll_map.vpos + scroll_map.vpage - hoehe)) { scroll_map.vpos = map_cursy - scroll_map.vpage / 2; 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_MAP != WIN_ERR) mar_cliparound(); 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) { if (scan >= 0x67 && scan <= 0x6f && scan != 0x6b) { send_key(kpad[scan - KEYPADLO].normal); ch = 'g'; } else { 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 (scan == SCANF4) { /* Font-Selector */ if (!CallFontSelector(0, FAIL, FAIL, FAIL, FAIL)) { xalert(1, 1, X_ICN_ALERT, NULL, SYS_MODAL, BUTTONS_RIGHT, TRUE, "Hello", "Fontselector not available!", NULL); } } 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 - 1), 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; mar_curs(map_cursx, map_cursy); mar_display_nhwindow(WIN_MAP); break; default: } break; default: mar_about(); break; } break; /* MN_SELECTED */ case WM_CLOSED: WindowHandler(W_ICONIFYALL, NULL, NULL); break; case AP_TERM: retval = 'S'; break; case FONT_CHANGED: if (buf[3] >= 0) { if (buf[3] == Gem_nhwindow[WIN_MESSAGE].gw_window->handle) { mar_set_fontbyid(NHW_MESSAGE, buf[4], buf[5]); mar_display_nhwindow(WIN_MESSAGE); } else if (buf[3] == Gem_nhwindow[WIN_MAP].gw_window->handle) { mar_set_fontbyid(NHW_MAP, buf[4], buf[5]); mar_display_nhwindow(WIN_MAP); } else if (buf[3] == Gem_nhwindow[WIN_STATUS].gw_window->handle) { mar_set_fontbyid(NHW_STATUS, buf[4], buf[5]); mar_display_nhwindow(WIN_STATUS); } FontAck(buf[1], 1); } 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 = WIN_MAP != WIN_ERR ? Gem_nhwindow[WIN_MAP].gw_window : NULL; if (tiles < 0) return (tile_mode); else if (!z_w) tile_mode = tiles; else if (tile_mode == tiles || (mar_set_rogue(FAIL) && tiles)) return (FAIL); else { GRECT tmp; tile_mode = tiles; scroll_map.px_hline = tiles ? Tile_width : map_font.cw; scroll_map.px_vline = tiles ? Tile_heigth : map_font.ch; window_border(MAP_GADGETS, 0, 0, scroll_map.px_hline * (COLNO - 1), scroll_map.px_vline * ROWNO, &tmp); z_w->max.g_w = tmp.g_w; z_w->max.g_h = tmp.g_h; 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, bkgl) winid window; int x, y, gl, bkgl; { if (window != WIN_ERR && window == WIN_MAP) { static int pla[8]; pla[2] = pla[0] = (gl % Tiles_per_line) * Tile_width; pla[3] = pla[1] = (gl / Tiles_per_line) * Tile_heigth; pla[2] += Tile_width - 1; pla[3] += Tile_heigth - 1; pla[6] = pla[4] = Tile_width * x; /* x_wert to */ pla[7] = pla[5] = Tile_heigth * y; /* y_wert to */ pla[6] += Tile_width - 1; pla[7] += Tile_heigth - 1; 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] = map_font.cw - 1; pla[3] = map_font.ch - 1; pla[6] = pla[4] = map_font.cw * x; pla[7] = pla[5] = map_font.ch * y; pla[6] += map_font.cw - 1; pla[7] += map_font.ch - 1; colindex[0] = gem_color[col]; colindex[1] = WHITE; vrt_cpyfm(x_handle, MD_REPLACE, pla, &Black_bild, &FontCol_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 * gr_ch; length = z_ob[LGPROMPT].ob_width / gr_cw; 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 * gr_cw) / gr_cw); z_ob[ROOT].ob_width = (len + 8) * gr_cw; z_ob[YNPROMPT].ob_width = gr_cw * 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 + gr_ch + gr_ch / 2; Max((int *) &z_ob[ROOT].ob_width, z_ob[SOMECHARS].ob_width + 4 * gr_cw); z_ob[ROOT].ob_height = z_ob[SOMECHARS].ob_height + 4 * gr_ch; if (strchr(resp, '#')) z_ob[ROOT].ob_height = z_ob[YNOK].ob_y + 2 * gr_ch; 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 * gr_ch; z_ob[CHOSENCH].ob_y = z_ob[CHOSENCH + 1].ob_y = gr_ch / 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 * gr_cw; z_ob[ROOT].ob_height = z_ob[ANYCHAR].ob_height + z_ob[ANYCHAR].ob_y + gr_ch / 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*/