Files
nethack/win/gem/wingem1.c
nhmall c3a77914a9 Modify the window interface for print_glyph
Changes to be committed:
	modified:   doc/window.doc
	modified:   include/qt_win.h
	modified:   include/trampoli.h
	modified:   include/winX.h
	modified:   include/wingem.h
	modified:   include/winprocs.h
	modified:   include/wintty.h
	modified:   src/display.c
	modified:   src/windows.c
	modified:   sys/amiga/winami.p
	modified:   sys/amiga/winfuncs.c
	modified:   sys/amiga/winproto.h
	modified:   sys/wince/mswproc.c
	modified:   sys/wince/winMS.h
	modified:   win/Qt/qt_win.cpp
	modified:   win/X11/winmap.c
	modified:   win/chain/wc_chainin.c
	modified:   win/chain/wc_chainout.c
	modified:   win/chain/wc_trace.c
	modified:   win/gem/wingem.c
	modified:   win/gem/wingem1.c
	modified:   win/gnome/gnbind.c
	modified:   win/tty/wintty.c
	modified:   win/win32/mswproc.c
	modified:   win/win32/winMS.h

print_glyph now takes a second parameter.

Tiles on tiled ports always looked odd on places like the plane of air
where the background color of the tile didn't match the general background
of the surrounding area.

3.6 made that even worse and more glaringly noticeable with the introduction
of darkened room tiles.

The code to actually send something useful through the new parameter
for window ports to take advantage if they want will follow.
2015-06-08 19:37:26 -04:00

3291 lines
97 KiB
C

/* 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 <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <ctype.h>
#include <e_gem.h>
#include <string.h>
#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*/