has_color() performance fixes

Performance profiling showed that multiple strcmpi() calls were
occurring each and every time a character was going to the map.

This update:
- honors the WC_COLOR capability
- It allows a window-port to control individual color availability should the window-port wish to do so.
- Makes checking on the individual colors for the active window-port is a straightforward table lookup at the CLR_ offset.

iflags.use_color remains a master on/off switch for use of color, regardless of the capability
compiled into the game (default TRUE).

The has_color() routine, which is now a shared routine in src/windows.c, could likely be made
into a simple macro to eliminate the function call, but this update does not go that far.

This hits a lot of port files due to the window-port interface change, mostly cookie-cutter.
This commit is contained in:
nhmall
2019-11-30 11:44:07 -05:00
parent 49e4dfbc0f
commit 42a13a1198
18 changed files with 62 additions and 24 deletions
+1
View File
@@ -14,6 +14,7 @@ struct window_procs {
* '+' are reserved for processors. */ * '+' are reserved for processors. */
unsigned long wincap; /* window port capability options supported */ unsigned long wincap; /* window port capability options supported */
unsigned long wincap2; /* additional window port capability options */ unsigned long wincap2; /* additional window port capability options */
boolean has_color[CLR_MAX];
void FDECL((*win_init_nhwindows), (int *, char **)); void FDECL((*win_init_nhwindows), (int *, char **));
void NDECL((*win_player_selection)); void NDECL((*win_player_selection));
void NDECL((*win_askname)); void NDECL((*win_askname));
+1 -6
View File
@@ -245,16 +245,11 @@ unsigned mgflags;
#ifdef TEXTCOLOR #ifdef TEXTCOLOR
/* Turn off color if no color defined, or rogue level w/o PC graphics. */ /* Turn off color if no color defined, or rogue level w/o PC graphics. */
if (!has_color(color) || (Is_rogue_level(&u.uz) && !has_rogue_color)) if (!has_color(color) || (Is_rogue_level(&u.uz) && !has_rogue_color))
color = NO_COLOR;
#endif #endif
color = NO_COLOR;
*ochar = (int) ch; *ochar = (int) ch;
*ospecial = special; *ospecial = special;
#ifdef TEXTCOLOR
*ocolor = color; *ocolor = color;
#else
nhUse(ocolor);
#endif
return idx; return idx;
} }
+1 -5
View File
@@ -106,11 +106,7 @@ static struct Bool_Opt {
#endif #endif
{ "clicklook", &iflags.clicklook, FALSE, SET_IN_GAME }, { "clicklook", &iflags.clicklook, FALSE, SET_IN_GAME },
{ "cmdassist", &iflags.cmdassist, TRUE, SET_IN_GAME }, { "cmdassist", &iflags.cmdassist, TRUE, SET_IN_GAME },
#if defined(MICRO) || defined(WIN32) || defined(CURSES_GRAPHICS) { "color", &iflags.wc_color, TRUE, SET_IN_GAME }, /* on/off: use WC or not */
{ "color", &iflags.wc_color, TRUE, SET_IN_GAME }, /*WC*/
#else /* systems that support multiple terminals, many monochrome */
{ "color", &iflags.wc_color, FALSE, SET_IN_GAME }, /*WC*/
#endif
{ "confirm", &flags.confirm, TRUE, SET_IN_GAME }, { "confirm", &flags.confirm, TRUE, SET_IN_GAME },
{ "dark_room", &flags.dark_room, TRUE, SET_IN_GAME }, { "dark_room", &flags.dark_room, TRUE, SET_IN_GAME },
{ "eight_bit_tty", &iflags.wc_eight_bit_input, FALSE, SET_IN_GAME }, /*WC*/ { "eight_bit_tty", &iflags.wc_eight_bit_input, FALSE, SET_IN_GAME }, /*WC*/
+27 -1
View File
@@ -525,7 +525,9 @@ static void FDECL(hup_void_fdecl_winid, (winid));
static void FDECL(hup_void_fdecl_constchar_p, (const char *)); static void FDECL(hup_void_fdecl_constchar_p, (const char *));
static struct window_procs hup_procs = { static struct window_procs hup_procs = {
"hup", 0L, 0L, hup_init_nhwindows, "hup", 0L, 0L,
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
hup_init_nhwindows,
hup_void_ndecl, /* player_selection */ hup_void_ndecl, /* player_selection */
hup_void_ndecl, /* askname */ hup_void_ndecl, /* askname */
hup_void_ndecl, /* get_nh_event */ hup_void_ndecl, /* get_nh_event */
@@ -1373,4 +1375,28 @@ boolean onoff_flag;
} }
} }
#ifdef TTY_GRAPHICS
#ifdef TEXTCOLOR
#ifdef TOS
extern const char *hilites[CLR_MAX];
#else
extern NEARDATA char *hilites[CLR_MAX];
#endif
#endif
#endif
int
has_color(color)
int color;
{
return (iflags.use_color && windowprocs.name
&& (windowprocs.wincap & WC_COLOR) && windowprocs.has_color[color]
#ifdef TTY_GRAPHICS
#if defined(TEXTCOLOR) && defined(TERMLIB) && !defined(NO_TERMS)
&& (hilites[color] != 0)
#endif
#endif
);
}
/*windows.c*/ /*windows.c*/
+6 -2
View File
@@ -28,7 +28,9 @@ long amii_scrnmode;
* the intuition interface for the amiga... * the intuition interface for the amiga...
*/ */
struct window_procs amii_procs = { struct window_procs amii_procs = {
"amii", WC_COLOR | WC_HILITE_PET | WC_INVERSE, 0L, amii_init_nhwindows, "amii", WC_COLOR | WC_HILITE_PET | WC_INVERSE,
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */
0L, amii_init_nhwindows,
amii_player_selection, amii_askname, amii_get_nh_event, amii_player_selection, amii_askname, amii_get_nh_event,
amii_exit_nhwindows, amii_suspend_nhwindows, amii_resume_nhwindows, amii_exit_nhwindows, amii_suspend_nhwindows, amii_resume_nhwindows,
amii_create_nhwindow, amii_clear_nhwindow, amii_display_nhwindow, amii_create_nhwindow, amii_clear_nhwindow, amii_display_nhwindow,
@@ -60,7 +62,9 @@ struct window_procs amii_procs = {
* a shared library to allow the executable to be smaller. * a shared library to allow the executable to be smaller.
*/ */
struct window_procs amiv_procs = { struct window_procs amiv_procs = {
"amitile", WC_COLOR | WC_HILITE_PET | WC_INVERSE, 0L, amii_init_nhwindows, "amitile", WC_COLOR | WC_HILITE_PET | WC_INVERSE,
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */
0L, amii_init_nhwindows,
amii_player_selection, amii_askname, amii_get_nh_event, amii_player_selection, amii_askname, amii_get_nh_event,
amii_exit_nhwindows, amii_suspend_nhwindows, amii_resume_nhwindows, amii_exit_nhwindows, amii_suspend_nhwindows, amii_resume_nhwindows,
amii_create_nhwindow, amii_clear_nhwindow, amii_display_nhwindow, amii_create_nhwindow, amii_clear_nhwindow, amii_display_nhwindow,
+3 -1
View File
@@ -3251,7 +3251,9 @@ struct window_procs mac_procs = {
WC_COLOR | WC_HILITE_PET | WC_FONT_MAP | WC_FONT_MENU | WC_FONT_MESSAGE WC_COLOR | WC_HILITE_PET | WC_FONT_MAP | WC_FONT_MENU | WC_FONT_MESSAGE
| WC_FONT_STATUS | WC_FONT_TEXT | WC_FONTSIZ_MAP | WC_FONTSIZ_MENU | WC_FONT_STATUS | WC_FONT_TEXT | WC_FONTSIZ_MAP | WC_FONTSIZ_MENU
| WC_FONTSIZ_MESSAGE | WC_FONTSIZ_STATUS | WC_FONTSIZ_TEXT, | WC_FONTSIZ_MESSAGE | WC_FONTSIZ_STATUS | WC_FONTSIZ_TEXT,
0L, mac_init_nhwindows, 0L,
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */
mac_init_nhwindows,
mac_unimplemented, /* see macmenu.c:mac_askname() for player selection */ mac_unimplemented, /* see macmenu.c:mac_askname() for player selection */
mac_askname, mac_get_nh_event, mac_exit_nhwindows, mac_suspend_nhwindows, mac_askname, mac_get_nh_event, mac_exit_nhwindows, mac_suspend_nhwindows,
mac_unimplemented, mac_create_nhwindow, mac_clear_nhwindow, mac_unimplemented, mac_create_nhwindow, mac_clear_nhwindow,
+1
View File
@@ -50,6 +50,7 @@ struct window_procs mswin_procs = {
| WC_TILE_WIDTH | WC_TILE_HEIGHT | WC_TILE_FILE | WC_VARY_MSGCOUNT | WC_TILE_WIDTH | WC_TILE_HEIGHT | WC_TILE_FILE | WC_VARY_MSGCOUNT
| WC_WINDOWCOLORS | WC_PLAYER_SELECTION, | WC_WINDOWCOLORS | WC_PLAYER_SELECTION,
WC2_FULLSCREEN | WC2_SOFTKEYBOARD | WC2_WRAPTEXT, mswin_init_nhwindows, WC2_FULLSCREEN | WC2_SOFTKEYBOARD | WC2_WRAPTEXT, mswin_init_nhwindows,
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */
mswin_player_selection, mswin_askname, mswin_get_nh_event, mswin_player_selection, mswin_askname, mswin_get_nh_event,
mswin_exit_nhwindows, mswin_suspend_nhwindows, mswin_resume_nhwindows, mswin_exit_nhwindows, mswin_suspend_nhwindows, mswin_resume_nhwindows,
mswin_create_nhwindow, mswin_clear_nhwindow, mswin_display_nhwindow, mswin_create_nhwindow, mswin_clear_nhwindow, mswin_display_nhwindow,
+2
View File
@@ -790,6 +790,7 @@ init_ttycolor()
} }
#endif /* TEXTCOLOR */ #endif /* TEXTCOLOR */
#if 0
int int
has_color(int color) has_color(int color)
{ {
@@ -803,6 +804,7 @@ has_color(int color)
else else
return 0; return 0;
} }
#endif
int int
term_attr_fixup(int attrmask) term_attr_fixup(int attrmask)
-6
View File
@@ -114,12 +114,6 @@ backsp()
return; return;
} }
int
has_color(int color)
{
return 1;
}
#ifndef NO_MOUSE_ALLOWED #ifndef NO_MOUSE_ALLOWED
void void
toggle_mouse_support() toggle_mouse_support()
+1
View File
@@ -5229,6 +5229,7 @@ struct window_procs Qt_procs = {
WC_FONT_MAP|WC_TILE_FILE|WC_TILE_WIDTH|WC_TILE_HEIGHT| WC_FONT_MAP|WC_TILE_FILE|WC_TILE_WIDTH|WC_TILE_HEIGHT|
WC_PLAYER_SELECTION|WC_SPLASH_SCREEN, WC_PLAYER_SELECTION|WC_SPLASH_SCREEN,
0L, 0L,
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */
NetHackQtBind::qt_init_nhwindows, NetHackQtBind::qt_init_nhwindows,
NetHackQtBind::qt_player_selection, NetHackQtBind::qt_player_selection,
NetHackQtBind::qt_askname, NetHackQtBind::qt_askname,
+1
View File
@@ -730,6 +730,7 @@ struct window_procs Qt_procs = {
| WC_FONT_MAP | WC_TILE_FILE | WC_TILE_WIDTH | WC_TILE_HEIGHT | WC_FONT_MAP | WC_TILE_FILE | WC_TILE_WIDTH | WC_TILE_HEIGHT
| WC_PLAYER_SELECTION | WC_SPLASH_SCREEN, | WC_PLAYER_SELECTION | WC_SPLASH_SCREEN,
0L, 0L,
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */
nethack_qt4::NetHackQtBind::qt_init_nhwindows, nethack_qt4::NetHackQtBind::qt_init_nhwindows,
nethack_qt4::NetHackQtBind::qt_player_selection, nethack_qt4::NetHackQtBind::qt_player_selection,
nethack_qt4::NetHackQtBind::qt_askname, nethack_qt4::NetHackQtBind::qt_askname,
+1
View File
@@ -107,6 +107,7 @@ struct window_procs X11_procs = {
WC2_FLUSH_STATUS | WC2_RESET_STATUS | WC2_HILITE_STATUS | WC2_FLUSH_STATUS | WC2_RESET_STATUS | WC2_HILITE_STATUS |
#endif #endif
0L, 0L,
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */
X11_init_nhwindows, X11_init_nhwindows,
X11_player_selection, X11_askname, X11_get_nh_event, X11_exit_nhwindows, X11_player_selection, X11_askname, X11_get_nh_event, X11_exit_nhwindows,
X11_suspend_nhwindows, X11_resume_nhwindows, X11_create_nhwindow, X11_suspend_nhwindows, X11_resume_nhwindows, X11_create_nhwindow,
+1
View File
@@ -51,6 +51,7 @@ struct window_procs curses_procs = {
| WC2_FLUSH_STATUS | WC2_TERM_SIZE | WC2_FLUSH_STATUS | WC2_TERM_SIZE
| WC2_STATUSLINES | WC2_WINDOWBORDERS | WC2_PETATTR | WC2_GUICOLOR | WC2_STATUSLINES | WC2_WINDOWBORDERS | WC2_PETATTR | WC2_GUICOLOR
| WC2_SUPPRESS_HIST), | WC2_SUPPRESS_HIST),
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */
curses_init_nhwindows, curses_init_nhwindows,
curses_player_selection, curses_player_selection,
curses_askname, curses_askname,
+3 -1
View File
@@ -43,7 +43,9 @@ struct window_procs Gem_procs = {
| WC_FONT_TEXT | WC_FONT_MAP | WC_FONTSIZ_MESSAGE | WC_FONTSIZ_STATUS | WC_FONT_TEXT | WC_FONT_MAP | WC_FONTSIZ_MESSAGE | WC_FONTSIZ_STATUS
| WC_FONTSIZ_MENU | WC_FONTSIZ_TEXT | WC_FONTSIZ_MAP | WC_TILE_WIDTH | WC_FONTSIZ_MENU | WC_FONTSIZ_TEXT | WC_FONTSIZ_MAP | WC_TILE_WIDTH
| WC_TILE_HEIGHT | WC_TILE_FILE | WC_VARY_MSGCOUNT | WC_ASCII_MAP, | WC_TILE_HEIGHT | WC_TILE_FILE | WC_VARY_MSGCOUNT | WC_ASCII_MAP,
0L, Gem_init_nhwindows, Gem_player_selection, Gem_askname, 0L,
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */
Gem_init_nhwindows, Gem_player_selection, Gem_askname,
Gem_get_nh_event, Gem_exit_nhwindows, Gem_suspend_nhwindows, Gem_get_nh_event, Gem_exit_nhwindows, Gem_suspend_nhwindows,
Gem_resume_nhwindows, Gem_create_nhwindow, Gem_clear_nhwindow, Gem_resume_nhwindows, Gem_create_nhwindow, Gem_clear_nhwindow,
Gem_display_nhwindow, Gem_destroy_nhwindow, Gem_curs, Gem_putstr, Gem_display_nhwindow, Gem_destroy_nhwindow, Gem_curs, Gem_putstr,
+3 -1
View File
@@ -24,7 +24,9 @@ extern NEARDATA winid WIN_STATUS;
/* Interface definition, for windows.c */ /* Interface definition, for windows.c */
struct window_procs Gnome_procs = { struct window_procs Gnome_procs = {
"Gnome", WC_COLOR | WC_HILITE_PET | WC_INVERSE, 0L, gnome_init_nhwindows, "Gnome", WC_COLOR | WC_HILITE_PET | WC_INVERSE, 0L,
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */
gnome_init_nhwindows,
gnome_player_selection, gnome_askname, gnome_get_nh_event, gnome_player_selection, gnome_askname, gnome_get_nh_event,
gnome_exit_nhwindows, gnome_suspend_nhwindows, gnome_resume_nhwindows, gnome_exit_nhwindows, gnome_suspend_nhwindows, gnome_resume_nhwindows,
gnome_create_nhwindow, gnome_clear_nhwindow, gnome_display_nhwindow, gnome_create_nhwindow, gnome_clear_nhwindow, gnome_display_nhwindow,
+1
View File
@@ -67,6 +67,7 @@
struct window_procs safe_procs = { struct window_procs safe_procs = {
"safe-startup", 0L, 0L, "safe-startup", 0L, 0L,
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */
safe_init_nhwindows, safe_player_selection, safe_askname, safe_get_nh_event, safe_init_nhwindows, safe_player_selection, safe_askname, safe_get_nh_event,
safe_exit_nhwindows, safe_suspend_nhwindows, safe_resume_nhwindows, safe_exit_nhwindows, safe_suspend_nhwindows, safe_resume_nhwindows,
safe_create_nhwindow, safe_clear_nhwindow, safe_display_nhwindow, safe_create_nhwindow, safe_clear_nhwindow, safe_display_nhwindow,
+4 -1
View File
@@ -1282,6 +1282,9 @@ int color;
xputs(hilites[color]); xputs(hilites[color]);
} }
#if 0
/* Replaced by src/windows.c general proc or a macro in 3.6.3 */
/* not to be confused with has_colors() in unixtty.c */ /* not to be confused with has_colors() in unixtty.c */
int int
has_color(color) has_color(color)
@@ -1316,7 +1319,7 @@ int color;
return hilites[color] != (char *) 0; return hilites[color] != (char *) 0;
#endif #endif
} }
#endif /* 0 */
#endif /* TEXTCOLOR */ #endif /* TEXTCOLOR */
#endif /* TTY_GRAPHICS && !NO_TERMS */ #endif /* TTY_GRAPHICS && !NO_TERMS */
+5
View File
@@ -97,6 +97,11 @@ struct window_procs tty_procs = {
| WC2_RESET_STATUS | WC2_RESET_STATUS
#endif #endif
| WC2_DARKGRAY | WC2_SUPPRESS_HIST | WC2_STATUSLINES), | WC2_DARKGRAY | WC2_SUPPRESS_HIST | WC2_STATUSLINES),
#ifdef TEXTCOLOR
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */
#else
{1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1},
#endif
tty_init_nhwindows, tty_player_selection, tty_askname, tty_get_nh_event, tty_init_nhwindows, tty_player_selection, tty_askname, tty_get_nh_event,
tty_exit_nhwindows, tty_suspend_nhwindows, tty_resume_nhwindows, tty_exit_nhwindows, tty_suspend_nhwindows, tty_resume_nhwindows,
tty_create_nhwindow, tty_clear_nhwindow, tty_display_nhwindow, tty_create_nhwindow, tty_clear_nhwindow, tty_display_nhwindow,