1 #include "sound_options.h"
2 
3 #include "game/settings.h"
4 #include "graphics/arrow_button.h"
5 #include "graphics/generic_button.h"
6 #include "graphics/graphics.h"
7 #include "graphics/lang_text.h"
8 #include "graphics/panel.h"
9 #include "graphics/text.h"
10 #include "graphics/window.h"
11 #include "input/input.h"
12 #include "sound/city.h"
13 #include "sound/effect.h"
14 #include "sound/music.h"
15 #include "sound/speech.h"
16 
17 static void button_toggle(int type, int param2);
18 static void button_ok(int param1, int param2);
19 static void button_cancel(int param1, int param2);
20 
21 static void arrow_button_music(int is_down, int param2);
22 static void arrow_button_speech(int is_down, int param2);
23 static void arrow_button_effects(int is_down, int param2);
24 static void arrow_button_city(int is_down, int param2);
25 
26 static generic_button buttons[] = {
27     {64, 162, 224, 20, button_toggle, button_none, SOUND_MUSIC, 0},
28     {64, 192, 224, 20, button_toggle, button_none, SOUND_SPEECH, 0},
29     {64, 222, 224, 20, button_toggle, button_none, SOUND_EFFECTS, 0},
30     {64, 252, 224, 20, button_toggle, button_none, SOUND_CITY, 0},
31     {144, 296, 192, 20, button_ok, button_none, 1, 0},
32     {144, 326, 192, 20, button_cancel, button_none, 1, 0},
33 };
34 
35 static arrow_button arrow_buttons[] = {
36     {112, 100, 17, 24, arrow_button_music, 1, 0},
37     {136, 100, 15, 24, arrow_button_music, 0, 0},
38     {112, 130, 17, 24, arrow_button_speech, 1, 0},
39     {136, 130, 15, 24, arrow_button_speech, 0, 0},
40     {112, 160, 17, 24, arrow_button_effects, 1, 0},
41     {136, 160, 15, 24, arrow_button_effects, 0, 0},
42     {112, 190, 17, 24, arrow_button_city, 1, 0},
43     {136, 190, 15, 24, arrow_button_city, 0, 0},
44 };
45 
46 static struct {
47     int focus_button_id;
48     void (*close_callback)(void);
49 
50     set_sound original_effects;
51     set_sound original_music;
52     set_sound original_speech;
53     set_sound original_city;
54 } data;
55 
init(void (* close_callback)(void))56 static void init(void (*close_callback)(void))
57 {
58     data.focus_button_id = 0;
59     data.close_callback = close_callback;
60 
61     data.original_effects = *setting_sound(SOUND_EFFECTS);
62     data.original_music = *setting_sound(SOUND_MUSIC);
63     data.original_speech = *setting_sound(SOUND_SPEECH);
64     data.original_city = *setting_sound(SOUND_CITY);
65 }
66 
draw_foreground(void)67 static void draw_foreground(void)
68 {
69     graphics_in_dialog();
70 
71     outer_panel_draw(48, 80, 24, 18);
72 
73     // on/off labels
74     label_draw(64, 162, 14, data.focus_button_id == 1 ? 1 : 2);
75     label_draw(64, 192, 14, data.focus_button_id == 2 ? 1 : 2);
76     label_draw(64, 222, 14, data.focus_button_id == 3 ? 1 : 2);
77     label_draw(64, 252, 14, data.focus_button_id == 4 ? 1 : 2);
78     // ok/cancel labels
79     label_draw(144, 296, 12, data.focus_button_id == 5 ? 1 : 2);
80     label_draw(144, 326, 12, data.focus_button_id == 6 ? 1 : 2);
81 
82     // title
83     lang_text_draw_centered(46, 0, 96, 92, 288, FONT_LARGE_BLACK);
84 
85     lang_text_draw_centered(46, 12, 128, 300, 224, FONT_NORMAL_GREEN);
86     lang_text_draw_centered(46, 9, 128, 330, 224, FONT_NORMAL_GREEN);
87 
88     lang_text_draw(46, 10, 112, 142, FONT_SMALL_PLAIN);
89     lang_text_draw(46, 11, 336, 142, FONT_SMALL_PLAIN);
90 
91     const set_sound *music = setting_sound(SOUND_MUSIC);
92     lang_text_draw_centered(46, music->enabled ? 2 : 1, 64, 166, 224, FONT_NORMAL_GREEN);
93     text_draw_percentage(music->volume, 374, 166, FONT_NORMAL_PLAIN);
94 
95     const set_sound *speech = setting_sound(SOUND_SPEECH);
96     lang_text_draw_centered(46, speech->enabled ? 4 : 3, 64, 196, 224, FONT_NORMAL_GREEN);
97     text_draw_percentage(speech->volume, 374, 196, FONT_NORMAL_PLAIN);
98 
99     const set_sound *effects = setting_sound(SOUND_EFFECTS);
100     lang_text_draw_centered(46, effects->enabled ? 6 : 5, 64, 226, 224, FONT_NORMAL_GREEN);
101     text_draw_percentage(effects->volume, 374, 226, FONT_NORMAL_PLAIN);
102 
103     const set_sound *city = setting_sound(SOUND_CITY);
104     lang_text_draw_centered(46, city->enabled ? 8 : 7, 64, 256, 224, FONT_NORMAL_GREEN);
105     text_draw_percentage(city->volume, 374, 256, FONT_NORMAL_PLAIN);
106 
107     arrow_buttons_draw(208, 60, arrow_buttons, 8);
108 
109     graphics_reset_dialog();
110 }
111 
handle_input(const mouse * m,const hotkeys * h)112 static void handle_input(const mouse *m, const hotkeys *h)
113 {
114     const mouse *m_dialog = mouse_in_dialog(m);
115     if (generic_buttons_handle_mouse(m_dialog, 0, 0, buttons, 6, &data.focus_button_id) ||
116         arrow_buttons_handle_mouse(m_dialog, 208, 60, arrow_buttons, 8, 0)) {
117         return;
118     }
119     if (input_go_back_requested(m, h)) {
120         data.close_callback();
121     }
122 }
123 
button_toggle(int type,int param2)124 static void button_toggle(int type, int param2)
125 {
126     setting_toggle_sound_enabled(type);
127     if (type == SOUND_MUSIC) {
128         if (setting_sound(SOUND_MUSIC)->enabled) {
129             sound_music_update(1);
130         } else {
131             sound_music_stop();
132         }
133     } else if (type == SOUND_SPEECH) {
134         if (!setting_sound(SOUND_SPEECH)->enabled) {
135             sound_speech_stop();
136         }
137     }
138 }
139 
button_ok(int param1,int param2)140 static void button_ok(int param1, int param2)
141 {
142     data.close_callback();
143 }
144 
button_cancel(int param1,int param2)145 static void button_cancel(int param1, int param2)
146 {
147     setting_reset_sound(SOUND_EFFECTS, data.original_effects.enabled, data.original_effects.volume);
148     setting_reset_sound(SOUND_MUSIC, data.original_music.enabled, data.original_music.volume);
149     setting_reset_sound(SOUND_SPEECH, data.original_speech.enabled, data.original_speech.volume);
150     setting_reset_sound(SOUND_CITY, data.original_city.enabled, data.original_city.volume);
151     if (data.original_music.enabled) {
152         if (setting_sound_is_enabled(SOUND_MUSIC) != data.original_music.enabled) {
153             sound_music_update(1);
154         }
155     } else {
156         sound_music_stop();
157     }
158     sound_music_set_volume(data.original_music.volume);
159     sound_speech_set_volume(data.original_speech.volume);
160     sound_effect_set_volume(data.original_effects.volume);
161     sound_city_set_volume(data.original_city.volume);
162 
163     data.close_callback();
164 }
165 
update_volume(set_sound_type type,int is_decrease)166 static void update_volume(set_sound_type type, int is_decrease)
167 {
168     if (is_decrease) {
169         setting_decrease_sound_volume(type);
170     } else {
171         setting_increase_sound_volume(type);
172     }
173 }
174 
arrow_button_music(int is_down,int param2)175 static void arrow_button_music(int is_down, int param2)
176 {
177     update_volume(SOUND_MUSIC, is_down);
178     sound_music_set_volume(setting_sound(SOUND_MUSIC)->volume);
179 }
180 
arrow_button_speech(int is_down,int param2)181 static void arrow_button_speech(int is_down, int param2)
182 {
183     update_volume(SOUND_SPEECH, is_down);
184     sound_speech_set_volume(setting_sound(SOUND_SPEECH)->volume);
185 }
186 
arrow_button_effects(int is_down,int param2)187 static void arrow_button_effects(int is_down, int param2)
188 {
189     update_volume(SOUND_EFFECTS, is_down);
190     sound_effect_set_volume(setting_sound(SOUND_EFFECTS)->volume);
191 }
192 
arrow_button_city(int is_down,int param2)193 static void arrow_button_city(int is_down, int param2)
194 {
195     update_volume(SOUND_CITY, is_down);
196     sound_city_set_volume(setting_sound(SOUND_CITY)->volume);
197 }
198 
window_sound_options_show(void (* close_callback)(void))199 void window_sound_options_show(void (*close_callback)(void))
200 {
201     window_type window = {
202         WINDOW_SOUND_OPTIONS,
203         window_draw_underlying_window,
204         draw_foreground,
205         handle_input,
206     };
207     init(close_callback);
208     window_show(&window);
209 }
210