Below is the full text to src/music.c from NetHack 3.4.3. To link to a particular line, write [[music.c#line123]], for example.
Top of file[]
1. /* SCCS Id: @(#)music.c 3.4 2003/05/25 */ 2. /* Copyright (c) 1989 by Jean-Christophe Collet */ 3. /* NetHack may be freely redistributed. See license for details. */ 4.
| The NetHack General Public License applies to screenshots, source code and other content from NetHack. |
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.
awaken_monsters[]
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.
put_monsters_to_sleep[]
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.
charm_snakes[]
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.
calm_nymphs[]
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.
awaken_soldiers[]
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.
charm_monsters[]
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.
do_earthquake[]
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.
do_improvisation[]
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. consume_obj_charge(instr, TRUE); 388. 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. consume_obj_charge(instr, TRUE); 404. 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, KILLED_BY); 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. consume_obj_charge(instr, TRUE); 434. 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. consume_obj_charge(instr, TRUE); 450. 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.
do_play_instrument[]
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. char *s; 481. int x,y; 482. boolean ok; 483. 484. if (Underwater) { 485. You_cant("play music underwater!"); 486. return(0); 487. } 488. if (instr->otyp != LEATHER_DRUM && instr->otyp != DRUM_OF_EARTHQUAKE) { 489. c = yn("Improvise?"); 490. } 491. if (c == 'n') { 492. if (u.uevent.uheard_tune == 2 && yn("Play the passtune?") == 'y') { 493. Strcpy(buf, tune); 494. } else { 495. getlin("What tune are you playing? [5 notes, A-G]", buf); 496. (void)mungspaces(buf); 497. /* convert to uppercase and change any "H" to the expected "B" */ 498. for (s = buf; *s; s++) { 499. #ifndef AMIGA 500. *s = highc(*s); 501. #else 502. /* The AMIGA supports two octaves of notes */ 503. if (*s == 'h') *s = 'b'; 504. #endif 505. if (*s == 'H') *s = 'B'; 506. } 507. } 508. You("extract a strange sound from %s!", the(xname(instr))); 509. #ifdef UNIX386MUSIC 510. /* if user is at the console, play through the console speaker */ 511. if (atconsole()) 512. speaker(instr, buf); 513. #endif 514. #ifdef VPIX_MUSIC 515. if (sco_flag_console) 516. speaker(instr, buf); 517. #endif 518. #ifdef MAC 519. mac_speaker ( instr , buf ) ; 520. #endif 521. #ifdef PCMUSIC 522. pc_speaker ( instr, buf ); 523. #endif 524. #ifdef AMIGA 525. { 526. char nbuf[ 20 ]; 527. int i; 528. for( i = 0; buf[i] && i < 5; ++i ) 529. { 530. nbuf[ i*2 ] = buf[ i ]; 531. nbuf[ (i*2)+1 ] = 'h'; 532. } 533. nbuf[ i*2 ] = 0; 534. amii_speaker ( instr , nbuf, AMII_OKAY_VOLUME ) ; 535. } 536. #endif 537. /* Check if there was the Stronghold drawbridge near 538. * and if the tune conforms to what we're waiting for. 539. */ 540. if(Is_stronghold(&u.uz)) { 541. exercise(A_WIS, TRUE); /* just for trying */ 542. if(!strcmp(buf,tune)) { 543. /* Search for the drawbridge */ 544. for(y=u.uy-1; y<=u.uy+1; y++) 545. for(x=u.ux-1;x<=u.ux+1;x++) 546. if(isok(x,y)) 547. if(find_drawbridge(&x,&y)) { 548. u.uevent.uheard_tune = 2; /* tune now fully known */ 549. if(levl[x][y].typ == DRAWBRIDGE_DOWN) 550. close_drawbridge(x,y); 551. else 552. open_drawbridge(x,y); 553. return 0; 554. } 555. } else if(flags.soundok) { 556. if (u.uevent.uheard_tune < 1) u.uevent.uheard_tune = 1; 557. /* Okay, it wasn't the right tune, but perhaps 558. * we can give the player some hints like in the 559. * Mastermind game */ 560. ok = FALSE; 561. for(y = u.uy-1; y <= u.uy+1 && !ok; y++) 562. for(x = u.ux-1; x <= u.ux+1 && !ok; x++) 563. if(isok(x,y)) 564. if(IS_DRAWBRIDGE(levl[x][y].typ) || 565. is_drawbridge_wall(x,y) >= 0) 566. ok = TRUE; 567. if(ok) { /* There is a drawbridge near */ 568. int tumblers, gears; 569. boolean matched[5]; 570. 571. tumblers = gears = 0; 572. for(x=0; x < 5; x++) 573. matched[x] = FALSE; 574. 575. for(x=0; x < (int)strlen(buf); x++) 576. if(x < 5) { 577. if(buf[x] == tune[x]) { 578. gears++; 579. matched[x] = TRUE; 580. } else 581. for(y=0; y < 5; y++) 582. if(!matched[y] && 583. buf[x] == tune[y] && 584. buf[y] != tune[y]) { 585. tumblers++; 586. matched[y] = TRUE; 587. break; 588. } 589. } 590. if(tumblers) 591. if(gears) 592. You_hear("%d tumbler%s click and %d gear%s turn.", 593. tumblers, plur(tumblers), gears, plur(gears)); 594. else 595. You_hear("%d tumbler%s click.", 596. tumblers, plur(tumblers)); 597. else if(gears) { 598. You_hear("%d gear%s turn.", gears, plur(gears)); 599. /* could only get `gears == 5' by playing five 600. correct notes followed by excess; otherwise, 601. tune would have matched above */ 602. if (gears == 5) u.uevent.uheard_tune = 2; 603. } 604. } 605. } 606. } 607. return 1; 608. } else 609. return do_improvisation(instr); 610. } 611. 612. #ifdef UNIX386MUSIC
atconsole[]
613. /* 614. * Play audible music on the machine's speaker if appropriate. 615. */ 616. 617. STATIC_OVL int 618. atconsole() 619. { 620. /* 621. * Kluge alert: This code assumes that your [34]86 has no X terminals 622. * attached and that the console tty type is AT386 (this is always true 623. * under AT&T UNIX for these boxen). The theory here is that your remote 624. * ttys will have terminal type `ansi' or something else other than 625. * `AT386' or `xterm'. We'd like to do better than this, but testing 626. * to see if we're running on the console physical terminal is quite 627. * difficult given the presence of virtual consoles and other modern 628. * UNIX impedimenta... 629. */ 630. char *termtype = nh_getenv("TERM"); 631. 632. return(!strcmp(termtype, "AT386") || !strcmp(termtype, "xterm")); 633. } 634.
speaker[]
635. STATIC_OVL void 636. speaker(instr, buf) 637. struct obj *instr; 638. char *buf; 639. { 640. /* 641. * For this to work, you need to have installed the PD speaker-control 642. * driver for PC-compatible UNIX boxes that I (esr@snark.thyrsus.com) 643. * posted to comp.sources.unix in Feb 1990. A copy should be included 644. * with your nethack distribution. 645. */ 646. int fd; 647. 648. if ((fd = open("/dev/speaker", 1)) != -1) 649. { 650. /* send a prefix to modify instrumental `timbre' */ 651. switch (instr->otyp) 652. { 653. case WOODEN_FLUTE: 654. case MAGIC_FLUTE: 655. (void) write(fd, ">ol", 1); /* up one octave & lock */ 656. break; 657. case TOOLED_HORN: 658. case FROST_HORN: 659. case FIRE_HORN: 660. (void) write(fd, "<<ol", 2); /* drop two octaves & lock */ 661. break; 662. case BUGLE: 663. (void) write(fd, "ol", 2); /* octave lock */ 664. break; 665. case WOODEN_HARP: 666. case MAGIC_HARP: 667. (void) write(fd, "l8mlol", 4); /* fast, legato, octave lock */ 668. break; 669. } 670. (void) write(fd, buf, strlen(buf)); 671. (void) close(fd); 672. } 673. } 674. #endif /* UNIX386MUSIC */ 675. 676. #ifdef VPIX_MUSIC 677. 678. # if 0 679. #include <sys/types.h> 680. #include <sys/console.h> 681. #include <sys/vtkd.h> 682. # else 683. #define KIOC ('K' << 8) 684. #define KDMKTONE (KIOC | 8) 685. # endif 686. 687. #define noDEBUG 688. 689. STATIC_OVL void tone(hz, ticks) 690. /* emit tone of frequency hz for given number of ticks */ 691. unsigned int hz, ticks; 692. { 693. ioctl(0,KDMKTONE,hz|((ticks*10)<<16)); 694. # ifdef DEBUG 695. printf("TONE: %6d %6d\n",hz,ticks * 10); 696. # endif 697. nap(ticks * 10); 698. } 699. 700. STATIC_OVL void rest(ticks) 701. /* rest for given number of ticks */ 702. int ticks; 703. { 704. nap(ticks * 10); 705. # ifdef DEBUG 706. printf("REST: %6d\n",ticks * 10); 707. # endif 708. } 709. 710. 711. #include "interp.c" /* from snd86unx.shr */ 712. 713. 714. STATIC_OVL void 715. speaker(instr, buf) 716. struct obj *instr; 717. char *buf; 718. { 719. /* emit a prefix to modify instrumental `timbre' */ 720. playinit(); 721. switch (instr->otyp) 722. { 723. case WOODEN_FLUTE: 724. case MAGIC_FLUTE: 725. playstring(">ol", 1); /* up one octave & lock */ 726. break; 727. case TOOLED_HORN: 728. case FROST_HORN: 729. case FIRE_HORN: 730. playstring("<<ol", 2); /* drop two octaves & lock */ 731. break; 732. case BUGLE: 733. playstring("ol", 2); /* octave lock */ 734. break; 735. case WOODEN_HARP: 736. case MAGIC_HARP: 737. playstring("l8mlol", 4); /* fast, legato, octave lock */ 738. break; 739. } 740. playstring( buf, strlen(buf)); 741. } 742. 743. # ifdef DEBUG 744. main(argc,argv) 745. char *argv[]; 746. { 747. if (argc == 2) { 748. playinit(); 749. playstring(argv[1], strlen(argv[1])); 750. } 751. } 752. # endif 753. #endif /* VPIX_MUSIC */ 754. 755. /*music.c*/