1 /* NetHack 3.6 music.c $NHDT-Date: 1446808448 2015/11/06 11:14:08 $ $NHDT-Branch: master $:$NHDT-Revision: 1.40 $ */
2 /* Copyright (c) 1989 by Jean-Christophe Collet */
3 /* NetHack may be freely redistributed. See license for details. */
5 /* JNetHack Copyright */
6 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
7 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016 */
8 /* JNetHack may be freely redistributed. See license for details. */
11 * This file contains the different functions designed to manipulate the
12 * musical instruments and their various effects.
14 * Actually the list of instruments / effects is :
16 * (wooden) flute may calm snakes if player has enough dexterity
17 * magic flute may put monsters to sleep: area of effect depends
19 * (tooled) horn Will awaken monsters: area of effect depends on
20 * player level. May also scare monsters.
21 * fire horn Acts like a wand of fire.
22 * frost horn Acts like a wand of cold.
23 * bugle Will awaken soldiers (if any): area of effect depends
25 * (wooden) harp May calm nymph if player has enough dexterity.
26 * magic harp Charm monsters: area of effect depends on player
28 * (leather) drum Will awaken monsters like the horn.
29 * drum of earthquake Will initiate an earthquake whose intensity depends
30 * on player level. That is, it creates random pits
36 STATIC_DCL void FDECL(awaken_monsters, (int));
37 STATIC_DCL void FDECL(put_monsters_to_sleep, (int));
38 STATIC_DCL void FDECL(charm_snakes, (int));
39 STATIC_DCL void FDECL(calm_nymphs, (int));
40 STATIC_DCL void FDECL(charm_monsters, (int));
41 STATIC_DCL void FDECL(do_earthquake, (int));
42 STATIC_DCL int FDECL(do_improvisation, (struct obj *));
45 STATIC_DCL int NDECL(atconsole);
46 STATIC_DCL void FDECL(speaker, (struct obj *, char *));
49 extern int sco_flag_console; /* will need changing if not _M_UNIX */
50 STATIC_DCL void NDECL(playinit);
51 STATIC_DCL void FDECL(playstring, (char *, size_t));
52 STATIC_DCL void FDECL(speaker, (struct obj *, char *));
55 void FDECL(pc_speaker, (struct obj *, char *));
58 void FDECL(amii_speaker, (struct obj *, char *, int));
62 * Wake every monster in range...
66 awaken_monsters(distance)
69 register struct monst *mtmp;
72 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
73 if (DEADMONSTER(mtmp))
75 if ((distm = distu(mtmp->mx, mtmp->my)) < distance) {
79 /* may scare some monsters -- waiting monsters excluded */
80 if (!unique_corpstat(mtmp->data)
81 && (mtmp->mstrategy & STRAT_WAITMASK) != 0)
82 mtmp->mstrategy &= ~STRAT_WAITMASK;
83 else if (distm < distance / 3
84 && !resist(mtmp, TOOL_CLASS, 0, NOTELL))
85 monflee(mtmp, 0, FALSE, TRUE);
91 * Make monsters fall asleep. Note that they may resist the spell.
95 put_monsters_to_sleep(distance)
98 register struct monst *mtmp;
100 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
101 if (DEADMONSTER(mtmp))
103 if (distu(mtmp->mx, mtmp->my) < distance
104 && sleep_monst(mtmp, d(10, 10), TOOL_CLASS)) {
105 mtmp->msleeping = 1; /* 10d10 turns + wake_nearby to rouse */
112 * Charm snakes in range. Note that the snakes are NOT tamed.
116 charm_snakes(distance)
119 register struct monst *mtmp;
120 int could_see_mon, was_peaceful;
122 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
123 if (DEADMONSTER(mtmp))
125 if (mtmp->data->mlet == S_SNAKE && mtmp->mcanmove
126 && distu(mtmp->mx, mtmp->my) < distance) {
127 was_peaceful = mtmp->mpeaceful;
130 mtmp->mstrategy &= ~STRAT_WAITMASK;
131 could_see_mon = canseemon(mtmp);
132 mtmp->mundetected = 0;
133 newsym(mtmp->mx, mtmp->my);
134 if (canseemon(mtmp)) {
137 You("notice %s, swaying with the music.", a_monnam(mtmp));
139 You("%s
\82ª
\89¹
\8ay
\82É
\8d\87\82í
\82¹
\82Ä
\97h
\82ê
\82Ä
\82¢
\82é
\82Ì
\82É
\8bC
\95t
\82¢
\82½
\81D", a_monnam(mtmp));
142 pline("%s freezes, then sways with the music%s.",
144 was_peaceful ? "" : ", and now seems quieter");
146 pline("%s
\82Í
\97§
\82¿
\82·
\82
\82Ý
\81C
\89¹
\8ay
\82É
\8d\87\82í
\82¹
\82Ä
\97h
\82ê%s
\82½
\81D",
148 was_peaceful ? "" : "
\81C
\82¨
\82Æ
\82È
\82µ
\82
\82È
\82Á");
156 * Calm nymphs in range.
160 calm_nymphs(distance)
163 register struct monst *mtmp;
165 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
166 if (DEADMONSTER(mtmp))
168 if (mtmp->data->mlet == S_NYMPH && mtmp->mcanmove
169 && distu(mtmp->mx, mtmp->my) < distance) {
173 mtmp->mstrategy &= ~STRAT_WAITMASK;
177 "%s listens cheerfully to the music, then seems quieter.",
179 "%s
\82Í
\89¹
\8ay
\82É
\95·
\82«
\82¢
\82è
\81C
\82¨
\82Æ
\82È
\82µ
\82
\82È
\82Á
\82½
\81D",
185 /* Awake soldiers anywhere the level (and any nearby monster). */
187 awaken_soldiers(bugler)
188 struct monst *bugler; /* monster that played instrument */
190 register struct monst *mtmp;
193 /* distance of affected non-soldier monsters to bugler */
194 distance = ((bugler == &youmonst) ? u.ulevel : bugler->data->mlevel) * 30;
196 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
197 if (DEADMONSTER(mtmp))
199 if (is_mercenary(mtmp->data) && mtmp->data != &mons[PM_GUARD]) {
200 mtmp->mpeaceful = mtmp->msleeping = mtmp->mfrozen = 0;
202 mtmp->mstrategy &= ~STRAT_WAITMASK;
205 pline("%s is now ready for battle!", Monnam(mtmp));
207 pline("%s
\82Í
\90í
\82¢
\82Ì
\8f\80\94õ
\82ª
\90®
\82Á
\82½
\81I", Monnam(mtmp));
210 Norep("You hear the rattle of battle gear being readied.");
212 Norep("
\82 \82È
\82½
\82Í
\90í
\82¢
\82Ì
\8f\80\94õ
\82ª
\90®
\82Á
\82½
\82±
\82Æ
\82ð
\8e¦
\82·
\89¹
\82ð
\95·
\82¢
\82½
\81D");
213 } else if ((distm = ((bugler == &youmonst)
214 ? distu(mtmp->mx, mtmp->my)
215 : dist2(bugler->mx, bugler->my, mtmp->mx,
216 mtmp->my))) < distance) {
220 /* may scare some monsters -- waiting monsters excluded */
221 if (!unique_corpstat(mtmp->data)
222 && (mtmp->mstrategy & STRAT_WAITMASK) != 0)
223 mtmp->mstrategy &= ~STRAT_WAITMASK;
224 else if (distm < distance / 3
225 && !resist(mtmp, TOOL_CLASS, 0, NOTELL))
226 monflee(mtmp, 0, FALSE, TRUE);
231 /* Charm monsters in range. Note that they may resist the spell.
232 * If swallowed, range is reduced to 0.
235 charm_monsters(distance)
238 struct monst *mtmp, *mtmp2;
241 if (!resist(u.ustuck, TOOL_CLASS, 0, NOTELL))
242 (void) tamedog(u.ustuck, (struct obj *) 0);
244 for (mtmp = fmon; mtmp; mtmp = mtmp2) {
246 if (DEADMONSTER(mtmp))
249 if (distu(mtmp->mx, mtmp->my) <= distance) {
250 if (!resist(mtmp, TOOL_CLASS, 0, NOTELL))
251 (void) tamedog(mtmp, (struct obj *) 0);
257 /* Generate earthquake :-) of desired force.
258 * That is: create random chasms (pits).
267 struct trap *chasm, *trap_at_u = t_at(u.ux, u.uy);
268 int start_x, start_y, end_x, end_y;
273 tu_pit = (trap_at_u->ttyp == PIT || trap_at_u->ttyp == SPIKED_PIT);
274 start_x = u.ux - (force * 2);
275 start_y = u.uy - (force * 2);
276 end_x = u.ux + (force * 2);
277 end_y = u.uy + (force * 2);
286 for (x = start_x; x <= end_x; x++)
287 for (y = start_y; y <= end_y; y++) {
288 if ((mtmp = m_at(x, y)) != 0) {
289 wakeup(mtmp); /* peaceful monster will become hostile */
290 if (mtmp->mundetected && is_hider(mtmp->data)) {
291 mtmp->mundetected = 0;
294 pline("%s is shaken loose from the ceiling!",
296 pline("%s
\82Í
\97h
\82·
\82ç
\82ê
\81C
\93V
\88ä
\82©
\82ç
\97\8e\82¿
\82Ä
\82«
\82½
\81I",
300 You_hear("a thumping sound.");
302 You_hear("
\83h
\83\93\83h
\83\93\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D");
303 if (x == u.ux && y == u.uy)
305 You("easily dodge the falling %s.", mon_nam(mtmp));
307 You("
\97\8e\82¿
\82Ä
\82«
\82½%s
\82ð
\8aÈ
\92P
\82É
\82©
\82í
\82µ
\82½
\81D", mon_nam(mtmp));
311 if (!rn2(14 - force))
312 switch (levl[x][y].typ) {
313 case FOUNTAIN: /* Make the fountain disappear */
316 pline_The("fountain falls into a chasm.");
318 pline("
\90ò
\82Í
\92n
\8a\84\82ê
\82É
\97\8e\82¿
\82½
\81D");
323 pline_The("kitchen sink falls into a chasm.");
325 pline("
\97¬
\82µ
\91ä
\82Í
\92n
\8a\84\82ê
\82É
\97\8e\82¿
\82½
\81D");
328 if (Is_astralevel(&u.uz) || Is_sanctum(&u.uz))
333 pline_The("altar falls into a chasm.");
335 pline("
\8dÕ
\92d
\82Í
\92n
\8a\84\82ê
\82É
\97\8e\82¿
\82½
\81D");
340 pline_The("headstone topples into a chasm.");
342 pline("
\95æ
\90Î
\82Í
\95ö
\82ê
\82³
\82Á
\82½
\81D");
347 pline_The("throne falls into a chasm.");
349 pline("
\8bÊ
\8dÀ
\82Í
\92n
\8a\84\82ê
\82É
\97\8e\82¿
\82½
\81D");
350 /* Falls into next case */
352 case CORR: /* Try to make a pit */
354 chasm = maketrap(x, y, PIT);
356 break; /* no pit if portal at that location */
359 levl[x][y].doormask = 0;
361 * Let liquid flow into the newly created chasm.
362 * Adjust corresponding code in apply.c for
363 * exploding wand of digging if you alter this sequence.
365 filltype = fillholetyp(x, y, FALSE);
366 if (filltype != ROOM) {
367 levl[x][y].typ = filltype;
368 liquid_flow(x, y, filltype, chasm, (char *) 0);
373 if ((otmp = sobj_at(BOULDER, x, y)) != 0) {
376 pline("KADOOM! The boulder falls into a chasm%s!",
377 ((x == u.ux) && (y == u.uy)) ? " below you"
380 pline("
\83h
\83h
\81[
\83\93\81I
\8aâ
\82Í%s
\92n
\8a\84\82ê
\82É
\97\8e\82¿
\82½
\81I",
381 ((x == u.ux) && (y == u.uy)) ? "
\82 \82È
\82½
\82Ì
\89º
\82Ì"
386 obj_extract_self(otmp);
387 (void) flooreffects(otmp, x, y, "");
391 /* We have to check whether monsters or player
392 falls in a chasm... */
394 if (!is_flyer(mtmp->data)
395 && !is_clinger(mtmp->data)) {
396 boolean m_already_trapped = mtmp->mtrapped;
398 if (!m_already_trapped) { /* suppress messages */
401 pline("%s falls into a chasm!",
403 pline("%s
\82Í
\92n
\8a\84\82ê
\82É
\97\8e\82¿
\82½
\81I",
405 else if (humanoid(mtmp->data))
407 You_hear("a scream!");
409 You_hear("
\8b©
\82Ñ
\90º
\82ð
\95·
\82¢
\82½
\81I");
411 /* Falling is okay for falling down
412 within a pit from jostling too */
414 mselftouch(mtmp, "Falling, ", TRUE);
416 mselftouch(mtmp, "
\97\8e\89º
\92\86\81C", TRUE);
419 rnd(m_already_trapped ? 4 : 6)) <= 0) {
422 pline("It is destroyed!");
424 pline("
\89½
\8eÒ
\82©
\82Í
\8e\80\82ñ
\82¾
\81I");
438 pline("%s%s
\82Í
\8e\80\82ñ
\82¾
\81I",
440 ? "
\82©
\82í
\82¢
\82»
\82¤
\82È" : "",
447 } else if (x == u.ux && y == u.uy) {
448 if (Levitation || Flying
449 || is_clinger(youmonst.data)) {
450 if (!tu_pit) { /* no pit here previously */
452 pline("A chasm opens up under you!");
454 pline("
\92n
\8a\84\82ê
\82ª
\91«
\8c³
\82É
\8aJ
\82¢
\82½
\81I");
456 You("don't fall in!");
458 You("
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81I");
460 } else if (!tu_pit || !u.utrap
461 || (u.utrap && u.utraptype != TT_PIT)) {
462 /* no pit here previously, or you were
463 not in it even it there was */
465 You("fall into a chasm!");
467 You("
\92n
\8a\84\82ê
\82É
\97\8e\82¿
\82½
\81I");
469 u.utraptype = TT_PIT;
471 losehp(Maybe_Half_Phys(rnd(6)),
472 "fell into a chasm", NO_KILLER_PREFIX);
474 losehp(Maybe_Half_Phys(rnd(6)),
475 "
\92n
\8a\84\82ê
\82É
\97\8e\82¿
\82Ä", NO_KILLER_PREFIX);
478 selftouch("Falling, you");
480 selftouch("
\97\8e\82¿
\82È
\82ª
\82ç
\81C
\82 \82È
\82½
\82Í");
481 } else if (u.utrap && u.utraptype == TT_PIT) {
482 boolean keepfooting =
483 ((Fumbling && !rn2(5))
484 || (!rnl(Role_if(PM_ARCHEOLOGIST) ? 3 : 9))
485 || ((ACURR(A_DEX) > 7) && rn2(5)));
486 You("are jostled around violently!");
488 u.utraptype = TT_PIT; /* superfluous */
489 losehp(Maybe_Half_Phys(rnd(keepfooting ? 2 : 4)),
490 "hurt in a chasm", NO_KILLER_PREFIX);
492 exercise(A_DEX, TRUE);
495 (Upolyd && (slithy(youmonst.data)
496 || nolimbs(youmonst.data)))
498 : "Falling down, you");
503 case DOOR: /* Make the door collapse */
504 if (levl[x][y].doormask == D_NODOOR)
508 pline_The("door collapses.");
510 pline_The("
\94à
\82Í
\82±
\82È
\82²
\82È
\82É
\82È
\82Á
\82½
\81D");
511 if (*in_rooms(x, y, SHOPBASE))
512 add_damage(x, y, 0L);
513 levl[x][y].doormask = D_NODOOR;
522 * The player is trying to extract something from his/her instrument.
525 do_improvisation(instr)
528 int damage, do_spec = !Confusion;
529 #if defined(MAC) || defined(AMIGA) || defined(VPIX_MUSIC) || defined(PCMUSIC)
533 itmp.oextra = (struct oextra *) 0; /* ok on this copy as instr maintains
534 the ptr to free at some point if
537 /* if won't yield special effect, make sound of mundane counterpart */
538 if (!do_spec || instr->spe <= 0)
539 while (objects[itmp.otyp].oc_magic)
542 mac_speaker(&itmp, "C");
545 amii_speaker(&itmp, "Cw", AMII_OKAY_VOLUME);
548 if (sco_flag_console)
552 pc_speaker(&itmp, "C");
554 #endif /* MAC || AMIGA || VPIX_MUSIC || PCMUSIC */
558 pline("What you produce is quite far from music...");
560 pline("
\82 \82È
\82½
\82ª
\91t
\82Å
\82½
\82à
\82Ì
\82Í
\89¹
\8ay
\82Æ
\82Í
\82Æ
\82Ä
\82à
\8cÄ
\82×
\82È
\82¢
\81D
\81D
\81D");
563 You("start playing %s.", the(xname(instr)));
565 You("%s
\82ð
\91t
\82Å
\82Í
\82¶
\82ß
\82½
\81D", the(xname(instr)));
567 switch (instr->otyp) {
568 case MAGIC_FLUTE: /* Make monster fall asleep */
569 if (do_spec && instr->spe > 0) {
570 consume_obj_charge(instr, TRUE);
573 You("produce %s music.", Hallucination ? "piped" : "soft");
575 You("%s
\82ð
\91t
\82Å
\82½
\81D", Hallucination ? "
\82a
\82f
\82l" : "
\93î
\82ç
\82©
\82¢
\8bÈ");
576 put_monsters_to_sleep(u.ulevel * 5);
577 exercise(A_DEX, TRUE);
579 } /* else FALLTHRU */
580 case WOODEN_FLUTE: /* May charm snakes */
581 do_spec &= (rn2(ACURR(A_DEX)) + u.ulevel > 25);
583 pline("%s.", Tobjnam(instr, do_spec ? "trill" : "toot"));
585 pline("%s
\82ð%s
\82½
\81D", xname(instr), do_spec ? "
\91t
\82Å" : "
\90\81\82¢");
587 charm_snakes(u.ulevel * 3);
588 exercise(A_DEX, TRUE);
590 case FIRE_HORN: /* Idem wand of fire */
591 case FROST_HORN: /* Idem wand of cold */
592 if (do_spec && instr->spe > 0) {
593 consume_obj_charge(instr, TRUE);
595 if (!getdir((char *) 0)) {
597 pline("%s.", Tobjnam(instr, "vibrate"));
599 pline("%s
\82Í
\90k
\82¦
\82½
\81D", xname(instr));
601 } else if (!u.dx && !u.dy && !u.dz) {
602 if ((damage = zapyourself(instr, TRUE)) != 0) {
606 Sprintf(buf, "using a magical horn on %sself", uhim());
608 Strcpy(buf, "
\8e©
\95ª
\8e©
\90g
\82Ì
\96\82\96@
\82Ì
\83z
\83\8b\83\93\82Ì
\97Í
\82ð
\97\81\82Ñ
\82Ä");
609 losehp(damage, buf, KILLED_BY); /* fire or frost damage */
612 buzz((instr->otyp == FROST_HORN) ? AD_COLD - 1 : AD_FIRE - 1,
613 rn1(6, 6), u.ux, u.uy, u.dx, u.dy);
615 makeknown(instr->otyp);
617 } /* else FALLTHRU */
618 case TOOLED_HORN: /* Awaken or scare monsters */
620 You("produce a frightful, grave sound.");
622 You("
\90g
\90k
\82¢
\82·
\82é
\82æ
\82¤
\82È
\8e\80\8eÒ
\82Ì
\89¹
\8ay
\82ð
\91t
\82Å
\82½
\81D");
623 awaken_monsters(u.ulevel * 30);
624 exercise(A_WIS, FALSE);
626 case BUGLE: /* Awaken & attract soldiers */
628 You("extract a loud noise from %s.", the(xname(instr)));
630 You("%s
\82©
\82ç
\91å
\82«
\82È
\8e¨
\8fá
\82è
\82È
\89¹
\82ð
\8fo
\82µ
\82½
\81D", the(xname(instr)));
631 awaken_soldiers(&youmonst);
632 exercise(A_WIS, FALSE);
634 case MAGIC_HARP: /* Charm monsters */
635 if (do_spec && instr->spe > 0) {
636 consume_obj_charge(instr, TRUE);
639 pline("%s very attractive music.", Tobjnam(instr, "produce"));
641 pline("%s
\82Í
\82Æ
\82Ä
\82à
\96£
\97Í
\93I
\82È
\89¹
\8ay
\82ð
\91t
\82Å
\82½
\81D", xname(instr));
642 charm_monsters((u.ulevel - 1) / 3 + 1);
643 exercise(A_DEX, TRUE);
645 } /* else FALLTHRU */
646 case WOODEN_HARP: /* May calm Nymph */
647 do_spec &= (rn2(ACURR(A_DEX)) + u.ulevel > 25);
649 pline("%s %s.", The(xname(instr)),
650 do_spec ? "produces a lilting melody" : "twangs");
653 do_spec ? "
\8cy
\89õ
\82È
\89¹
\8ay
\82ð
\91t
\82Å
\82½" : "
\83|
\83\8d\81[
\83\93\82Æ
\82¢
\82¤
\89¹
\82ð
\8fo
\82µ
\82½");
656 calm_nymphs(u.ulevel * 3);
657 exercise(A_DEX, TRUE);
659 case DRUM_OF_EARTHQUAKE: /* create several pits */
660 if (do_spec && instr->spe > 0) {
661 consume_obj_charge(instr, TRUE);
664 You("produce a heavy, thunderous rolling!");
666 You("
\8fd
\8cú
\82È
\97\8b\82Ì
\82æ
\82¤
\82È
\89¹
\82ð
\91t
\82Å
\82½
\81I");
668 pline_The("entire dungeon is shaking around you!");
670 pline("
\82 \82È
\82½
\82Ì
\89ñ
\82è
\82Ì
\96À
\8b{
\82ª
\97h
\82ê
\82½
\81I");
671 do_earthquake((u.ulevel - 1) / 3 + 1);
672 /* shake up monsters in a much larger radius... */
673 awaken_monsters(ROWNO * COLNO);
674 makeknown(DRUM_OF_EARTHQUAKE);
676 } /* else FALLTHRU */
677 case LEATHER_DRUM: /* Awaken monsters */
679 You("beat a deafening row!");
681 You("
\8e¨
\82ª
\95·
\82±
\82¦
\82È
\82
\82È
\82é
\82
\82ç
\82¢
\92@
\82¢
\82½
\81I");
682 awaken_monsters(u.ulevel * 40);
683 incr_itimeout(&HDeaf, rn1(20, 30));
684 exercise(A_WIS, FALSE);
687 impossible("What a weird instrument (%d)!", instr->otyp);
690 return 2; /* That takes time */
694 * So you want music...
697 do_play_instrument(instr)
700 char buf[BUFSZ], c = 'y';
707 You_cant("play music underwater!");
709 You("
\90\85\82Ì
\92\86\82Å
\82Í
\89¹
\8ay
\82ð
\91t
\82Å
\82ç
\82ê
\82È
\82¢
\81I");
711 } else if ((instr->otyp == WOODEN_FLUTE || instr->otyp == MAGIC_FLUTE
712 || instr->otyp == TOOLED_HORN || instr->otyp == FROST_HORN
713 || instr->otyp == FIRE_HORN || instr->otyp == BUGLE)
714 && !can_blow(&youmonst)) {
715 You("are incapable of playing %s.", the(distant_name(instr, xname)));
718 if (instr->otyp != LEATHER_DRUM && instr->otyp != DRUM_OF_EARTHQUAKE) {
720 c = ynq("Improvise?");
722 c = ynq("
\91¦
\8b»
\82Å
\89\89\91t
\82·
\82é
\81H");
727 if (u.uevent.uheard_tune == 2)
729 c = ynq("Play the passtune?");
731 c = ynq("
\83R
\81[
\83h
\82ð
\89\89\91t
\82·
\82é
\81H");
734 } else if (c == 'y') {
738 getlin("What tune are you playing? [5 notes, A-G]", buf);
740 getlin("
\82Ç
\82Ì
\82æ
\82¤
\82È
\92²
\82×
\82ð
\89\89\91t
\82µ
\82Ü
\82·
\82©
\81H[A-G
\82©
\82ç5
\89¹
\82ð
\82¢
\82ê
\82Ä
\82Ë]", buf);
741 (void) mungspaces(buf);
745 /* convert to uppercase and change any "H" to the expected "B" */
746 for (s = buf; *s; s++) {
750 /* The AMIGA supports two octaves of notes */
759 You("extract a strange sound from %s!", the(xname(instr)));
761 You("%s
\82©
\82ç
\8aï
\96
\82È
\89¹
\82ð
\8fo
\82µ
\82½
\81I", the(xname(instr)));
763 /* if user is at the console, play through the console speaker */
768 if (sco_flag_console)
772 mac_speaker(instr, buf);
775 pc_speaker(instr, buf);
782 for (i = 0; buf[i] && i < 5; ++i) {
783 nbuf[i * 2] = buf[i];
784 nbuf[(i * 2) + 1] = 'h';
787 amii_speaker(instr, nbuf, AMII_OKAY_VOLUME);
790 /* Check if there was the Stronghold drawbridge near
791 * and if the tune conforms to what we're waiting for.
793 if (Is_stronghold(&u.uz)) {
794 exercise(A_WIS, TRUE); /* just for trying */
795 if (!strcmp(buf, tune)) {
796 /* Search for the drawbridge */
797 for (y = u.uy - 1; y <= u.uy + 1; y++)
798 for (x = u.ux - 1; x <= u.ux + 1; x++)
800 if (find_drawbridge(&x, &y)) {
801 u.uevent.uheard_tune =
802 2; /* tune now fully known */
803 if (levl[x][y].typ == DRAWBRIDGE_DOWN)
804 close_drawbridge(x, y);
806 open_drawbridge(x, y);
810 if (u.uevent.uheard_tune < 1)
811 u.uevent.uheard_tune = 1;
812 /* Okay, it wasn't the right tune, but perhaps
813 * we can give the player some hints like in the
816 for (y = u.uy - 1; y <= u.uy + 1 && !ok; y++)
817 for (x = u.ux - 1; x <= u.ux + 1 && !ok; x++)
819 if (IS_DRAWBRIDGE(levl[x][y].typ)
820 || is_drawbridge_wall(x, y) >= 0)
822 if (ok) { /* There is a drawbridge near */
826 tumblers = gears = 0;
827 for (x = 0; x < 5; x++)
830 for (x = 0; x < (int) strlen(buf); x++)
832 if (buf[x] == tune[x]) {
836 for (y = 0; y < 5; y++)
837 if (!matched[y] && buf[x] == tune[y]
838 && buf[y] != tune[y]) {
847 You_hear("%d tumbler%s click and %d gear%s turn.",
848 tumblers, plur(tumblers), gears,
851 You_hear("%d
\82Ì
\8bà
\8bï
\82ª
\83J
\83`
\82Á
\82Æ
\82È
\82è
\81C%d
\82Ì
\8e\95\8eÔ
\82ª
\82Ü
\82í
\82é
\89¹
\82ð
\95·
\82¢
\82½
\81D",
856 You_hear("%d tumbler%s click.", tumblers,
859 You_hear("%d
\82Ì
\8bà
\8bï
\82ª
\83J
\83`
\82Á
\82Æ
\82È
\82é
\89¹
\82ð
\95·
\82¢
\82½
\81D",
864 You_hear("%d gear%s turn.", gears, plur(gears));
866 You_hear("%d
\82Ì
\8e\95\8eÔ
\82ª
\89ñ
\82é
\89¹
\82ð
\95·
\82¢
\82½
\81D", gears);
867 /* could only get `gears == 5' by playing five
868 correct notes followed by excess; otherwise,
869 tune would have matched above */
871 u.uevent.uheard_tune = 2;
878 return do_improvisation(instr);
887 * Play audible music on the machine's speaker if appropriate.
894 * Kluge alert: This code assumes that your [34]86 has no X terminals
895 * attached and that the console tty type is AT386 (this is always true
896 * under AT&T UNIX for these boxen). The theory here is that your remote
897 * ttys will have terminal type `ansi' or something else other than
898 * `AT386' or `xterm'. We'd like to do better than this, but testing
899 * to see if we're running on the console physical terminal is quite
900 * difficult given the presence of virtual consoles and other modern
901 * UNIX impedimenta...
903 char *termtype = nh_getenv("TERM");
906 return (!strcmp(termtype, "AT386") || !strcmp(termtype, "xterm"));
908 return (!strcmp(termtype, "AT386") || !strcmp(termtype, "xterm") || !strcmp(termtype, "kterm"));
917 * For this to work, you need to have installed the PD speaker-control
918 * driver for PC-compatible UNIX boxes that I (esr@snark.thyrsus.com)
919 * posted to comp.sources.unix in Feb 1990. A copy should be included
920 * with your nethack distribution.
924 if ((fd = open("/dev/speaker", 1)) != -1) {
925 /* send a prefix to modify instrumental `timbre' */
926 switch (instr->otyp) {
929 (void) write(fd, ">ol", 1); /* up one octave & lock */
934 (void) write(fd, "<<ol", 2); /* drop two octaves & lock */
937 (void) write(fd, "ol", 2); /* octave lock */
941 (void) write(fd, "l8mlol", 4); /* fast, legato, octave lock */
944 (void) write(fd, buf, strlen(buf));
948 #endif /* UNIX386MUSIC */
953 #include <sys/types.h>
954 #include <sys/console.h>
955 #include <sys/vtkd.h>
957 #define KIOC ('K' << 8)
958 #define KDMKTONE (KIOC | 8)
963 /* emit tone of frequency hz for given number of ticks */
966 unsigned int hz, ticks;
968 ioctl(0, KDMKTONE, hz | ((ticks * 10) << 16));
970 printf("TONE: %6d %6d\n", hz, ticks * 10);
975 /* rest for given number of ticks */
982 printf("REST: %6d\n", ticks * 10);
986 #include "interp.c" /* from snd86unx.shr */
993 /* emit a prefix to modify instrumental `timbre' */
995 switch (instr->otyp) {
998 playstring(">ol", 1); /* up one octave & lock */
1003 playstring("<<ol", 2); /* drop two octaves & lock */
1006 playstring("ol", 2); /* octave lock */
1010 playstring("l8mlol", 4); /* fast, legato, octave lock */
1013 playstring(buf, strlen(buf));
1023 playstring(argv[1], strlen(argv[1]));
1027 #endif /* VPIX_MUSIC */