Source:NetHack 3.4.0/music.c

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