1 /* NetHack 3.6 mttymain.c $NHDT-Date: 1554215928 2019/04/02 14:38:48 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.13 $ */
2 /* Copyright (c) Jon W{tte, 1993 */
3 /* NetHack may be freely redistributed. See license for details. */
11 #if !TARGET_API_MAC_CARBON
23 * Statics are prefixed _
27 static long _mt_attrs[5][2] = {
28 { 0x000000, 0xffffff }, /* Normal */
29 { 0xff8080, 0xffffff }, /* Underline */
30 { 0x40c020, 0xe0e0e0 }, /* Bold */
31 { 0x003030, 0xff0060 }, /* Blink */
32 { 0xff8888, 0x000000 }, /* Inverse */
35 static char _attrs_inverse[5] = {
41 static long _mt_colors[CLR_MAX][2] = {
42 { 0x000000, 0x808080 }, /* Black */
43 { 0x880000, 0xffffff }, /* Red */
44 { 0x008800, 0xffffff }, /* Green */
45 { 0x553300, 0xffffff }, /* Brown */
46 { 0x000088, 0xffffff }, /* Blue */
47 { 0x880088, 0xffffff }, /* Magenta */
48 { 0x008888, 0xffffff }, /* Cyan */
49 { 0x888888, 0xffffff }, /* Gray */
50 { 0x000000, 0xffffff }, /* No Color */
51 { 0xff4400, 0xffffff }, /* Orange */
52 { 0x00ff00, 0xffffff }, /* Bright Green */
53 { 0xffff00, 0x606060 }, /* Yellow */
54 { 0x0033ff, 0xffffff }, /* Bright Blue */
55 { 0xff00ff, 0xffffff }, /* Bright Magenta */
56 { 0x00ffff, 0xffffff }, /* Bright Cyan */
57 { 0xffffff, 0x505050 }, /* White */
60 static char _colors_inverse[CLR_MAX] = {
61 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
66 #define POWER_LIMIT 22
67 #define SECONDARY_POWER_LIMIT 16
68 #define CHANNEL_LIMIT 14
69 #define SECONDARY_CHANNEL_LIMIT 12
72 tty_change_color(int color, long rgb, int reverse)
74 long inverse, working_rgb = rgb;
75 int total_power = 0, max_channel = 0;
80 total_power += working_rgb & 0xf;
81 max_channel = max(max_channel, working_rgb & 0xf);
85 if (total_power >= POWER_LIMIT
86 || (total_power >= SECONDARY_POWER_LIMIT
87 && max_channel >= SECONDARY_CHANNEL_LIMIT)
88 || max_channel >= CHANNEL_LIMIT)
96 inverse = working_rgb;
99 if (color >= CLR_MAX) {
100 if (color - CLR_MAX >= 5)
101 impossible("Changing too many colors");
103 _mt_attrs[color - CLR_MAX][0] = rgb;
104 _mt_attrs[color - CLR_MAX][1] = inverse;
105 _attrs_inverse[color - CLR_MAX] = reverse;
107 } else if (color >= 0) {
108 _mt_colors[color][0] = rgb;
109 _mt_colors[color][1] = inverse;
110 _colors_inverse[color] = reverse;
112 impossible("Changing negative color");
116 tty_change_background(int white_or_black)
120 for (i = 0; i < CLR_MAX; i++) {
122 _mt_colors[i][1] = 0xffffff; /* white */
124 _mt_colors[i][1] = 0x000000; /* black */
128 if (white_or_black) {
129 _mt_colors[CLR_BLACK][1] =
130 0x808080; /* differentiate black from no color */
131 _mt_colors[CLR_WHITE][1] =
132 0x505050; /* highlight white with grey background */
133 _mt_colors[CLR_YELLOW][1] =
134 0x606060; /* highlight yellow with grey background */
135 _mt_colors[CLR_BLUE][0] = 0x000088; /* make pure blue */
136 _mt_colors[NO_COLOR][0] = 0x000000; /* make no_color black on white */
137 _mt_attrs[0][0] = 0x000000; /* "normal" is black on white */
138 _mt_attrs[0][1] = 0xffffff;
140 _mt_colors[NO_COLOR][0] = 0xffffff; /* make no_color white on black */
141 _mt_colors[CLR_BLACK][1] =
142 0x808080; /* differentiate black from no color */
143 _mt_colors[CLR_BLUE][0] =
144 0x222288; /* lighten blue - it's too dark on black */
145 _mt_attrs[0][0] = 0xffffff; /* "normal" is white on black */
146 _mt_attrs[0][1] = 0x000000;
151 tty_get_color_string(void)
155 static char color_buf[5 * (CLR_MAX + 5) + 1];
160 for (count = 0; count < CLR_MAX; count++) {
161 int flag = _colors_inverse[count] ? 1 : 0;
163 sprintf(ptr, "%s%s%x%x%x", count ? "/" : "", flag ? "-" : "",
164 (int) (_mt_colors[count][flag] >> 20) & 0xf,
165 (int) (_mt_colors[count][flag] >> 12) & 0xf,
166 (int) (_mt_colors[count][flag] >> 4) & 0xf);
169 for (count = 0; count < 5; count++) {
170 int flag = _attrs_inverse[count] ? 1 : 0;
172 sprintf(ptr, "/%s%x%x%x", flag ? "-" : "",
173 (int) (_mt_attrs[count][flag] >> 20) & 0xf,
174 (int) (_mt_attrs[count][flag] >> 12) & 0xf,
175 (int) (_mt_attrs[count][flag] >> 4) & 0xf);
183 extern struct DisplayDesc *ttyDisplay; /* the tty display descriptor */
185 char kill_char = CHAR_ESC;
186 char erase_char = CHAR_BS;
188 WindowRef _mt_window = (WindowRef) 0;
189 static Boolean _mt_in_color = 0;
190 extern short win_fonts[NHW_TEXT + 1];
196 short num_cols, num_rows, win_width, win_height, font_num, font_size;
197 short char_width, row_height;
203 if (!strcmp(windowprocs.name, "mac")) {
204 dprintf("Mac Windows");
207 dprintf("TTY Windows");
211 * If there is at least one screen CAPABLE of color, and if
212 * 32-bit QD is there, we use color. 32-bit QD is needed for the
215 if (!Gestalt(gestaltQuickdrawVersion, &resp) && resp > 0x1ff) {
216 GDHandle gdh = GetDeviceList();
218 if (TestDeviceAttribute(gdh, screenDevice)) {
219 if (HasDepth(gdh, 4, 1, 1) || HasDepth(gdh, 8, 1, 1)
220 || HasDepth(gdh, 16, 1, 1) || HasDepth(gdh, 32, 1, 1)) {
225 gdh = GetNextDevice(gdh);
229 if (create_tty(&_mt_window, WIN_BASE_KIND + NHW_MAP, _mt_in_color)
231 error("_mt_init_stuff: Couldn't create tty.");
232 SetWindowKind(_mt_window, WIN_BASE_KIND + NHW_MAP);
233 SelectWindow(_mt_window);
234 SetPortWindowPort(_mt_window);
237 font_size = iflags.wc_fontsiz_map
238 ? iflags.wc_fontsiz_map
239 : (iflags.large_font && !small_screen) ? 12 : 9;
240 if (init_tty_number(_mt_window, win_fonts[NHW_MAP], font_size, CO, LI)
242 error("_mt_init_stuff: Couldn't init tty.");
244 if (get_tty_metrics(_mt_window, &num_cols, &num_rows, &win_width,
245 &win_height, &font_num, &font_size, &char_width,
247 error("_mt_init_stuff: Couldn't get tty metrics.");
249 SizeWindow(_mt_window, win_width + 2, win_height + 2, 1);
250 if (RetrievePosition(kMapWindow, &vert, &hor)) {
251 dprintf("Moving window to (%d,%d)", hor, vert);
252 MoveWindow(_mt_window, hor, vert, 1);
254 ShowWindow(_mt_window);
256 /* Start in raw, always flushing mode */
257 get_tty_attrib(_mt_window, TTY_ATTRIB_FLAGS, &flag);
258 flag |= TA_ALWAYS_REFRESH | TA_WRAP_AROUND;
259 set_tty_attrib(_mt_window, TTY_ATTRIB_FLAGS, flag);
261 get_tty_attrib(_mt_window, TTY_ATTRIB_CURSOR, &flag);
262 flag |= (TA_BLINKING_CURSOR | TA_NL_ADD_CR);
263 set_tty_attrib(_mt_window, TTY_ATTRIB_CURSOR, flag);
265 set_tty_attrib(_mt_window, TTY_ATTRIB_FOREGROUND,
266 _mt_colors[NO_COLOR][0]);
267 set_tty_attrib(_mt_window, TTY_ATTRIB_BACKGROUND,
268 _mt_colors[NO_COLOR][1]);
269 clear_tty(_mt_window);
282 WaitNextEvent(-1, &event, sleepTime, 0);
284 blink_cursor(_mt_window, event.when);
285 if (event.what == nullEvent) {
286 sleepTime = GetCaretTime();
290 ret = GetFromKeyQueue();
301 msmsg("Press space %s", str);
308 #if defined(__SC__) || defined(__MRC__)
309 #pragma unused(color)
318 GetWindowBounds(_mt_window, kWindowContentRgn, &r);
319 // SetPortWindowPort(_mt_window);
320 // LocalToGlobal (&p);
321 // OffsetRect (&r, p.h, p.v);
323 gh = GetMaxDevice(&r);
328 return (*((*gh)->gdPMap))->pixelSize > 4; /* > 4 bpp */
332 tty_delay_output(void)
335 long toWhen = TickCount() + 3;
337 while (TickCount() < toWhen) {
338 WaitNextEvent(updateMask, &event, 3L, 0);
339 if (event.what == updateEvt) {
341 blink_cursor(_mt_window, event.when);
349 move_tty_cursor(_mt_window, x, y);
350 ttyDisplay->cury = y;
351 ttyDisplay->curx = x;
361 _mt_set_colors(long *colors)
368 err = set_tty_attrib(_mt_window, TTY_ATTRIB_FOREGROUND, colors[0]);
369 err = set_tty_attrib(_mt_window, TTY_ATTRIB_BACKGROUND, colors[1]);
373 term_attr_fixup(int attrmask)
375 attrmask &= ~ATR_DIM;
380 term_end_attr(int attr)
382 #if defined(__SC__) || defined(__MRC__)
385 _mt_set_colors(_mt_attrs[0]);
389 term_start_attr(int attr)
393 _mt_set_colors(_mt_attrs[1]);
396 _mt_set_colors(_mt_attrs[2]);
399 _mt_set_colors(_mt_attrs[3]);
402 _mt_set_colors(_mt_attrs[4]);
405 _mt_set_colors(_mt_attrs[0]);
413 term_end_attr(ATR_INVERSE);
419 term_start_attr(ATR_INVERSE);
425 _mt_set_colors(_mt_colors[NO_COLOR]);
431 _mt_set_colors(_mt_attrs[0]);
432 clear_tty_window(_mt_window, ttyDisplay->curx, ttyDisplay->cury, CO - 1,
439 _mt_set_colors(_mt_attrs[0]);
440 clear_tty(_mt_window);
446 _mt_set_colors(_mt_attrs[0]);
447 clear_tty_window(_mt_window, ttyDisplay->curx, ttyDisplay->cury, CO - 1,
460 char eraser[] = { CHAR_BS, CHAR_BLANK, CHAR_BS, 0 };
463 err = add_tty_string(_mt_window, eraser);
464 err = update_tty(_mt_window);
468 msmsg(const char *str, ...)
474 vsprintf(buf, str, args);
481 term_end_raw_bold(void)
483 term_end_attr(ATR_INVERSE);
487 term_start_raw_bold(void)
489 term_start_attr(ATR_INVERSE);
493 term_start_color(int color)
495 if (color >= 0 && color < CLR_MAX) {
496 _mt_set_colors(_mt_colors[color]);
505 /* Buffered output for the game */
506 get_tty_attrib(_mt_window, TTY_ATTRIB_FLAGS, &flag);
507 flag &= ~TA_ALWAYS_REFRESH;
508 flag |= TA_INHIBIT_VERT_SCROLL; /* don't scroll */
509 set_tty_attrib(_mt_window, TTY_ATTRIB_FLAGS, flag);
514 tty_startup(int *width, int *height)
527 settty(const char *str)
531 update_tty(_mt_window);
533 /* Buffered output for the game, raw in "raw" mode */
534 get_tty_attrib(_mt_window, TTY_ATTRIB_FLAGS, &flag);
535 flag &= ~TA_INHIBIT_VERT_SCROLL; /* scroll */
536 flag |= TA_ALWAYS_REFRESH;
537 set_tty_attrib(_mt_window, TTY_ATTRIB_FLAGS, flag);
546 tty_number_pad(int arg)
548 #if defined(__SC__) || defined(__MRC__)
554 tty_start_screen(void)
565 xputs(const char *str)
567 add_tty_string(_mt_window, str);
571 term_puts(const char *str)
582 err = add_tty_char(_mt_window, c);
583 return err ? EOF : c;
587 term_flush(void *desc)
589 if (desc == stdout || desc == stderr) {
590 update_tty(_mt_window);
592 impossible("Substituted flush for file");