Remove start_screen() and end_screen() from the Window-port interface. They were only ever used by tty, and there was a comment carried to several window-ports about how they "really should go away. They are tty-specific" term_start_screen() and term_end_screen() are part of terminal/NO_TERMS supporting routines now.
627 lines
14 KiB
C
627 lines
14 KiB
C
/* 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 $ */
|
|
/* Copyright (c) Jon W{tte, 1993 */
|
|
/* NetHack may be freely redistributed. See license for details. */
|
|
|
|
#include "hack.h"
|
|
#include "macwin.h"
|
|
#include "mttypriv.h"
|
|
#include "mactty.h"
|
|
#include "wintty.h"
|
|
|
|
#if !TARGET_API_MAC_CARBON
|
|
#include <Palettes.h>
|
|
#endif
|
|
#include <Gestalt.h>
|
|
|
|
#define MT_WINDOW 135
|
|
#define MT_WIDTH 80
|
|
#define MT_HEIGHT 24
|
|
|
|
/*
|
|
* Names:
|
|
*
|
|
* Statics are prefixed _
|
|
* Mac-tty becomes mt_
|
|
*/
|
|
|
|
static long _mt_attrs[5][2] = {
|
|
{ 0x000000, 0xffffff }, /* Normal */
|
|
{ 0xff8080, 0xffffff }, /* Underline */
|
|
{ 0x40c020, 0xe0e0e0 }, /* Bold */
|
|
{ 0x003030, 0xff0060 }, /* Blink */
|
|
{ 0xff8888, 0x000000 }, /* Inverse */
|
|
};
|
|
|
|
static char _attrs_inverse[5] = {
|
|
0, 0, 0, 0, 0,
|
|
};
|
|
|
|
/* see color.h */
|
|
|
|
static long _mt_colors[CLR_MAX][2] = {
|
|
{ 0x000000, 0x808080 }, /* Black */
|
|
{ 0x880000, 0xffffff }, /* Red */
|
|
{ 0x008800, 0xffffff }, /* Green */
|
|
{ 0x553300, 0xffffff }, /* Brown */
|
|
{ 0x000088, 0xffffff }, /* Blue */
|
|
{ 0x880088, 0xffffff }, /* Magenta */
|
|
{ 0x008888, 0xffffff }, /* Cyan */
|
|
{ 0x888888, 0xffffff }, /* Gray */
|
|
{ 0x000000, 0xffffff }, /* No Color */
|
|
{ 0xff4400, 0xffffff }, /* Orange */
|
|
{ 0x00ff00, 0xffffff }, /* Bright Green */
|
|
{ 0xffff00, 0x606060 }, /* Yellow */
|
|
{ 0x0033ff, 0xffffff }, /* Bright Blue */
|
|
{ 0xff00ff, 0xffffff }, /* Bright Magenta */
|
|
{ 0x00ffff, 0xffffff }, /* Bright Cyan */
|
|
{ 0xffffff, 0x505050 }, /* White */
|
|
};
|
|
|
|
static char _colors_inverse[CLR_MAX] = {
|
|
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
};
|
|
|
|
#ifdef CHANGE_COLOR
|
|
|
|
#define POWER_LIMIT 22
|
|
#define SECONDARY_POWER_LIMIT 16
|
|
#define CHANNEL_LIMIT 14
|
|
#define SECONDARY_CHANNEL_LIMIT 12
|
|
|
|
void
|
|
tty_change_color(int color, long rgb, int reverse)
|
|
{
|
|
long inverse, working_rgb = rgb;
|
|
int total_power = 0, max_channel = 0;
|
|
int cnt = 3;
|
|
|
|
working_rgb >>= 4;
|
|
while (cnt-- > 0) {
|
|
total_power += working_rgb & 0xf;
|
|
max_channel = max(max_channel, working_rgb & 0xf);
|
|
working_rgb >>= 8;
|
|
}
|
|
|
|
if (total_power >= POWER_LIMIT
|
|
|| (total_power >= SECONDARY_POWER_LIMIT
|
|
&& max_channel >= SECONDARY_CHANNEL_LIMIT)
|
|
|| max_channel >= CHANNEL_LIMIT)
|
|
inverse = 0x000000;
|
|
else
|
|
inverse = 0xffffff;
|
|
|
|
if (reverse) {
|
|
working_rgb = rgb;
|
|
rgb = inverse;
|
|
inverse = working_rgb;
|
|
}
|
|
|
|
if (color >= CLR_MAX) {
|
|
if (color - CLR_MAX >= 5)
|
|
impossible("Changing too many colors");
|
|
else {
|
|
_mt_attrs[color - CLR_MAX][0] = rgb;
|
|
_mt_attrs[color - CLR_MAX][1] = inverse;
|
|
_attrs_inverse[color - CLR_MAX] = reverse;
|
|
}
|
|
} else if (color >= 0) {
|
|
_mt_colors[color][0] = rgb;
|
|
_mt_colors[color][1] = inverse;
|
|
_colors_inverse[color] = reverse;
|
|
} else
|
|
impossible("Changing negative color");
|
|
}
|
|
|
|
void
|
|
tty_change_background(int white_or_black)
|
|
{
|
|
register int i;
|
|
|
|
for (i = 0; i < CLR_MAX; i++) {
|
|
if (white_or_black)
|
|
_mt_colors[i][1] = 0xffffff; /* white */
|
|
else
|
|
_mt_colors[i][1] = 0x000000; /* black */
|
|
}
|
|
|
|
/* special cases */
|
|
if (white_or_black) {
|
|
_mt_colors[CLR_BLACK][1] =
|
|
0x808080; /* differentiate black from no color */
|
|
_mt_colors[CLR_WHITE][1] =
|
|
0x505050; /* highlight white with grey background */
|
|
_mt_colors[CLR_YELLOW][1] =
|
|
0x606060; /* highlight yellow with grey background */
|
|
_mt_colors[CLR_BLUE][0] = 0x000088; /* make pure blue */
|
|
_mt_colors[NO_COLOR][0] = 0x000000; /* make no_color black on white */
|
|
_mt_attrs[0][0] = 0x000000; /* "normal" is black on white */
|
|
_mt_attrs[0][1] = 0xffffff;
|
|
} else {
|
|
_mt_colors[NO_COLOR][0] = 0xffffff; /* make no_color white on black */
|
|
_mt_colors[CLR_BLACK][1] =
|
|
0x808080; /* differentiate black from no color */
|
|
_mt_colors[CLR_BLUE][0] =
|
|
0x222288; /* lighten blue - it's too dark on black */
|
|
_mt_attrs[0][0] = 0xffffff; /* "normal" is white on black */
|
|
_mt_attrs[0][1] = 0x000000;
|
|
}
|
|
}
|
|
|
|
char *
|
|
tty_get_color_string(void)
|
|
{
|
|
char *ptr;
|
|
int count;
|
|
static char color_buf[5 * (CLR_MAX + 5) + 1];
|
|
|
|
color_buf[0] = 0;
|
|
ptr = color_buf;
|
|
|
|
for (count = 0; count < CLR_MAX; count++) {
|
|
int flag = _colors_inverse[count] ? 1 : 0;
|
|
|
|
sprintf(ptr, "%s%s%x%x%x", count ? "/" : "", flag ? "-" : "",
|
|
(int) (_mt_colors[count][flag] >> 20) & 0xf,
|
|
(int) (_mt_colors[count][flag] >> 12) & 0xf,
|
|
(int) (_mt_colors[count][flag] >> 4) & 0xf);
|
|
ptr += strlen(ptr);
|
|
}
|
|
for (count = 0; count < 5; count++) {
|
|
int flag = _attrs_inverse[count] ? 1 : 0;
|
|
|
|
sprintf(ptr, "/%s%x%x%x", flag ? "-" : "",
|
|
(int) (_mt_attrs[count][flag] >> 20) & 0xf,
|
|
(int) (_mt_attrs[count][flag] >> 12) & 0xf,
|
|
(int) (_mt_attrs[count][flag] >> 4) & 0xf);
|
|
ptr += strlen(ptr);
|
|
}
|
|
|
|
return color_buf;
|
|
}
|
|
#endif
|
|
|
|
extern struct DisplayDesc *ttyDisplay; /* the tty display descriptor */
|
|
|
|
char kill_char = CHAR_ESC;
|
|
char erase_char = CHAR_BS;
|
|
|
|
WindowRef _mt_window = (WindowRef) 0;
|
|
static Boolean _mt_in_color = 0;
|
|
extern short win_fonts[NHW_TEXT + 1];
|
|
|
|
static void
|
|
_mt_init_stuff(void)
|
|
{
|
|
long resp, flag;
|
|
short num_cols, num_rows, win_width, win_height, font_num, font_size;
|
|
short char_width, row_height;
|
|
short hor, vert;
|
|
|
|
LI = MT_HEIGHT;
|
|
CO = MT_WIDTH;
|
|
|
|
if (!strcmp(windowprocs.name, "mac")) {
|
|
dprintf("Mac Windows");
|
|
LI -= 1;
|
|
} else {
|
|
dprintf("TTY Windows");
|
|
}
|
|
|
|
/*
|
|
* If there is at least one screen CAPABLE of color, and if
|
|
* 32-bit QD is there, we use color. 32-bit QD is needed for the
|
|
* offscreen GWorld
|
|
*/
|
|
if (!Gestalt(gestaltQuickdrawVersion, &resp) && resp > 0x1ff) {
|
|
GDHandle gdh = GetDeviceList();
|
|
while (gdh) {
|
|
if (TestDeviceAttribute(gdh, screenDevice)) {
|
|
if (HasDepth(gdh, 4, 1, 1) || HasDepth(gdh, 8, 1, 1)
|
|
|| HasDepth(gdh, 16, 1, 1) || HasDepth(gdh, 32, 1, 1)) {
|
|
_mt_in_color = 1;
|
|
break;
|
|
}
|
|
}
|
|
gdh = GetNextDevice(gdh);
|
|
}
|
|
}
|
|
|
|
if (create_tty(&_mt_window, WIN_BASE_KIND + NHW_MAP, _mt_in_color)
|
|
!= noErr)
|
|
error("_mt_init_stuff: Couldn't create tty.");
|
|
SetWindowKind(_mt_window, WIN_BASE_KIND + NHW_MAP);
|
|
SelectWindow(_mt_window);
|
|
SetPortWindowPort(_mt_window);
|
|
SetOrigin(-1, -1);
|
|
|
|
font_size = iflags.wc_fontsiz_map
|
|
? iflags.wc_fontsiz_map
|
|
: (iflags.large_font && !small_screen) ? 12 : 9;
|
|
if (init_tty_number(_mt_window, win_fonts[NHW_MAP], font_size, CO, LI)
|
|
!= noErr)
|
|
error("_mt_init_stuff: Couldn't init tty.");
|
|
|
|
if (get_tty_metrics(_mt_window, &num_cols, &num_rows, &win_width,
|
|
&win_height, &font_num, &font_size, &char_width,
|
|
&row_height))
|
|
error("_mt_init_stuff: Couldn't get tty metrics.");
|
|
|
|
SizeWindow(_mt_window, win_width + 2, win_height + 2, 1);
|
|
if (RetrievePosition(kMapWindow, &vert, &hor)) {
|
|
dprintf("Moving window to (%d,%d)", hor, vert);
|
|
MoveWindow(_mt_window, hor, vert, 1);
|
|
}
|
|
ShowWindow(_mt_window);
|
|
|
|
/* Start in raw, always flushing mode */
|
|
get_tty_attrib(_mt_window, TTY_ATTRIB_FLAGS, &flag);
|
|
flag |= TA_ALWAYS_REFRESH | TA_WRAP_AROUND;
|
|
set_tty_attrib(_mt_window, TTY_ATTRIB_FLAGS, flag);
|
|
|
|
get_tty_attrib(_mt_window, TTY_ATTRIB_CURSOR, &flag);
|
|
flag |= (TA_BLINKING_CURSOR | TA_NL_ADD_CR);
|
|
set_tty_attrib(_mt_window, TTY_ATTRIB_CURSOR, flag);
|
|
|
|
set_tty_attrib(_mt_window, TTY_ATTRIB_FOREGROUND,
|
|
_mt_colors[NO_COLOR][0]);
|
|
set_tty_attrib(_mt_window, TTY_ATTRIB_BACKGROUND,
|
|
_mt_colors[NO_COLOR][1]);
|
|
clear_tty(_mt_window);
|
|
|
|
InitMenuRes();
|
|
|
|
{
|
|
/* update the window proc has_color table */
|
|
int i, setting = 0;
|
|
Rect r;
|
|
// Point p = {0, 0};
|
|
GDHandle gh = (GDHandle) 0;
|
|
|
|
if (_mt_in_color) {
|
|
GetWindowBounds(_mt_window, kWindowContentRgn, &r);
|
|
// SetPortWindowPort(_mt_window);
|
|
// LocalToGlobal (&p);
|
|
// OffsetRect (&r, p.h, p.v);
|
|
gh = GetMaxDevice(&r);
|
|
/* > 4 bpp */
|
|
setting = ((*((*gh)->gdPMap))->pixelSize > 4) ? 1 : 0;
|
|
}
|
|
|
|
for (i = 0; i < CLR_MAX ; ++i) {
|
|
tty_procs.has_color[i] =
|
|
(i == CLR_BLACK || i == NO_COLOR || i == CLR_WHITE)
|
|
? 1
|
|
: (_mt_in_color && gh)
|
|
? setting
|
|
: 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
int
|
|
tgetch(void)
|
|
{
|
|
EventRecord event;
|
|
long sleepTime = 0;
|
|
int ret = 0;
|
|
|
|
for (; !ret;) {
|
|
WaitNextEvent(-1, &event, sleepTime, 0);
|
|
HandleEvent(&event);
|
|
blink_cursor(_mt_window, event.when);
|
|
if (event.what == nullEvent) {
|
|
sleepTime = GetCaretTime();
|
|
} else {
|
|
sleepTime = 0;
|
|
}
|
|
ret = GetFromKeyQueue();
|
|
if (ret == CHAR_CR)
|
|
ret = CHAR_LF;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void
|
|
getreturn(char *str)
|
|
{
|
|
FlushEvents(-1, 0);
|
|
msmsg("Press space %s", str);
|
|
(void) tgetch();
|
|
}
|
|
|
|
#if 0 /* this function is commented out */
|
|
/* the tty has_color[] table is filled in during init above */
|
|
int
|
|
has_color(int color)
|
|
{
|
|
#if defined(__SC__) || defined(__MRC__)
|
|
#pragma unused(color)
|
|
#endif
|
|
Rect r;
|
|
// Point p = {0, 0};
|
|
GDHandle gh;
|
|
|
|
if (!_mt_in_color)
|
|
return 0;
|
|
|
|
GetWindowBounds(_mt_window, kWindowContentRgn, &r);
|
|
// SetPortWindowPort(_mt_window);
|
|
// LocalToGlobal (&p);
|
|
// OffsetRect (&r, p.h, p.v);
|
|
|
|
gh = GetMaxDevice(&r);
|
|
if (!gh) {
|
|
return 0;
|
|
}
|
|
|
|
return (*((*gh)->gdPMap))->pixelSize > 4; /* > 4 bpp */
|
|
}
|
|
#endif
|
|
|
|
void
|
|
tty_delay_output(void)
|
|
{
|
|
EventRecord event;
|
|
long toWhen = TickCount() + 3;
|
|
|
|
while (TickCount() < toWhen) {
|
|
WaitNextEvent(updateMask, &event, 3L, 0);
|
|
if (event.what == updateEvt) {
|
|
HandleEvent(&event);
|
|
blink_cursor(_mt_window, event.when);
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
cmov(int x, int y)
|
|
{
|
|
move_tty_cursor(_mt_window, x, y);
|
|
ttyDisplay->cury = y;
|
|
ttyDisplay->curx = x;
|
|
}
|
|
|
|
void
|
|
nocmov(int x, int y)
|
|
{
|
|
cmov(x, y);
|
|
}
|
|
|
|
static void
|
|
_mt_set_colors(long *colors)
|
|
{
|
|
short err;
|
|
|
|
if (!_mt_in_color) {
|
|
return;
|
|
}
|
|
err = set_tty_attrib(_mt_window, TTY_ATTRIB_FOREGROUND, colors[0]);
|
|
err = set_tty_attrib(_mt_window, TTY_ATTRIB_BACKGROUND, colors[1]);
|
|
}
|
|
|
|
int
|
|
term_attr_fixup(int attrmask)
|
|
{
|
|
attrmask &= ~ATR_DIM;
|
|
return attrmask;
|
|
}
|
|
|
|
void
|
|
term_end_attr(int attr)
|
|
{
|
|
#if defined(__SC__) || defined(__MRC__)
|
|
#pragma unused(attr)
|
|
#endif
|
|
_mt_set_colors(_mt_attrs[0]);
|
|
}
|
|
|
|
void
|
|
term_start_attr(int attr)
|
|
{
|
|
switch (attr) {
|
|
case ATR_ULINE:
|
|
_mt_set_colors(_mt_attrs[1]);
|
|
break;
|
|
case ATR_BOLD:
|
|
_mt_set_colors(_mt_attrs[2]);
|
|
break;
|
|
case ATR_BLINK:
|
|
_mt_set_colors(_mt_attrs[3]);
|
|
break;
|
|
case ATR_INVERSE:
|
|
_mt_set_colors(_mt_attrs[4]);
|
|
break;
|
|
default:
|
|
_mt_set_colors(_mt_attrs[0]);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
standoutend(void)
|
|
{
|
|
term_end_attr(ATR_INVERSE);
|
|
}
|
|
|
|
void
|
|
standoutbeg(void)
|
|
{
|
|
term_start_attr(ATR_INVERSE);
|
|
}
|
|
|
|
void
|
|
term_end_color(void)
|
|
{
|
|
_mt_set_colors(_mt_colors[NO_COLOR]);
|
|
}
|
|
|
|
void
|
|
cl_end(void)
|
|
{
|
|
_mt_set_colors(_mt_attrs[0]);
|
|
clear_tty_window(_mt_window, ttyDisplay->curx, ttyDisplay->cury, CO - 1,
|
|
ttyDisplay->cury);
|
|
}
|
|
|
|
void
|
|
clear_screen(void)
|
|
{
|
|
_mt_set_colors(_mt_attrs[0]);
|
|
clear_tty(_mt_window);
|
|
}
|
|
|
|
void
|
|
cl_eos(void)
|
|
{
|
|
_mt_set_colors(_mt_attrs[0]);
|
|
clear_tty_window(_mt_window, ttyDisplay->curx, ttyDisplay->cury, CO - 1,
|
|
LI - 1);
|
|
}
|
|
|
|
void
|
|
home(void)
|
|
{
|
|
cmov(0, 0);
|
|
}
|
|
|
|
void
|
|
backsp(void)
|
|
{
|
|
char eraser[] = { CHAR_BS, CHAR_BLANK, CHAR_BS, 0 };
|
|
short err;
|
|
|
|
err = add_tty_string(_mt_window, eraser);
|
|
err = update_tty(_mt_window);
|
|
}
|
|
|
|
void
|
|
msmsg(const char *str, ...)
|
|
{
|
|
va_list args;
|
|
char buf[1000];
|
|
|
|
va_start(args, str);
|
|
vsprintf(buf, str, args);
|
|
va_end(args);
|
|
|
|
xputs(buf);
|
|
}
|
|
|
|
void
|
|
term_end_raw_bold(void)
|
|
{
|
|
term_end_attr(ATR_INVERSE);
|
|
}
|
|
|
|
void
|
|
term_start_raw_bold(void)
|
|
{
|
|
term_start_attr(ATR_INVERSE);
|
|
}
|
|
|
|
void
|
|
term_start_color(int color)
|
|
{
|
|
if (color >= 0 && color < CLR_MAX) {
|
|
_mt_set_colors(_mt_colors[color]);
|
|
}
|
|
}
|
|
|
|
void
|
|
setftty(void)
|
|
{
|
|
long flag;
|
|
|
|
/* Buffered output for the game */
|
|
get_tty_attrib(_mt_window, TTY_ATTRIB_FLAGS, &flag);
|
|
flag &= ~TA_ALWAYS_REFRESH;
|
|
flag |= TA_INHIBIT_VERT_SCROLL; /* don't scroll */
|
|
set_tty_attrib(_mt_window, TTY_ATTRIB_FLAGS, flag);
|
|
iflags.cbreak = 1;
|
|
}
|
|
|
|
void
|
|
term_startup(int *width, int *height)
|
|
{
|
|
_mt_init_stuff();
|
|
*width = CO;
|
|
*height = LI;
|
|
}
|
|
|
|
void
|
|
gettty(void)
|
|
{
|
|
}
|
|
|
|
void
|
|
settty(const char *str)
|
|
{
|
|
long flag;
|
|
|
|
update_tty(_mt_window);
|
|
|
|
/* Buffered output for the game, raw in "raw" mode */
|
|
get_tty_attrib(_mt_window, TTY_ATTRIB_FLAGS, &flag);
|
|
flag &= ~TA_INHIBIT_VERT_SCROLL; /* scroll */
|
|
flag |= TA_ALWAYS_REFRESH;
|
|
set_tty_attrib(_mt_window, TTY_ATTRIB_FLAGS, flag);
|
|
|
|
tty_raw_print("\n");
|
|
if (str) {
|
|
tty_raw_print(str);
|
|
}
|
|
}
|
|
|
|
void
|
|
tty_number_pad(int arg)
|
|
{
|
|
#if defined(__SC__) || defined(__MRC__)
|
|
#pragma unused(arg)
|
|
#endif
|
|
}
|
|
|
|
void
|
|
term_start_screen(void)
|
|
{
|
|
iflags.cbreak = 1;
|
|
}
|
|
|
|
void
|
|
term_end_screen(void)
|
|
{
|
|
}
|
|
|
|
void
|
|
xputs(const char *str)
|
|
{
|
|
add_tty_string(_mt_window, str);
|
|
}
|
|
|
|
int
|
|
term_puts(const char *str)
|
|
{
|
|
xputs(str);
|
|
return strlen(str);
|
|
}
|
|
|
|
int
|
|
term_putc(int c)
|
|
{
|
|
short err;
|
|
|
|
err = add_tty_char(_mt_window, c);
|
|
return err ? EOF : c;
|
|
}
|
|
|
|
int
|
|
term_flush(void *desc)
|
|
{
|
|
if (desc == stdout || desc == stderr) {
|
|
update_tty(_mt_window);
|
|
} else {
|
|
impossible("Substituted flush for file");
|
|
return fflush(desc);
|
|
}
|
|
return 0;
|
|
}
|