PropertyValue
rdfs:label
  • Source:NetHack 3.2.0/music.c
rdfs:comment
  • Below is the full text to music.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.0/music.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code
dcterms:subject
dbkwik:nethack/property/wikiPageUsesTemplate
abstract
  • Below is the full text to music.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.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.2 96/01/15 */ 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 void FDECL(awaken_monsters,(int)); 32. static void FDECL(put_monsters_to_sleep,(int)); 33. static void FDECL(charm_snakes,(int)); 34. static void FDECL(calm_nymphs,(int)); 35. static void FDECL(charm_monsters,(int)); 36. static void FDECL(do_earthquake,(int)); 37. static int FDECL(do_improvisation,(struct obj *)); 38. 39. #ifdef UNIX386MUSIC 40. static int NDECL(atconsole); 41. static 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 void NDECL(playinit); 46. static void FDECL(playstring, (char *,size_t)); 47. static 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 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->msleep = 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 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->msleep = 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 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 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->msleep = 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->msleep = 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 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 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 (cansee(x,y)) 248. pline_The("altar falls into a chasm."); 249. goto do_pit; 250. case THRONE : 251. if (cansee(x,y)) 252. pline_The("throne falls into a chasm."); 253. /* Falls into next case */ 254. case ROOM : 255. case CORR : /* Try to make a pit */ 256. do_pit: chasm = maketrap(x,y,PIT); 257. if (!chasm) break; /* no pit if portal at that location */ 258. chasm->tseen = 1; 259. 260. levl[x][y].doormask = 0; 261. 262. mtmp = m_at(x,y); 263. 264. if ((otmp = sobj_at(BOULDER, x, y)) != 0) { 265. if (cansee(x, y)) 266. pline("KADOOM! The boulder falls into a chasm%s!", 267. ((x == u.ux) && (y == u.uy)) ? " below you" : ""); 268. if (mtmp) 269. mtmp->mtrapped = 0; 270. obj_extract_self(otmp); 271. (void) flooreffects(otmp, x, y, ""); 272. break; 273. } 274. 275. /* We have to check whether monsters or player 276. falls in a chasm... */ 277. 278. if (mtmp) { 279. if(!is_flyer(mtmp->data) && !is_clinger(mtmp->data)) { 280. mtmp->mtrapped = 1; 281. if(cansee(x,y)) 282. pline("%s falls into a chasm!", Monnam(mtmp)); 283. else if (flags.soundok && humanoid(mtmp->data)) 284. You_hear("a scream!"); 285. mselftouch(mtmp, "Falling, ", TRUE); 286. if (mtmp->mhp > 0) 287. if ((mtmp->mhp -= rnd(6)) <= 0) { 288. if(!cansee(x,y)) 289. pline("It is destroyed!"); 290. else { 291. You("destroy %s!", mtmp->mtame ? 292. x_monnam(mtmp, 0, "poor", 0) : 293. mon_nam(mtmp)); 294. } 295. xkilled(mtmp,0); 296. } 297. } 298. } else if (x == u.ux && y == u.uy) { 299. if (Levitation || is_flyer(uasmon) || 300. is_clinger(uasmon)) { 301. pline("A chasm opens up under you!"); 302. You("don't fall in!"); 303. } else { 304. You("fall into a chasm!"); 305. u.utrap = rn1(6,2); 306. u.utraptype = TT_PIT; 307. losehp(rnd(6),"fell into a chasm", 308. NO_KILLER_PREFIX); 309. selftouch("Falling, you"); 310. } 311. } else newsym(x,y); 312. break; 313. case DOOR : /* Make the door collapse */ 314. if (levl[x][y].doormask == D_NODOOR) goto do_pit; 315. if (cansee(x,y)) 316. pline_The("door collapses."); 317. if (*in_rooms(x, y, SHOPBASE)) 318. add_damage(x, y, 0L); 319. levl[x][y].doormask = D_NODOOR; 320. newsym(x,y); 321. break; 322. } 323. } 324. } 325. 326. /* 327. * The player is trying to extract something from his/her instrument. 328. */ 329. 330. static int 331. do_improvisation(instr) 332. struct obj *instr; 333. { 334. int damage, do_spec = !Confusion; 335. #if defined(MAC) || defined(AMIGA) || defined(VPIX_MUSIC) || defined (PCMUSIC) 336. struct obj itmp; 337. 338. itmp = *instr; 339. /* if won't yield special effect, make sound of mundane counterpart */ 340. if (!do_spec || instr->spe <= 0) 341. while (objects[itmp.otyp].oc_magic) itmp.otyp -= 1; 342. # ifdef MAC 343. mac_speaker(&itmp, "C"); 344. # endif 345. # ifdef AMIGA 346. amii_speaker(&itmp, "Cw", AMII_OKAY_VOLUME); 347. # endif 348. # ifdef VPIX_MUSIC 349. if (sco_flag_console) 350. speaker(&itmp, "C"); 351. # endif 352. #ifdef PCMUSIC 353. pc_speaker ( &itmp, "C"); 354. #endif 355. #endif /* MAC || AMIGA || VPIX_MUSIC || PCMUSIC */ 356. 357. if (!do_spec) 358. pline("What you produce is quite far from music..."); 359. else 360. You("start playing %s.", the(xname(instr))); 361. 362. switch (instr->otyp) { 363. case MAGIC_FLUTE: /* Make monster fall asleep */ 364. if (do_spec && instr->spe > 0) { 365. check_unpaid(instr); 366. instr->spe--; 367. You("produce soft music."); 368. put_monsters_to_sleep(u.ulevel * 5); 369. exercise(A_DEX, TRUE); 370. break; 371. } /* else FALLTHRU */ 372. case WOODEN_FLUTE: /* May charm snakes */ 373. do_spec &= (rn2(ACURR(A_DEX)) + u.ulevel > 25); 374. pline("%s %s.", The(xname(instr)), 375. do_spec ? "trills" : "toots"); 376. if (do_spec) charm_snakes(u.ulevel * 3); 377. exercise(A_DEX, TRUE); 378. break; 379. case FROST_HORN: /* Idem wand of cold */ 380. case FIRE_HORN: /* Idem wand of fire */ 381. if (do_spec && instr->spe > 0) { 382. check_unpaid(instr); 383. instr->spe--; 384. if (!getdir((char *)0)) { 385. pline("%s vibrates.", The(xname(instr))); 386. break; 387. } else if (!u.dx && !u.dy && !u.dz) { 388. if ((damage = zapyourself(instr, TRUE)) != 0) 389. losehp(damage, 390. self_pronoun("using a magical horn on %sself", 391. "him"), 392. NO_KILLER_PREFIX); 393. } else { 394. buzz((instr->otyp == FROST_HORN) ? AD_COLD-1 : AD_FIRE-1, 395. rn1(6,6), u.ux, u.uy, u.dx, u.dy); 396. } 397. makeknown(instr->otyp); 398. break; 399. } /* else FALLTHRU */ 400. case TOOLED_HORN: /* Awaken or scare monsters */ 401. You("produce a frightful, grave sound."); 402. awaken_monsters(u.ulevel * 30); 403. exercise(A_WIS, FALSE); 404. break; 405. case BUGLE: /* Awaken & attract soldiers */ 406. You("extract a loud noise from %s.", the(xname(instr))); 407. awaken_soldiers(); 408. exercise(A_WIS, FALSE); 409. break; 410. case MAGIC_HARP: /* Charm monsters */ 411. if (do_spec && instr->spe > 0) { 412. check_unpaid(instr); 413. instr->spe--; 414. pline("%s produces very attractive music.", 415. The(xname(instr))); 416. charm_monsters((u.ulevel - 1) / 3 + 1); 417. exercise(A_DEX, TRUE); 418. break; 419. } /* else FALLTHRU */ 420. case WOODEN_HARP: /* May calm Nymph */ 421. do_spec &= (rn2(ACURR(A_DEX)) + u.ulevel > 25); 422. pline("%s %s.", The(xname(instr)), 423. do_spec ? "produces a lilting melody" : "twangs"); 424. if (do_spec) calm_nymphs(u.ulevel * 3); 425. exercise(A_DEX, TRUE); 426. break; 427. case DRUM_OF_EARTHQUAKE: /* create several pits */ 428. if (do_spec && instr->spe > 0) { 429. check_unpaid(instr); 430. instr->spe--; 431. You("produce a heavy, thunderous rolling!"); 432. pline_The("entire dungeon is shaking around you!"); 433. do_earthquake((u.ulevel - 1) / 3 + 1); 434. /* shake up monsters in a much larger radius... */ 435. awaken_monsters(ROWNO * COLNO); 436. makeknown(DRUM_OF_EARTHQUAKE); 437. break; 438. } /* else FALLTHRU */ 439. case LEATHER_DRUM: /* Awaken monsters */ 440. You("beat a deafening row!"); 441. awaken_monsters(u.ulevel * 40); 442. exercise(A_WIS, FALSE); 443. break; 444. default: 445. impossible("What a weird instrument (%d)!", instr->otyp); 446. break; 447. } 448. return 2; /* That takes time */ 449. } 450. 451. /* 452. * So you want music... 453. */ 454. 455. int 456. do_play_instrument(instr) 457. struct obj *instr; 458. { 459. char buf[BUFSZ], c = 'y'; 460. #ifndef AMIGA 461. char *s; 462. #endif 463. int x,y; 464. boolean ok; 465. 466. if (Underwater) { 467. You_cant("play music underwater!"); 468. return(0); 469. } 470. if (instr->otyp != LEATHER_DRUM && instr->otyp != DRUM_OF_EARTHQUAKE) { 471. c = yn("Improvise?"); 472. } 473. if (c == 'n') { 474. if (u.uevent.uheard_tune == 2 && yn("Play the passtune?") == 'y') 475. Strcpy(buf, tune); 476. else 477. getlin("What tune are you playing? [what 5 notes]", buf); 478. #ifndef AMIGA 479. /* The AMIGA supports two octaves of notes */ 480. for (s=buf; *s; s++) *s = highc(*s); 481. #endif 482. You("extract a strange sound from %s!", the(xname(instr))); 483. #ifdef UNIX386MUSIC 484. /* if user is at the console, play through the console speaker */ 485. if (atconsole()) 486. speaker(instr, buf); 487. #endif 488. #ifdef VPIX_MUSIC 489. if (sco_flag_console) 490. speaker(instr, buf); 491. #endif 492. #ifdef MAC 493. mac_speaker ( instr , buf ) ; 494. #endif 495. #ifdef PCMUSIC 496. pc_speaker ( instr, buf ); 497. #endif 498. #ifdef AMIGA 499. { 500. char nbuf[ 20 ]; 501. int i; 502. for( i = 0; buf[i] && i < 5; ++i ) 503. { 504. nbuf[ i*2 ] = buf[ i ]; 505. nbuf[ (i*2)+1 ] = 'h'; 506. } 507. nbuf[ i*2 ] = 0; 508. amii_speaker ( instr , nbuf, AMII_OKAY_VOLUME ) ; 509. } 510. #endif 511. /* Check if there was the Stronghold drawbridge near 512. * and if the tune conforms to what we're waiting for. 513. */ 514. if(Is_stronghold(&u.uz)) { 515. exercise(A_WIS, TRUE); /* just for trying */ 516. if(!strcmp(buf,tune)) { 517. /* Search for the drawbridge */ 518. for(y=u.uy-1; y<=u.uy+1; y++) 519. for(x=u.ux-1;x<=u.ux+1;x++) 520. if(isok(x,y)) 521. if(find_drawbridge(&x,&y)) { 522. u.uevent.uheard_tune = 2; /* tune now fully known */ 523. if(levl[x][y].typ == DRAWBRIDGE_DOWN) 524. close_drawbridge(x,y); 525. else 526. open_drawbridge(x,y); 527. return 0; 528. } 529. } else if(flags.soundok) { 530. if (u.uevent.uheard_tune < 1) u.uevent.uheard_tune = 1; 531. /* Okay, it wasn't the right tune, but perhaps 532. * we can give the player some hints like in the 533. * Mastermind game */ 534. ok = FALSE; 535. for(y = u.uy-1; y <= u.uy+1 && !ok; y++) 536. for(x = u.ux-1; x <= u.ux+1 && !ok; x++) 537. if(isok(x,y)) 538. if(IS_DRAWBRIDGE(levl[x][y].typ) || 539. is_drawbridge_wall(x,y) >= 0) 540. ok = TRUE; 541. if(ok) { /* There is a drawbridge near */ 542. int tumblers, gears; 543. boolean matched[5]; 544. 545. tumblers = gears = 0; 546. for(x=0; x < 5; x++) 547. matched[x] = FALSE; 548. 549. for(x=0; x < (int)strlen(buf); x++) 550. if(x < 5) { 551. if(buf[x] == tune[x]) { 552. gears++; 553. matched[x] = TRUE; 554. } else 555. for(y=0; y < 5; y++) 556. if(!matched[y] && 557. buf[x] == tune[y] && 558. buf[y] != tune[y]) { 559. tumblers++; 560. matched[y] = TRUE; 561. break; 562. } 563. } 564. if(tumblers) 565. if(gears) 566. You_hear("%d tumbler%s click and %d gear%s turn.", 567. tumblers, plur(tumblers), gears, plur(gears)); 568. else 569. You_hear("%d tumbler%s click.", 570. tumblers, plur(tumblers)); 571. else if(gears) { 572. You_hear("%d gear%s turn.", gears, plur(gears)); 573. /* could only get `gears == 5' by playing five 574. correct notes followed by excess; otherwise, 575. tune would have matched above */ 576. if (gears == 5) u.uevent.uheard_tune = 2; 577. } 578. } 579. } 580. } 581. return 1; 582. } else 583. return do_improvisation(instr); 584. } 585. 586. #ifdef UNIX386MUSIC 587. /* 588. * Play audible music on the machine's speaker if appropriate. 589. */ 590. 591. static int 592. atconsole() 593. { 594. /* 595. * Kluge alert: This code assumes that your [34]86 has no X terminals 596. * attached and that the console tty type is AT386 (this is always true 597. * under AT&T UNIX for these boxen). The theory here is that your remote 598. * ttys will have terminal type `ansi' or something else other than 599. * `AT386' or `xterm'. We'd like to do better than this, but testing 600. * to see if we're running on the console physical terminal is quite 601. * difficult given the presence of virtual consoles and other modern 602. * UNIX impedimenta... 603. */ 604. char *termtype = getenv("TERM"); 605. 606. return(!strcmp(termtype, "AT386") || !strcmp(termtype, "xterm")); 607. } 608. 609. static void 610. speaker(instr, buf) 611. struct obj *instr; 612. char *buf; 613. { 614. /* 615. * For this to work, you need to have installed the PD speaker-control 616. * driver for PC-compatible UNIX boxes that I (esr@snark.thyrsus.com) 617. * posted to comp.sources.unix in Feb 1990. A copy should be included 618. * with your nethack distribution. 619. */ 620. int fd; 621. 622. if ((fd = open("/dev/speaker", 1)) != -1) 623. { 624. /* send a prefix to modify instrumental `timbre' */ 625. switch (instr->otyp) 626. { 627. case WOODEN_FLUTE: 628. case MAGIC_FLUTE: 629. (void) write(fd, ">ol", 1); /* up one octave & lock */ 630. break; 631. case TOOLED_HORN: 632. case FROST_HORN: 633. case FIRE_HORN: 635. break; 636. case BUGLE: 637. (void) write(fd, "ol", 2); /* octave lock */ 638. break; 639. case WOODEN_HARP: 640. case MAGIC_HARP: 641. (void) write(fd, "l8mlol", 4); /* fast, legato, octave lock */ 642. break; 643. } 644. (void) write(fd, buf, strlen(buf)); 645. (void) close(fd); 646. } 647. } 648. #endif /* UNIX386MUSIC */ 649. 650. #ifdef VPIX_MUSIC 651. 652. # if 0 653. #include 654. #include 655. #include 656. # else 657. #define KIOC ('K' << 8) 658. #define KDMKTONE (KIOC | 8) 659. # endif 660. 661. #define noDEBUG 662. 663. static void tone(hz, ticks) 664. /* emit tone of frequency hz for given number of ticks */ 665. unsigned int hz, ticks; 666. { 667. ioctl(0,KDMKTONE,hz|((ticks*10)<<16)); 668. # ifdef DEBUG 669. printf("TONE: %6d %6d ",hz,ticks * 10); 670. # endif 671. nap(ticks * 10); 672. } 673. 674. static void rest(ticks) 675. /* rest for given number of ticks */ 676. int ticks; 677. { 678. nap(ticks * 10); 679. # ifdef DEBUG 680. printf("REST: %6d ",ticks * 10); 681. # endif 682. } 683. 684. 685. #include "interp.c" /* from snd86unx.shr */ 686. 687. 688. static void 689. speaker(instr, buf) 690. struct obj *instr; 691. char *buf; 692. { 693. /* emit a prefix to modify instrumental `timbre' */ 694. playinit(); 695. switch (instr->otyp) 696. { 697. case WOODEN_FLUTE: 698. case MAGIC_FLUTE: 699. playstring(">ol", 1); /* up one octave & lock */ 700. break; 701. case TOOLED_HORN: 702. case FROST_HORN: 703. case FIRE_HORN: 705. break; 706. case BUGLE: 707. playstring("ol", 2); /* octave lock */ 708. break; 709. case WOODEN_HARP: 710. case MAGIC_HARP: 711. playstring("l8mlol", 4); /* fast, legato, octave lock */ 712. break; 713. } 714. playstring( buf, strlen(buf)); 715. } 716. 717. # ifdef DEBUG 718. main(argc,argv) 719. char *argv[]; 720. { 721. if (argc == 2) { 722. playinit(); 723. playstring(argv[1], strlen(argv[1])); 724. } 725. } 726. # endif 727. #endif /* VPIX_MUSIC */ 728. 729. /*music.c*/