Update interpreters to latest Garglk codebase
[projects/chimara/chimara.git] / interpreters / nitfol / sound.c
1 /*  Nitfol - z-machine interpreter using Glk for output.
2     Copyright (C) 1999  Evin Robertson
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18     The author can be reached at nitfol@deja.com
19 */
20 #include "nitfol.h"
21
22 /* Link this in only if your glk supports sound */
23
24 #ifdef GLK_MODULE_SOUND
25
26 static schanid_t channel;
27
28 void init_sound(void)
29 {
30   channel = glk_schannel_create(0);
31 }
32
33 void kill_sound(void)
34 {
35   glk_schannel_destroy(channel);
36 }
37
38 static void set_volume(zword zvolume)
39 {
40   glui32 vol;
41   switch(zvolume) {
42   case   1: vol = 0x02000; break;
43   case   2: vol = 0x04000; break;
44   case   3: vol = 0x06000; break;
45   case   4: vol = 0x08000; break;
46   case   5: vol = 0x0a000; break;
47   case   6: vol = 0x0c000; break;
48   case   7: vol = 0x0e000; break;
49   case   8: vol = 0x10000; break;
50   case 255: vol = 0x20000; break;
51   default: n_show_error(E_SOUND, "illegal volume", zvolume);
52   }
53   glk_schannel_set_volume(channel, vol);
54 }
55
56
57 void check_sound(event_t moo) /* called from main event loop */
58 {
59   if(moo.type == evtype_SoundNotify) {
60     zword dummylocals[16];
61     in_timer = TRUE;
62     mop_call(moo.val2, 0, dummylocals, -2); /* add a special stack frame */
63     decode();                              /* start interpreting the routine */
64     in_timer = FALSE;
65     exit_decoder = FALSE;
66    }
67 }
68
69
70 void op_sound_effect(void)
71 {
72   zword number = operand[0], effect = operand[1];
73   zword volume = operand[2], routine = operand[3];
74   glui32 repeats;
75
76   if(!glk_gestalt(gestalt_Sound, 0))
77     return;
78
79   if(numoperands < 1)
80     number = 1;
81   if(numoperands < 2)
82     effect = 2;
83   if(numoperands < 3)
84     volume = 8;
85   if(numoperands < 4)
86     routine = 0;
87
88   repeats = (volume >> 8) & 0xff;
89   if(repeats == 0xff)
90     repeats = 0xffffffff;
91   else
92     repeats++;
93
94   volume &= 0xff;
95
96   switch(effect) {
97   case 1:
98     glk_sound_load_hint(number, 1);
99     break;
100   case 2:
101     glk_schannel_play_ext(channel, number, repeats, routine);
102     set_volume(volume);
103     break;
104   case 3:
105     glk_schannel_stop(channel);
106     break;
107   case 4:
108     glk_sound_load_hint(number, 0);
109   }
110
111 }
112
113 #endif