Source:NetHack 3.3.0/music.c

Below is the full text to music.c from the source code of NetHack 3.3.0. To link to a particular line, write [[NetHack 3.3.0/music.c#line123 ]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

1.   /*	SCCS Id: @(#)music.c	3.3	1999/08/19	*/ 2.   /*	Copyright (c) 1989 by Jean-Christophe Collet */ 3.   /* NetHack may be freely redistributed. See license for details. */ 4.     5.    /*  6.     * This file contains the different functions designed to manipulate the 7.    * musical instruments and their various effects. 8.    *  9.     * Actually the list of instruments / effects is : 10.   *  11.    * (wooden) flute	may calm snakes if player has enough dexterity 12.   * magic flute		may put monsters to sleep:  area of effect depends 13.   *			on player level. 14.   * (tooled) horn	Will awaken monsters:  area of effect depends on player 15.   *			level. May also scare monsters. 16.   * fire horn		Acts like a wand of fire. 17.   * frost horn		Acts like a wand of cold. 18.   * bugle		Will awaken soldiers (if any):  area of effect depends 19.   *			on player level. 20.   * (wooden) harp	May calm nymph if player has enough dexterity. 21.   * magic harp		Charm monsters:  area of effect depends on player 22.   *			level. 23.   * (leather) drum	Will awaken monsters like the horn. 24.   * drum of earthquake	Will initiate an earthquake whose intensity depends 25.   *			on player level. That is, it creates random pits 26.   *			called here chasms. 27.   */  28.    29.   #include "hack.h"  30. 31.  STATIC_DCL void FDECL(awaken_monsters,(int)); 32.  STATIC_DCL void FDECL(put_monsters_to_sleep,(int)); 33.  STATIC_DCL void FDECL(charm_snakes,(int)); 34.  STATIC_DCL void FDECL(calm_nymphs,(int)); 35.  STATIC_DCL void FDECL(charm_monsters,(int)); 36.  STATIC_DCL void FDECL(do_earthquake,(int)); 37.  STATIC_DCL int FDECL(do_improvisation,(struct obj *)); 38.   39.   #ifdef UNIX386MUSIC 40.  STATIC_DCL int NDECL(atconsole); 41.  STATIC_DCL void FDECL(speaker,(struct obj *,char *)); 42.  #endif 43.  #ifdef VPIX_MUSIC 44.  extern int sco_flag_console;	/* will need changing if not _M_UNIX */ 45.  STATIC_DCL void NDECL(playinit); 46.  STATIC_DCL void FDECL(playstring, (char *,size_t)); 47.  STATIC_DCL void FDECL(speaker,(struct obj *,char *)); 48.  #endif 49.  #ifdef PCMUSIC 50.  void FDECL( pc_speaker, ( struct obj *, char * ) ); 51.  #endif 52.  #ifdef AMIGA 53.  void FDECL( amii_speaker, ( struct obj *, char *, int ) ); 54.  #endif 55.   56.   /*  57.    * Wake every monster in range...  58. */ 59.    60.   STATIC_OVL void 61.  awaken_monsters(distance) 62.  int distance; 63.  {  64.   	register struct monst *mtmp = fmon; 65.  	register int distm; 66.   67.   	while(mtmp) { 68.  		distm = distu(mtmp->mx, mtmp->my); 69.  		if (distm < distance) { 70.  		    mtmp->msleeping = 0; 71.  		    mtmp->mcanmove = 1; 72.  		    mtmp->mfrozen = 0; 73.  		    /* May scare some monsters */ 74.  		    if (distm < distance/3 &&  75.   			    !resist(mtmp, SCROLL_CLASS, 0, NOTELL)) 76.  			mtmp->mflee = 1; 77.  		}  78.   		mtmp = mtmp->nmon; 79.  	}  80.   }  81.    82.   /*  83.    * Make monsters fall asleep. Note that they may resist the spell. 84.   */  85.    86.   STATIC_OVL void 87.  put_monsters_to_sleep(distance) 88.  int distance; 89.  {  90.   	register struct monst *mtmp = fmon; 91.   92.   	while(mtmp) { 93.  		if (distu(mtmp->mx, mtmp->my) < distance &&  94.   			sleep_monst(mtmp, d(10,10), WAND_CLASS)) { 95.  		    mtmp->msleeping = 1; /* 10d10 turns + wake_nearby to rouse */ 96.  		    slept_monst(mtmp); 97.  		}  98.   		mtmp = mtmp->nmon; 99.  	}  100.  }  101.   102.  /*  103.   * Charm snakes in range. Note that the snakes are NOT tamed. 104.  */  105.   106.  STATIC_OVL void 107. charm_snakes(distance) 108. int distance; 109. {  110.  	register struct monst *mtmp = fmon; 111. 	int could_see_mon, was_peaceful; 112.  113.  	while (mtmp) { 114. 	    if (mtmp->data->mlet == S_SNAKE && mtmp->mcanmove &&  115.  		    distu(mtmp->mx, mtmp->my) < distance) { 116. 		was_peaceful = mtmp->mpeaceful; 117. 		mtmp->mpeaceful = 1; 118. 		could_see_mon = canseemon(mtmp); 119. 		mtmp->mundetected = 0; 120. 		newsym(mtmp->mx, mtmp->my); 121. 		if (canseemon(mtmp)) { 122. 		    if (!could_see_mon) 123. 			You("notice %s, swaying with the music.",  124.  			    an(mon_nam(mtmp))); 125. 		    else 126. 			pline("%s freezes, then sways with the music%s.",  127.  			      Monnam(mtmp),  128.  			      was_peaceful ? "" : ", and now seems quieter"); 129. 		}  130.  	    }  131.  	    mtmp = mtmp->nmon; 132. 	}  133.  }  134.   135.  /*  136.   * Calm nymphs in range. 137.  */  138.   139.  STATIC_OVL void 140. calm_nymphs(distance) 141. int distance; 142. {  143.  	register struct monst *mtmp = fmon; 144.  145.  	while (mtmp) { 146. 	    if (mtmp->data->mlet == S_NYMPH && mtmp->mcanmove &&  147.  		    distu(mtmp->mx, mtmp->my) < distance) { 148. 		mtmp->msleeping = 0; 149. 		mtmp->mpeaceful = 1; 150. 		if (canseemon(mtmp)) 151. 		    pline(  152.  		     "%s listens cheerfully to the music, then seems quieter.",  153.  			  Monnam(mtmp)); 154. 	    }  155.  	    mtmp = mtmp->nmon; 156. 	}  157.  }  158.   159.  /* Awake only soldiers of the level. */ 160.   161.  void 162. awaken_soldiers 163. {  164.  	register struct monst *mtmp = fmon; 165.  166.  	while(mtmp) { 167. 	    if (is_mercenary(mtmp->data) && mtmp->data != &mons[PM_GUARD]) { 168. 		mtmp->mpeaceful = mtmp->msleeping = mtmp->mfrozen = 0; 169. 		mtmp->mcanmove = 1; 170. 		if (canseemon(mtmp)) 171. 		    pline("%s is now ready for battle!", Monnam(mtmp)); 172. 		else 173. 		    Norep("You hear the rattle of battle gear being readied."); 174. 	    }  175.  	    mtmp = mtmp->nmon; 176. 	}  177.  }  178.   179.  /* Charm monsters in range. Note that they may resist the spell. */ 180.   181.  STATIC_OVL void 182. charm_monsters(distance) 183. int distance; 184. {  185.  	register struct monst *mtmp = fmon, *mtmp2; 186.  187.  	while(mtmp) { 188. 		mtmp2 = mtmp->nmon; 189. 		if (distu(mtmp->mx, mtmp->my) <= distance) 190. 		    if(!resist(mtmp, SCROLL_CLASS, 0, NOTELL)) 191. 			(void) tamedog(mtmp, (struct obj *) 0); 192. 		mtmp = mtmp2; 193. 	}  194.   195.  }  196.   197.  /* Generate earthquake :-) of desired force.  198.   * That is:  create random chasms (pits).  199.   */  200.   201.  STATIC_OVL void  202.  do_earthquake(force)  203.  int force;  204.  {  205.  	register int x,y;  206.  	struct monst *mtmp;  207.  	struct obj *otmp;  208.  	struct trap *chasm;  209.  	int start_x, start_y, end_x, end_y;  210.   211.  	start_x = u.ux - (force * 2);  212.  	start_y = u.uy - (force * 2);  213.  	end_x = u.ux + (force * 2);  214.  	end_y = u.uy + (force * 2);  215.  	if (start_x < 1) start_x = 1;  216.  	if (start_y < 1) start_y = 1;  217.  	if (end_x >= COLNO) end_x = COLNO - 1;  218.  	if (end_y >= ROWNO) end_y = ROWNO - 1;  219.  	for (x=start_x; x<=end_x; x++) for (y=start_y; y<=end_y; y++) {  220.  	    if ((mtmp = m_at(x,y)) != 0) {  221.  		wakeup(mtmp);	/* peaceful monster will become hostile */  222.  		if (mtmp->mundetected && is_hider(mtmp->data)) { 223. 		    mtmp->mundetected = 0; 224. 		    if (cansee(x,y)) 225. 			pline("%s is shaken loose from the ceiling!",  226.  							    Amonnam(mtmp)); 227. 		    else 228. 			You_hear("a thumping sound."); 229. 		    if (x==u.ux && y==u.uy) 230. 			You("easily dodge the falling %s.",  231.  							    mon_nam(mtmp)); 232. 		    newsym(x,y); 233. 		}  234.  	    }  235.  	    if (!rn2(14 - force)) switch (levl[x][y].typ) { 236. 		  case FOUNTAIN : /* Make the fountain disappear */ 237. 			if (cansee(x,y)) 238. 				pline_The("fountain falls into a chasm."); 239. 			goto do_pit; 240. #ifdef SINKS 241. 		  case SINK : 242. 			if (cansee(x,y)) 243. 				pline_The("kitchen sink falls into a chasm."); 244. 			goto do_pit; 245. #endif 246. 		  case ALTAR : 247. 			if (Is_astralevel(&u.uz) || Is_sanctum(&u.uz)) break; 248.  249.  			if (cansee(x,y)) 250. 				pline_The("altar falls into a chasm."); 251. 			goto do_pit; 252. 		  case GRAVE : 253. 			if (cansee(x,y)) 254. 				pline("The headstone topples into a chasm."); 255. 			goto do_pit; 256. 		  case THRONE : 257. 			if (cansee(x,y)) 258. 				pline_The("throne falls into a chasm."); 259. 			/* Falls into next case */ 260. 		  case ROOM : 261. 		  case CORR : /* Try to make a pit */ 262. do_pit:		    chasm = maketrap(x,y,PIT); 263. 		    if (!chasm) break;	/* no pit if portal at that location */ 264. 		    chasm->tseen = 1; 265.  266.  		    levl[x][y].doormask = 0; 267.  268.  		    mtmp = m_at(x,y); 269.  270.  		    if ((otmp = sobj_at(BOULDER, x, y)) != 0) { 271. 			if (cansee(x, y)) 272. 			   pline("KADOOM! The boulder falls into a chasm%s!",  273.  			      ((x == u.ux) && (y == u.uy)) ? " below you" : ""); 274. 			if (mtmp) 275. 				mtmp->mtrapped = 0; 276. 			obj_extract_self(otmp); 277. 			(void) flooreffects(otmp, x, y, ""); 278. 			break; 279. 		    }  280.   281.  		    /* We have to check whether monsters or player 282. 		       falls in a chasm... */ 283.   284.  		    if (mtmp) { 285. 			if(!is_flyer(mtmp->data) && !is_clinger(mtmp->data)) { 286. 			    mtmp->mtrapped = 1; 287. 			    if(cansee(x,y)) 288. 				pline("%s falls into a chasm!", Monnam(mtmp)); 289. 			    else if (flags.soundok && humanoid(mtmp->data)) 290. 				You_hear("a scream!"); 291. 			    mselftouch(mtmp, "Falling, ", TRUE); 292. 			    if (mtmp->mhp > 0) 293. 				if ((mtmp->mhp -= rnd(6)) <= 0) { 294. 				    if(!cansee(x,y)) 295. 					pline("It is destroyed!"); 296. 				    else { 297. 					You("destroy %s!", mtmp->mtame ?  298.  					    x_monnam(mtmp, 0, "poor", 0) :  299.  					    mon_nam(mtmp)); 300. 				    }  301.  				    xkilled(mtmp,0); 302. 				}  303.  			}  304.  		    } else if (x == u.ux && y == u.uy) { 305. 			    if (Levitation || Flying ||  306.  						is_clinger(youmonst.data)) { 307. 				    pline("A chasm opens up under you!"); 308. 				    You("don't fall in!"); 309. 			    } else { 310. 				    You("fall into a chasm!"); 311. 				    u.utrap = rn1(6,2); 312. 				    u.utraptype = TT_PIT; 313. 				    losehp(rnd(6),"fell into a chasm",  314.  					NO_KILLER_PREFIX); 315. 				    selftouch("Falling, you"); 316. 			    }  317.  		    } else newsym(x,y); 318. 		    break; 319. 		  case DOOR : /* Make the door collapse */ 320. 		    if (levl[x][y].doormask == D_NODOOR) goto do_pit; 321. 		    if (cansee(x,y)) 322. 			pline_The("door collapses."); 323. 		    if (*in_rooms(x, y, SHOPBASE)) 324. 			add_damage(x, y, 0L); 325. 		    levl[x][y].doormask = D_NODOOR; 326. 		    newsym(x,y); 327. 		    break; 328. 	    }  329.  	}  330.  }  331.   332.  /*  333.   * The player is trying to extract something from his/her instrument. 334.  */  335.   336.  STATIC_OVL int 337. do_improvisation(instr) 338. struct obj *instr; 339. {  340.  	int damage, do_spec = !Confusion; 341. #if defined(MAC) || defined(AMIGA) || defined(VPIX_MUSIC) || defined (PCMUSIC) 342. 	struct obj itmp; 343.  344.  	itmp = *instr; 345. 	/* if won't yield special effect, make sound of mundane counterpart */ 346. 	if (!do_spec || instr->spe <= 0) 347. 	    while (objects[itmp.otyp].oc_magic) itmp.otyp -= 1; 348. # ifdef MAC 349. 	mac_speaker(&itmp, "C"); 350. # endif 351. # ifdef AMIGA 352. 	amii_speaker(&itmp, "Cw", AMII_OKAY_VOLUME); 353. # endif 354. # ifdef VPIX_MUSIC 355. 	if (sco_flag_console) 356. 	    speaker(&itmp, "C"); 357. # endif 358. #ifdef PCMUSIC 359. 	  pc_speaker ( &itmp, "C"); 360. #endif 361. #endif /* MAC || AMIGA || VPIX_MUSIC || PCMUSIC */ 362.  363.  	if (!do_spec) 364. 	    pline("What you produce is quite far from music..."); 365. 	else 366. 	    You("start playing %s.", the(xname(instr))); 367.  368.  	switch (instr->otyp) { 369. 	case MAGIC_FLUTE:		/* Make monster fall asleep */ 370. 	    if (do_spec && instr->spe > 0) { 371. 		check_unpaid(instr); 372. 		instr->spe--; 373. 		You("produce soft music."); 374. 		put_monsters_to_sleep(u.ulevel * 5); 375. 		exercise(A_DEX, TRUE); 376. 		break; 377. 	    } /* else FALLTHRU */ 378. 	case WOODEN_FLUTE:		/* May charm snakes */ 379. 	    do_spec &= (rn2(ACURR(A_DEX)) + u.ulevel > 25); 380. 	    pline("%s %s.", The(xname(instr)),  381.  		  do_spec ? "trills" : "toots"); 382. 	    if (do_spec) charm_snakes(u.ulevel * 3); 383. 	    exercise(A_DEX, TRUE); 384. 	    break; 385. 	case FROST_HORN:		/* Idem wand of cold */ 386. 	case FIRE_HORN:			/* Idem wand of fire */ 387. 	    if (do_spec && instr->spe > 0) { 388. 		check_unpaid(instr); 389. 		instr->spe--; 390. 		if (!getdir((char *)0)) { 391. 		    pline("%s vibrates.", The(xname(instr))); 392. 		    break; 393. 		} else if (!u.dx && !u.dy && !u.dz) { 394. 		    if ((damage = zapyourself(instr, TRUE)) != 0) 395. 			losehp(damage,  396.  			       self_pronoun("using a magical horn on %sself", 397. 					    "him"),  398.  			       NO_KILLER_PREFIX); 399. 		} else { 400. 		    buzz((instr->otyp == FROST_HORN) ? AD_COLD-1 : AD_FIRE-1,  401.  			 rn1(6,6), u.ux, u.uy, u.dx, u.dy); 402. 		}  403.  		makeknown(instr->otyp); 404. 		break; 405. 	    } /* else FALLTHRU */ 406. 	case TOOLED_HORN:		/* Awaken or scare monsters */ 407. 	    You("produce a frightful, grave sound."); 408. 	    awaken_monsters(u.ulevel * 30); 409. 	    exercise(A_WIS, FALSE); 410. 	    break; 411. 	case BUGLE:			/* Awaken & attract soldiers */ 412. 	    You("extract a loud noise from %s.", the(xname(instr))); 413. 	    awaken_soldiers; 414. 	    exercise(A_WIS, FALSE); 415. 	    break; 416. 	case MAGIC_HARP:		/* Charm monsters */ 417. 	    if (do_spec && instr->spe > 0) { 418. 		check_unpaid(instr); 419. 		instr->spe--; 420. 		pline("%s produces very attractive music.",  421.  		      The(xname(instr))); 422. 		charm_monsters((u.ulevel - 1) / 3 + 1); 423. 		exercise(A_DEX, TRUE); 424. 		break; 425. 	    } /* else FALLTHRU */ 426. 	case WOODEN_HARP:		/* May calm Nymph */ 427. 	    do_spec &= (rn2(ACURR(A_DEX)) + u.ulevel > 25); 428. 	    pline("%s %s.", The(xname(instr)),  429.  		  do_spec ? "produces a lilting melody" : "twangs"); 430. 	    if (do_spec) calm_nymphs(u.ulevel * 3); 431. 	    exercise(A_DEX, TRUE); 432. 	    break; 433. 	case DRUM_OF_EARTHQUAKE:	/* create several pits */ 434. 	    if (do_spec && instr->spe > 0) { 435. 		check_unpaid(instr); 436. 		instr->spe--; 437. 		You("produce a heavy, thunderous rolling!"); 438. 		pline_The("entire dungeon is shaking around you!"); 439. 		do_earthquake((u.ulevel - 1) / 3 + 1); 440. 		/* shake up monsters in a much larger radius... */ 441.  		awaken_monsters(ROWNO * COLNO); 442. 		makeknown(DRUM_OF_EARTHQUAKE); 443. 		break; 444. 	    } /* else FALLTHRU */ 445. 	case LEATHER_DRUM:		/* Awaken monsters */ 446. 	    You("beat a deafening row!"); 447. 	    awaken_monsters(u.ulevel * 40); 448. 	    exercise(A_WIS, FALSE); 449. 	    break; 450. 	default: 451. 	    impossible("What a weird instrument (%d)!", instr->otyp); 452. 	    break; 453. 	}  454.  	return 2;		/* That takes time */ 455. }  456.   457.  /*  458.   * So you want music...  459. */ 460.   461.  int 462. do_play_instrument(instr) 463. struct obj *instr; 464. {  465.      char buf[BUFSZ], c = 'y'; 466. #ifndef	AMIGA 467. 	char *s; 468. #endif 469.     int x,y; 470.     boolean ok; 471.  472.      if (Underwater) { 473. 	You_cant("play music underwater!"); 474. 	return(0); 475.     }  476.      if (instr->otyp != LEATHER_DRUM && instr->otyp != DRUM_OF_EARTHQUAKE) { 477. 	c = yn("Improvise?"); 478.     }  479.      if (c == 'n') { 480. 	if (u.uevent.uheard_tune == 2 && yn("Play the passtune?") == 'y') 481. 		Strcpy(buf, tune); 482. 	else 483. 		getlin("What tune are you playing? [what 5 notes]", buf); 484. #ifndef	AMIGA 485. 	/* The AMIGA supports two octaves of notes */ 486. 	for (s=buf; *s; s++) *s = highc(*s); 487. #endif 488. 	You("extract a strange sound from %s!", the(xname(instr))); 489. #ifdef UNIX386MUSIC 490. 	/* if user is at the console, play through the console speaker */ 491. 	if (atconsole) 492. 	    speaker(instr, buf); 493. #endif 494. #ifdef VPIX_MUSIC 495. 	if (sco_flag_console) 496. 	    speaker(instr, buf); 497. #endif 498. #ifdef MAC 499. 	mac_speaker ( instr, buf ) ; 500. #endif 501. #ifdef PCMUSIC 502. 	pc_speaker ( instr, buf ); 503. #endif 504. #ifdef AMIGA 505. 	{  506.  		char nbuf[ 20 ]; 507. 		int i;  508. for( i = 0; buf[i] && i < 5; ++i ) 509. 		{  510.  			nbuf[ i*2 ] = buf[ i ]; 511. 			nbuf[ (i*2)+1 ] = 'h'; 512. 		}  513.  		nbuf[ i*2 ] = 0; 514. 		amii_speaker ( instr, nbuf, AMII_OKAY_VOLUME ) ; 515. 	}  516.  #endif 517. 	/* Check if there was the Stronghold drawbridge near 518. 	 * and if the tune conforms to what we're waiting for. 519. 	 */  520.  	if(Is_stronghold(&u.uz)) { 521. 	    exercise(A_WIS, TRUE);		/* just for trying */ 522. 	    if(!strcmp(buf,tune)) { 523. 		/* Search for the drawbridge */ 524. 		for(y=u.uy-1; y<=u.uy+1; y++) 525. 		    for(x=u.ux-1;x<=u.ux+1;x++) 526. 			if(isok(x,y)) 527. 			if(find_drawbridge(&x,&y)) { 528. 			    u.uevent.uheard_tune = 2; /* tune now fully known */ 529. 			    if(levl[x][y].typ == DRAWBRIDGE_DOWN) 530. 				close_drawbridge(x,y); 531. 			    else 532. 				open_drawbridge(x,y); 533. 			    return 0; 534. 			}  535.  	    } else if(flags.soundok) { 536. 		if (u.uevent.uheard_tune < 1) u.uevent.uheard_tune = 1; 537. 		/* Okay, it wasn't the right tune, but perhaps 538. 		 * we can give the player some hints like in the 539. 		 * Mastermind game */ 540. 		ok = FALSE; 541. 		for(y = u.uy-1; y <= u.uy+1 && !ok; y++) 542. 		    for(x = u.ux-1; x <= u.ux+1 && !ok; x++) 543. 			if(isok(x,y)) 544. 			if(IS_DRAWBRIDGE(levl[x][y].typ) ||  545.  			   is_drawbridge_wall(x,y) >= 0) 546. 				ok = TRUE; 547. 		if(ok) { /* There is a drawbridge near */ 548. 		    int tumblers, gears; 549. 		    boolean matched[5]; 550.  551.  		    tumblers = gears = 0; 552. 		    for(x=0; x < 5; x++) 553. 			matched[x] = FALSE; 554.  555.  		    for(x=0; x < (int)strlen(buf); x++) 556. 			if(x < 5) { 557. 			    if(buf[x] == tune[x]) { 558. 				gears++; 559. 				matched[x] = TRUE; 560. 			    } else 561. 				for(y=0; y < 5; y++) 562. 				    if(!matched[y] &&  563.  				       buf[x] == tune[y] &&  564.  				       buf[y] != tune[y]) { 565. 					tumblers++; 566. 					matched[y] = TRUE; 567. 					break; 568. 				    }  569.  			}  570.  		    if(tumblers) 571. 			if(gears) 572. 			    You_hear("%d tumbler%s click and %d gear%s turn.",  573.  				tumblers, plur(tumblers), gears, plur(gears)); 574. 			else 575. 			    You_hear("%d tumbler%s click.",  576.  				tumblers, plur(tumblers)); 577. 		    else if(gears) { 578. 			You_hear("%d gear%s turn.", gears, plur(gears)); 579. 			/* could only get `gears == 5' by playing five 580. 			   correct notes followed by excess; otherwise, 581. 			   tune would have matched above */ 582. 			if (gears == 5) u.uevent.uheard_tune = 2; 583. 		    }  584.  		}  585.  	    }  586.  	  }  587.  	return 1; 588.     } else 589. 	    return do_improvisation(instr); 590. }  591.   592.  #ifdef UNIX386MUSIC 593. /*  594.   * Play audible music on the machine's speaker if appropriate. 595.  */  596.   597.  STATIC_OVL int 598. atconsole 599. {  600.      /*  601.       * Kluge alert: This code assumes that your [34]86 has no X terminals 602.      * attached and that the console tty type is AT386 (this is always true  603.       * under AT&T UNIX for these boxen). The theory here is that your remote 604.      * ttys will have terminal type `ansi' or something else other than 605.      * `AT386' or `xterm'. We'd like to do better than this, but testing 606.      * to see if we're running on the console physical terminal is quite 607.      * difficult given the presence of virtual consoles and other modern 608.      * UNIX impedimenta...  609. */ 610.      char	*termtype = getenv("TERM"); 611.  612.       return(!strcmp(termtype, "AT386") || !strcmp(termtype, "xterm")); 613. }  614.   615.  STATIC_OVL void 616. speaker(instr, buf) 617. struct obj *instr; 618. char	*buf; 619. {  620.      /*  621.       * For this to work, you need to have installed the PD speaker-control 622.      * driver for PC-compatible UNIX boxes that I (esr@snark.thyrsus.com) 623.      * posted to comp.sources.unix in Feb 1990. A copy should be included 624.      * with your nethack distribution. 625.      */  626.      int	fd; 627.  628.      if ((fd = open("/dev/speaker", 1)) != -1) 629.     {  630.  	/* send a prefix to modify instrumental `timbre' */ 631. 	switch (instr->otyp) 632. 	{  633.  	case WOODEN_FLUTE: 634. 	case MAGIC_FLUTE: 635. 	    (void) write(fd, ">ol", 1); /* up one octave & lock */ 636. 	    break; 637. 	case TOOLED_HORN: 638. 	case FROST_HORN: 639. 	case FIRE_HORN: 640. 	    (void) write(fd, "<  660. #include  661. #include  662. # else 663. #define KIOC ('K' << 8) 664. #define KDMKTONE (KIOC | 8) 665. # endif 666.  667.  #define noDEBUG 668.  669.  STATIC_OVL void tone(hz, ticks) 670. /* emit tone of frequency hz for given number of ticks */ 671. unsigned int hz, ticks; 672. {  673.      ioctl(0,KDMKTONE,hz|((ticks*10)<<16)); 674. # ifdef DEBUG 675.     printf("TONE: %6d %6d\n",hz,ticks * 10); 676. # endif 677.     nap(ticks * 10); 678. }  679.   680.  STATIC_OVL void rest(ticks) 681. /* rest for given number of ticks */ 682. int	ticks; 683. {  684.      nap(ticks * 10); 685. # ifdef DEBUG 686.     printf("REST:        %6d\n",ticks * 10); 687. # endif 688. }  689.   690.   691.  #include "interp.c"	/* from snd86unx.shr */ 692.  693.   694.  STATIC_OVL void 695. speaker(instr, buf) 696. struct obj *instr; 697. char	*buf; 698. {  699.      /* emit a prefix to modify instrumental `timbre' */ 700.     playinit; 701.     switch (instr->otyp) 702.     {  703.  	case WOODEN_FLUTE: 704. 	case MAGIC_FLUTE: 705. 	    playstring(">ol", 1); /* up one octave & lock */ 706. 	    break; 707. 	case TOOLED_HORN: 708. 	case FROST_HORN: 709. 	case FIRE_HORN: 710. 	    playstring("<<ol", 2); /* drop two octaves & lock */ 711. 	    break; 712. 	case BUGLE: 713. 	    playstring("ol", 2); /* octave lock */ 714. 	    break; 715. 	case WOODEN_HARP: 716. 	case MAGIC_HARP: 717. 	    playstring("l8mlol", 4); /* fast, legato, octave lock */ 718. 	    break; 719.     }  720.      playstring( buf, strlen(buf)); 721. }  722.   723.  # ifdef DEBUG 724. main(argc,argv) 725. char *argv[]; 726. {  727.      if (argc == 2) { 728. 	playinit; 729. 	playstring(argv[1], strlen(argv[1])); 730.     }  731.  }  732.  # endif 733. #endif	/* VPIX_MUSIC */ 734.  735.  /*music.c*/