1 /* aNetHack 0.0.1 mttymain.c $ANH-Date: 1432512797 2015/05/25 00:13:17 $ $ANH-Branch: master $:$ANH-Revision: 1.12 $ */
2 /* Copyright (c) Jon W{tte, 1993 */
3 /* aNetHack 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_end_attr(int attr
)
375 #if defined(__SC__) || defined(__MRC__)
378 _mt_set_colors(_mt_attrs
[0]);
382 term_start_attr(int attr
)
386 _mt_set_colors(_mt_attrs
[1]);
389 _mt_set_colors(_mt_attrs
[2]);
392 _mt_set_colors(_mt_attrs
[3]);
395 _mt_set_colors(_mt_attrs
[4]);
398 _mt_set_colors(_mt_attrs
[0]);
406 term_end_attr(ATR_INVERSE
);
412 term_start_attr(ATR_INVERSE
);
418 _mt_set_colors(_mt_colors
[NO_COLOR
]);
424 _mt_set_colors(_mt_attrs
[0]);
425 clear_tty_window(_mt_window
, ttyDisplay
->curx
, ttyDisplay
->cury
, CO
- 1,
432 _mt_set_colors(_mt_attrs
[0]);
433 clear_tty(_mt_window
);
439 _mt_set_colors(_mt_attrs
[0]);
440 clear_tty_window(_mt_window
, ttyDisplay
->curx
, ttyDisplay
->cury
, CO
- 1,
453 char eraser
[] = { CHAR_BS
, CHAR_BLANK
, CHAR_BS
, 0 };
456 err
= add_tty_string(_mt_window
, eraser
);
457 err
= update_tty(_mt_window
);
461 msmsg(const char *str
, ...)
467 vsprintf(buf
, str
, args
);
474 term_end_raw_bold(void)
476 term_end_attr(ATR_INVERSE
);
480 term_start_raw_bold(void)
482 term_start_attr(ATR_INVERSE
);
486 term_start_color(int color
)
488 if (color
>= 0 && color
< CLR_MAX
) {
489 _mt_set_colors(_mt_colors
[color
]);
498 /* Buffered output for the game */
499 get_tty_attrib(_mt_window
, TTY_ATTRIB_FLAGS
, &flag
);
500 flag
&= ~TA_ALWAYS_REFRESH
;
501 flag
|= TA_INHIBIT_VERT_SCROLL
; /* don't scroll */
502 set_tty_attrib(_mt_window
, TTY_ATTRIB_FLAGS
, flag
);
507 tty_startup(int *width
, int *height
)
520 settty(const char *str
)
524 update_tty(_mt_window
);
526 /* Buffered output for the game, raw in "raw" mode */
527 get_tty_attrib(_mt_window
, TTY_ATTRIB_FLAGS
, &flag
);
528 flag
&= ~TA_INHIBIT_VERT_SCROLL
; /* scroll */
529 flag
|= TA_ALWAYS_REFRESH
;
530 set_tty_attrib(_mt_window
, TTY_ATTRIB_FLAGS
, flag
);
539 tty_number_pad(int arg
)
541 #if defined(__SC__) || defined(__MRC__)
547 tty_start_screen(void)
558 xputs(const char *str
)
560 add_tty_string(_mt_window
, str
);
564 term_puts(const char *str
)
575 err
= add_tty_char(_mt_window
, c
);
576 return err
? EOF
: c
;
580 term_flush(void *desc
)
582 if (desc
== stdout
|| desc
== stderr
) {
583 update_tty(_mt_window
);
585 impossible("Substituted flush for file");