fix github issue 361 to make user_sounds useful even if MSGTYPE is hidden

fixes #361

Also, experminental introduction of vt_sounddata to enable tty to pass
a sound file index to the terminal side of things where perhaps someone
can add code to something like hterm to take the information relayed by
NetHack to trigger user_sounds locally even if playing on a server.

Compile time option TTY_SOUND_ESCCODES required to build that support in.

It should be independent of TTY_TILE_ESCCODES.
This commit is contained in:
nhmall
2020-07-02 15:49:45 -04:00
parent 3a94f0a9f8
commit e4b18f0545
13 changed files with 151 additions and 32 deletions
+3
View File
@@ -114,6 +114,9 @@ preload_tiles control whether tiles get pre-loaded into RAM at [TRUE]
Boolean option if TTY_TILES_ESCCODES was set at compile time (tty only): Boolean option if TTY_TILES_ESCCODES was set at compile time (tty only):
vt_tiledata insert extra data escape code markers into output [FALSE] vt_tiledata insert extra data escape code markers into output [FALSE]
Boolean option if TTY_SOUND_ESCCODES was set at compile time (tty only):
vt_sounddata insert sound data escape code markers into output [FALSE]
Any Boolean option can be negated by prefixing it with a '!' or 'no'. Any Boolean option can be negated by prefixing it with a '!' or 'no'.
+3 -1
View File
@@ -35,7 +35,7 @@
.ds vr "NetHack 3.7 .ds vr "NetHack 3.7
.ds f0 "\*(vr .ds f0 "\*(vr
.ds f1 .ds f1
.ds f2 "June 20, 2020 .ds f2 "July 2, 2020
. .
.\" A note on some special characters: .\" A note on some special characters:
.\" \(lq = left double quote .\" \(lq = left double quote
@@ -4662,6 +4662,8 @@ the pattern to match;
the sound file to play; the sound file to play;
.PL volume .PL volume
the volume to be set while playing the sound file. the volume to be set while playing the sound file.
.PL "vt_sounddata index"
optional - the index corresponding to a sound file;
.PE .PE
.lp "" .lp ""
The pattern should be a POSIX extended regular expression. The pattern should be a POSIX extended regular expression.
+2 -1
View File
@@ -45,7 +45,7 @@
%.au %.au
\author{Original version - Eric S. Raymond\\ \author{Original version - Eric S. Raymond\\
(Edited and expanded for 3.7 by Mike Stephenson and others)} (Edited and expanded for 3.7 by Mike Stephenson and others)}
\date{June 20, 2020} \date{July 2, 2020}
\maketitle \maketitle
@@ -5110,6 +5110,7 @@ Each SOUND entry is broken down into the following parts:
{\tt pattern } --- the pattern to match;\\ {\tt pattern } --- the pattern to match;\\
{\tt sound file} --- the sound file to play;\\ {\tt sound file} --- the sound file to play;\\
{\tt volume } --- the volume to be set while playing the sound file. {\tt volume } --- the volume to be set while playing the sound file.
{\tt sound index } --- optional - the index corresponding to a sound file.
%.ei %.ei
%.ed %.ed
\elist \elist
+9
View File
@@ -298,6 +298,10 @@ Unix: when user name is used as default character name, keep hyphenated value
intact instead stripping off dash and whatever follows as if that intact instead stripping off dash and whatever follows as if that
specified role/race/&c (worked once upon a time; broken since 3.3.0) specified role/race/&c (worked once upon a time; broken since 3.3.0)
Unix: add "ec2-user" to the list of user names 'sysconf' classifies as generic Unix: add "ec2-user" to the list of user names 'sysconf' classifies as generic
user_sounds: move the message hook from inside individual window display ports
to the core where it allows MSGTYP_NOSHOW msgtyp's to still trigger
sounds to correct a reported github issue; also fixes a past reported
issue that the curses port on Windows not working with user_sounds
Windows: update for new status condition fields Windows: update for new status condition fields
Windows: include commented-out 'PORTABLE_DEVICE_PATHS' in sysconf.template Windows: include commented-out 'PORTABLE_DEVICE_PATHS' in sysconf.template
X11: substantial overhaul of status display, both 'fancy' and 'tty-style' X11: substantial overhaul of status display, both 'fancy' and 'tty-style'
@@ -384,6 +388,11 @@ record number of wishes and artifact wishes in xlogfile
Platform- and/or Interface-Specific New Features Platform- and/or Interface-Specific New Features
------------------------------------------------ ------------------------------------------------
user_sounds: provide an experimental mechanism for terminal-side sounds similar
to the method used for vt_tiledata; new option vt_sounddata that also
requires compile-time definition of TTY_SOUND_ESCCODES (also requires
terminal-side code external to NetHack to recognize the sequence and
act on it
NetHack Community Patches (or Variation) Included NetHack Community Patches (or Variation) Included
+9 -3
View File
@@ -474,7 +474,10 @@ typedef unsigned char uchar;
*/ */
/* TTY_TILES_ESCCODES: Enable output of special console escape codes /* TTY_TILES_ESCCODES: Enable output of special console escape codes
* which act as hints for external programs such as EbonHack. * which act as hints for external programs such as EbonHack, or hterm.
*
* TTY_SOUND_ESCCODES: Enable output of special console escape codes
* which act as hints for theoretical external programs to play sound effect.
* *
* Only for TTY_GRAPHICS. * Only for TTY_GRAPHICS.
* *
@@ -482,12 +485,14 @@ typedef unsigned char uchar;
* one or more positive integer values, separated by semicolons. * one or more positive integer values, separated by semicolons.
* For example ESC [ 1 ; 0 ; 120 z * For example ESC [ 1 ; 0 ; 120 z
* *
* Possible codes are: * Possible TTY_TILES_ESCCODES codes are:
* ESC [ 1 ; 0 ; n ; m z Start a glyph (aka a tile) number n, with flags m * ESC [ 1 ; 0 ; n ; m z Start a glyph (aka a tile) number n, with flags m
* ESC [ 1 ; 1 z End a glyph. * ESC [ 1 ; 1 z End a glyph.
* ESC [ 1 ; 2 ; n z Select a window n to output to. * ESC [ 1 ; 2 ; n z Select a window n to output to.
* ESC [ 1 ; 3 z End of data. NetHack has finished sending data, * ESC [ 1 ; 3 z End of data. NetHack has finished sending data,
* and is waiting for input. * and is waiting for input.
* Possible TTY_SOUND_ESCCODES codes are:
* ESC [ 1 ; 4 ; n ; m z Play specified sound n, volume m
* *
* Whenever NetHack outputs anything, it will first output the "select window" * Whenever NetHack outputs anything, it will first output the "select window"
* code. Whenever NetHack outputs a tile, it will first output the "start * code. Whenever NetHack outputs a tile, it will first output the "start
@@ -496,9 +501,10 @@ typedef unsigned char uchar;
* *
* To compile NetHack with this, add tile.c to WINSRC and tile.o to WINOBJ * To compile NetHack with this, add tile.c to WINSRC and tile.o to WINOBJ
* in the hints file or Makefile. * in the hints file or Makefile.
* Set boolean option vt_tiledata in your config file to turn this on. * Set boolean option vt_xdata in your config file to turn either of these on.
* Note that gnome-terminal at least doesn't work with this. */ * Note that gnome-terminal at least doesn't work with this. */
/* #define TTY_TILES_ESCCODES */ /* #define TTY_TILES_ESCCODES */
/* #define TTY_SOUND_ESCCODES */
/* NetHack will execute an external program whenever a new message-window /* NetHack will execute an external program whenever a new message-window
* message is shown. The program to execute is given in environment variable * message is shown. The program to execute is given in environment variable
+3
View File
@@ -326,6 +326,9 @@ struct instance_flags {
#endif #endif
#ifdef TTY_TILES_ESCCODES #ifdef TTY_TILES_ESCCODES
boolean vt_tiledata; /* output console codes for tile support in TTY */ boolean vt_tiledata; /* output console codes for tile support in TTY */
#endif
#ifdef TTY_SOUND_ESCCODES
boolean vt_sounddata; /* output console codes for sound support in TTY*/
#endif #endif
boolean clicklook; /* allow right-clicking for look */ boolean clicklook; /* allow right-clicking for look */
boolean cmdassist; /* provide detailed assistance for some comnds */ boolean cmdassist; /* provide detailed assistance for some comnds */
+1
View File
@@ -29,6 +29,7 @@
#define DUMPLOG_MSG_COUNT 50 #define DUMPLOG_MSG_COUNT 50
#define USER_SOUNDS #define USER_SOUNDS
#define TTY_SOUND_ESCCODES
/*#define CHANGE_COLOR*/ /* allow palette changes */ /*#define CHANGE_COLOR*/ /* allow palette changes */
#define SELECTSAVED /* Provide menu of saved games to choose from at start */ #define SELECTSAVED /* Provide menu of saved games to choose from at start */
+7
View File
@@ -516,6 +516,13 @@ pfx_##a,
#else #else
NHOPTB(vt_tiledata, 0, opt_in, set_in_config, Off, Yes, No, No, NoAlias, NHOPTB(vt_tiledata, 0, opt_in, set_in_config, Off, Yes, No, No, NoAlias,
(boolean *) 0) (boolean *) 0)
#endif
#ifdef TTY_SOUND_ESCCODES
NHOPTB(vt_sounddata, 0, opt_in, set_in_config, Off, Yes, No, No, NoAlias,
&iflags.vt_sounddata)
#else
NHOPTB(vt_sounddata, 0, opt_in, set_in_config, Off, Yes, No, No, NoAlias,
(boolean *) 0)
#endif #endif
NHOPTC(warnings, 10, opt_in, set_in_config, No, Yes, No, No, NoAlias, NHOPTC(warnings, 10, opt_in, set_in_config, No, Yes, No, No, NoAlias,
"display characters for warnings") "display characters for warnings")
+8 -2
View File
@@ -15,7 +15,9 @@ static char *FDECL(You_buf, (int));
#if defined(MSGHANDLER) && (defined(POSIX_TYPES) || defined(__GNUC__)) #if defined(MSGHANDLER) && (defined(POSIX_TYPES) || defined(__GNUC__))
static void FDECL(execplinehandler, (const char *)); static void FDECL(execplinehandler, (const char *));
#endif #endif
#ifdef USER_SOUNDS
extern void FDECL(maybe_play_sound, (const char *));
#endif
#ifdef DUMPLOG #ifdef DUMPLOG
/* keep the most recent DUMPLOG_MSG_COUNT messages */ /* keep the most recent DUMPLOG_MSG_COUNT messages */
@@ -163,6 +165,7 @@ VA_DECL(const char *, line)
pbuf[BUFSZ - 1] = '\0'; pbuf[BUFSZ - 1] = '\0';
line = pbuf; line = pbuf;
} }
msgtyp = MSGTYP_NORMAL;
#ifdef DUMPLOG #ifdef DUMPLOG
/* We hook here early to have options-agnostic output. /* We hook here early to have options-agnostic output.
@@ -182,10 +185,13 @@ VA_DECL(const char *, line)
goto pline_done; goto pline_done;
} }
msgtyp = MSGTYP_NORMAL;
no_repeat = (g.pline_flags & PLINE_NOREPEAT) ? TRUE : FALSE; no_repeat = (g.pline_flags & PLINE_NOREPEAT) ? TRUE : FALSE;
if ((g.pline_flags & OVERRIDE_MSGTYPE) == 0) { if ((g.pline_flags & OVERRIDE_MSGTYPE) == 0) {
msgtyp = msgtype_type(line, no_repeat); msgtyp = msgtype_type(line, no_repeat);
#ifdef USER_SOUNDS
if (msgtyp == MSGTYP_NORMAL || msgtyp == MSGTYP_NOSHOW)
maybe_play_sound(line);
#endif
if ((g.pline_flags & URGENT_MESSAGE) == 0 if ((g.pline_flags & URGENT_MESSAGE) == 0
&& (msgtyp == MSGTYP_NOSHOW && (msgtyp == MSGTYP_NOSHOW
|| (msgtyp == MSGTYP_NOREP && !strcmp(line, g.prevmsg)))) || (msgtyp == MSGTYP_NOREP && !strcmp(line, g.prevmsg))))
+60 -12
View File
@@ -1258,16 +1258,23 @@ tiphat()
#ifdef USER_SOUNDS #ifdef USER_SOUNDS
#if defined(WIN32) || defined(QT_GRAPHICS)
extern void FDECL(play_usersound, (const char *, int)); extern void FDECL(play_usersound, (const char *, int));
#endif
#if defined(TTY_SOUND_ESCCODES)
extern void FDECL(play_usersound_via_idx, (int, int));
#endif
typedef struct audio_mapping_rec { typedef struct audio_mapping_rec {
struct nhregex *regex; struct nhregex *regex;
char *filename; char *filename;
int volume; int volume;
int idx;
struct audio_mapping_rec *next; struct audio_mapping_rec *next;
} audio_mapping; } audio_mapping;
static audio_mapping *soundmap = 0; static audio_mapping *soundmap = 0;
static audio_mapping *FDECL(sound_matches_message, (const char *));
char *sounddir = 0; /* set in files.c */ char *sounddir = 0; /* set in files.c */
@@ -1279,26 +1286,29 @@ const char *mapping;
char text[256]; char text[256];
char filename[256]; char filename[256];
char filespec[256]; char filespec[256];
int volume; int volume, idx = -1;
boolean toolong = FALSE;
if (sscanf(mapping, "MESG \"%255[^\"]\"%*[\t ]\"%255[^\"]\" %d", text, if (sscanf(mapping, "MESG \"%255[^\"]\"%*[\t ]\"%255[^\"]\" %d %d", text,
filename, &volume, &idx) == 4
|| sscanf(mapping, "MESG \"%255[^\"]\"%*[\t ]\"%255[^\"]\" %d", text,
filename, &volume) == 3) { filename, &volume) == 3) {
audio_mapping *new_map; audio_mapping *new_map;
if (!sounddir) if (!sounddir)
sounddir = dupstr("."); sounddir = dupstr(".");
if (strlen(sounddir) + 1 + strlen(filename) >= sizeof filespec) { if (strlen(sounddir) + 1 + strlen(filename) >= sizeof filespec) {
raw_print("sound file name too long"); raw_print("sound file name too long");
return 0; return 0;
} }
Sprintf(filespec, "%s/%s", sounddir, filename); Sprintf(filespec, "%s/%s", sounddir, filename);
if (can_read_file(filespec)) { if (idx >= 0 || can_read_file(filespec)) {
new_map = (audio_mapping *) alloc(sizeof *new_map); new_map = (audio_mapping *) alloc(sizeof *new_map);
new_map->regex = regex_init(); new_map->regex = regex_init();
new_map->filename = dupstr(filespec); new_map->filename = dupstr(filespec);
new_map->volume = volume; new_map->volume = volume;
new_map->idx = idx;
new_map->next = soundmap; new_map->next = soundmap;
if (!regex_compile(text, new_map->regex)) { if (!regex_compile(text, new_map->regex)) {
@@ -1325,18 +1335,56 @@ const char *mapping;
return 1; return 1;
} }
static audio_mapping *
sound_matches_message(msg)
const char *msg;
{
audio_mapping *snd = soundmap;
while (snd) {
if (regex_match(msg, snd->regex))
return snd;
snd = snd->next;
}
return (audio_mapping *) 0;
}
void void
play_sound_for_message(msg) play_sound_for_message(msg)
const char *msg; const char *msg;
{ {
audio_mapping *cursor = soundmap; audio_mapping *snd = sound_matches_message(msg);
while (cursor) { if (snd)
if (regex_match(msg, cursor->regex)) { play_usersound(snd->filename, snd->volume);
play_usersound(cursor->filename, cursor->volume); }
}
cursor = cursor->next; void
} maybe_play_sound(msg)
const char *msg;
{
#if defined(WIN32) || defined(QT_GRAPHICS) || defined(TTY_SOUND_ESCCODES)
audio_mapping *snd = sound_matches_message(msg);
if (snd
#if defined(WIN32) || defined(QT_GRAPHICS)
#ifdef TTY_SOUND_ESCCODES
&& !iflags.vt_sounddata
#endif
#if defined(QT_GRAPHICS)
&& WINDOWPORT("Qt")
#endif
#if defined(WIN32)
&& (WINDOWPORT("tty") || WINDOWPORT("mswin") || WINDOWPORT("curses"))
#endif
#endif /* WIN32 || QT_GRAPHICS */
)
play_usersound(snd->filename, snd->volume);
#if defined(TTY_GRAPHICS) && defined(TTY_SOUND_ESCCODES)
else if (snd && iflags.vt_sounddata && snd->idx >= 0 && WINDOWPORT("tty"))
play_usersound_via_idx(snd->idx, snd->volume);
#endif /* TTY_GRAPHICS && TTY_SOUND_ESCCODES */
#endif /* WIN32 || QT_GRAPHICS || TTY_SOUND_ESCCODES */
} }
void void
+9
View File
@@ -189,4 +189,13 @@ set_altkeyhandler(const char *inName)
{ {
return; return;
} }
#if defined(USER_SOUNDS) && defined(TTY_SOUND_ESCCODES)
void
play_usersound_via_idx(idx, volume)
int idx, volume;
{
}
#endif /* USER_SOUNDS && TTY_SOUND_ESCCODES */
#endif /* TTYSTUBS */ #endif /* TTYSTUBS */
-4
View File
@@ -103,10 +103,6 @@ const char * NetHackQtMessageWindow::GetStr(bool init)
void NetHackQtMessageWindow::PutStr(int attr, const QString& text) void NetHackQtMessageWindow::PutStr(int attr, const QString& text)
{ {
#ifdef USER_SOUNDS
play_sound_for_message(text.toLatin1().constData());
#endif
changed=true; changed=true;
// If the line is output from the "/" command, map the first character // If the line is output from the "/" command, map the first character
+37 -9
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 wintty.c $NHDT-Date: 1587110794 2020/04/17 08:06:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.256 $ */ /* NetHack 3.6 wintty.c $NHDT-Date: 1587110794 2020/04/17 08:06:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.256 $ */
/* Copyright (c) David Cohrs, 1991 */ /* Copyright (c) David Cohrs, 1991 */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -36,14 +36,19 @@ extern void msmsg(const char *, ...);
#endif #endif
#endif #endif
#if defined(TTY_TILES_ESCCODES) || defined(TTY_SOUND_ESCCODES)
#define VT_ANSI_COMMAND 'z'
#endif
#ifdef TTY_TILES_ESCCODES #ifdef TTY_TILES_ESCCODES
extern short glyph2tile[]; extern short glyph2tile[];
#define TILE_ANSI_COMMAND 'z'
#define AVTC_GLYPH_START 0 #define AVTC_GLYPH_START 0
#define AVTC_GLYPH_END 1 #define AVTC_GLYPH_END 1
#define AVTC_SELECT_WINDOW 2 #define AVTC_SELECT_WINDOW 2
#define AVTC_INLINE_SYNC 3 #define AVTC_INLINE_SYNC 3
#endif #endif
#ifdef TTY_SOUND_ESCCODES
#define AVTC_SOUND_PLAY 4
#endif
#ifdef HANGUP_HANDLING #ifdef HANGUP_HANDLING
/* /*
@@ -244,11 +249,11 @@ int i, c, d;
vt_tile_current_window = c; vt_tile_current_window = c;
} }
if (d >= 0) if (d >= 0)
printf("\033[1;%d;%d;%d%c", i, c, d, TILE_ANSI_COMMAND); printf("\033[1;%d;%d;%d%c", i, c, d, VT_ANSI_COMMAND);
else else
printf("\033[1;%d;%d%c", i, c, TILE_ANSI_COMMAND); printf("\033[1;%d;%d%c", i, c, VT_ANSI_COMMAND);
} else { } else {
printf("\033[1;%d%c", i, TILE_ANSI_COMMAND); printf("\033[1;%d%c", i, VT_ANSI_COMMAND);
} }
} }
} }
@@ -259,6 +264,24 @@ int i, c, d;
#define print_vt_code2(i,c) print_vt_code((i), (c), -1) #define print_vt_code2(i,c) print_vt_code((i), (c), -1)
#define print_vt_code3(i,c,d) print_vt_code((i), (c), (d)) #define print_vt_code3(i,c,d) print_vt_code((i), (c), (d))
#ifdef TTY_SOUND_ESCCODES
void
print_vt_soundcode_idx(idx, v)
int idx, v;
{
HUPSKIP();
if (iflags.vt_sounddata) {
if (v >= 0)
printf("\033[1;%d;%d;%d%c", AVTC_SOUND_PLAY,
idx, v, VT_ANSI_COMMAND);
else
printf("\033[1;%d;%d%c", AVTC_SOUND_PLAY,
idx, VT_ANSI_COMMAND);
}
}
#else
# define print_vt_soundcode_idx(idx, v) ;
#endif /* !TTY_SOUND_ESCCODES */
/* clean up and quit */ /* clean up and quit */
static void static void
@@ -2678,10 +2701,6 @@ const char *str;
messages, clear flag mask leaving only display attr */ messages, clear flag mask leaving only display attr */
/*attr &= ~(ATR_URGENT | ATR_NOHISTORY);*/ /*attr &= ~(ATR_URGENT | ATR_NOHISTORY);*/
/* really do this later */
#if defined(USER_SOUNDS) && defined(WIN32CON)
play_sound_for_message(str);
#endif
if (!suppress_history) { if (!suppress_history) {
/* normal output; add to current top line if room, else flush /* normal output; add to current top line if room, else flush
whatever is there to history and then write this */ whatever is there to history and then write this */
@@ -4634,6 +4653,15 @@ render_status(VOID_ARGS)
#endif /* STATUS_HILITES */ #endif /* STATUS_HILITES */
#if defined(USER_SOUNDS) && defined(TTY_SOUND_ESCCODES)
void
play_usersound_via_idx(idx, volume)
int idx, volume;
{
print_vt_soundcode_idx(idx, volume);
}
#endif /* USER_SOUNDS && TTY_SOUND_ESCCODES */
#endif /* TTY_GRAPHICS */ #endif /* TTY_GRAPHICS */
/*wintty.c*/ /*wintty.c*/