1 /*
2  * Schism Tracker - a cross-platform Impulse Tracker clone
3  * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
4  * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
5  * copyright (c) 2009 Storlek & Mrs. Brisby
6  * copyright (c) 2010-2012 Storlek
7  * URL: http://schismtracker.org/
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23 
24 #define NEED_TIME
25 #include "headers.h"
26 
27 #include "it.h"
28 #include "song.h"
29 #include "page.h"
30 
31 #include "sdlmain.h"
32 
33 #include "snd_gm.h"
34 
35 #include "disko.h"
36 
37 /* --------------------------------------------------------------------- */
38 
39 #define SAVED_AT_EXIT "System configuration will be saved at exit"
40 
41 static void config_set_page(void);
42 
43 static struct widget widgets_config[32];
44 
45 static const char *const time_displays[] = {
46 	"Off", "Play / Elapsed", "Play / Clock", "Play / Off", "Elapsed", "Clock", "Absolute", NULL
47 };
48 static const char *const vis_styles[] = {
49 	"Off", "Memory Stats", "Oscilloscope", "VU Meter", "Monoscope", "Spectrum", NULL
50 };
51 
52 static const char *const sharp_flat[] = {
53 	"Sharps (#)", "Flats (b)", NULL
54 };
55 
56 static const char *const output_channels[] = {
57 	"Mono", "Stereo", NULL
58 };
59 
60 static int sample_rate_cursor = 0;
61 
62 static const char *const bit_rates[] = { "8 Bit", "16 Bit", //"24 Bit", "32 Bit",
63 			NULL };
64 
65 static const char *const midi_modes[] = {
66 	"IT semantics", "Tracker semantics", NULL
67 };
68 
69 static const int video_fs_group[] = { 9, 10, -1 };
70 static int video_group[] = { 11, 12, 13, 14, -1 };
71 
change_mixer_limits(void)72 static void change_mixer_limits(void)
73 {
74 	audio_settings.channel_limit = widgets_config[0].d.thumbbar.value;
75 
76 	audio_settings.sample_rate = widgets_config[1].d.numentry.value;
77 	audio_settings.bits = widgets_config[2].d.menutoggle.state ? 16 : 8;
78 	audio_settings.channels = widgets_config[3].d.menutoggle.state+1;
79 
80 	song_init_modplug();
81 	status_text_flash(SAVED_AT_EXIT);
82 }
change_ui_settings(void)83 static void change_ui_settings(void)
84 {
85 	status.vis_style = widgets_config[4].d.menutoggle.state;
86 	status.time_display = widgets_config[7].d.menutoggle.state;
87 	if (widgets_config[5].d.toggle.state) {
88 		status.flags |= CLASSIC_MODE;
89 	} else {
90 		status.flags &= ~CLASSIC_MODE;
91 	}
92 	kbd_sharp_flat_toggle(widgets_config[6].d.menutoggle.state);
93 
94 	GM_Reset(0);
95 	if (widgets_config[8].d.toggle.state) {
96 		status.flags |= MIDI_LIKE_TRACKER;
97 	} else {
98 		status.flags &= ~MIDI_LIKE_TRACKER;
99 	}
100 
101 	status.flags |= NEED_UPDATE;
102 	status_text_flash(SAVED_AT_EXIT);
103 }
104 static int countdown = 10;
105 static time_t started = 0;
106 
107 static const char *video_revert_driver = NULL;
108 static int video_revert_fs = 0;
109 
video_mode_keep(UNUSED void * ign)110 static void video_mode_keep(UNUSED void*ign)
111 {
112 	status_text_flash(SAVED_AT_EXIT);
113 	config_set_page();
114 	status.flags |= NEED_UPDATE;
115 }
video_mode_cancel(UNUSED void * ign)116 static void video_mode_cancel(UNUSED void*ign)
117 {
118 	if (video_revert_driver) {
119 		video_setup(video_revert_driver);
120 		video_startup();
121 	}
122 	video_fullscreen(video_revert_fs);
123 	palette_apply();
124 	font_init();
125 	config_set_page();
126 	status.flags |= NEED_UPDATE;
127 }
128 
video_dialog_draw_const(void)129 static void video_dialog_draw_const(void)
130 {
131 	char buf[80];
132 	time_t now;
133 
134 	time(&now);
135 	if (now != started) {
136 		countdown--;
137 		time(&started); /* err... */
138 		status.flags |= NEED_UPDATE;
139 		if (countdown == 0) {
140 			dialog_destroy();
141 			video_mode_cancel(NULL);
142 			return;
143 		}
144 	}
145 
146 	draw_text("Your video settings have been changed.", 21,19,0,2);
147 	sprintf(buf, "In %2d seconds, your changes will be", countdown);
148 	draw_text(buf, 23, 21, 0, 2);
149 	draw_text("reverted to the last known-good", 21, 22, 0, 2);
150 	draw_text("settings.", 21, 23, 0, 2);
151 	draw_text("To use the new video mode, and make", 21, 24, 0, 2);
152 	draw_text("it default, select OK.", 21, 25, 0, 2);
153 }
154 
155 static struct widget video_dialog_widgets[2];
video_change_dialog(void)156 static void video_change_dialog(void)
157 {
158 	struct dialog *d;
159 
160 	video_revert_driver = video_driver_name();
161 	video_revert_fs = video_is_fullscreen();
162 
163 	countdown = 10;
164 	time(&started);
165 
166 	create_button(video_dialog_widgets+0, 28,28,8, 0, 0, 0, 1, 1,
167 					dialog_yes_NULL, "OK", 4);
168 	create_button(video_dialog_widgets+1, 42,28,8, 1, 1, 0, 1, 0,
169 					dialog_cancel_NULL, "Cancel", 2);
170 	d = dialog_create_custom(20, 17, 40, 14,
171 			video_dialog_widgets,
172 			2, 1,
173 			video_dialog_draw_const, NULL);
174 	d->action_yes = video_mode_keep;
175 	d->action_no = video_mode_cancel;
176 	d->action_cancel = video_mode_cancel;
177 }
178 
change_video_settings(void)179 static void change_video_settings(void)
180 {
181 	const char *new_video_driver;
182 	int new_fs_flag;
183 
184 	if (widgets_config[11].d.togglebutton.state) {
185 		new_video_driver = "sdl";
186 	} else if (widgets_config[12].d.togglebutton.state) {
187 		new_video_driver = "yuv";
188 	} else if (widgets_config[13].d.togglebutton.state) {
189 		new_video_driver = "gl";
190 	} else if (widgets_config[14].d.togglebutton.state) {
191 		new_video_driver = "directdraw";
192 	} else {
193 		new_video_driver = "sdl";
194 	}
195 
196 	if (widgets_config[9].d.togglebutton.state) {
197 		new_fs_flag = 1;
198 	} else {
199 		new_fs_flag = 0;
200 	}
201 
202 	if (!strcasecmp(new_video_driver, video_driver_name())
203 	&& new_fs_flag == video_is_fullscreen()) {
204 		return;
205 	}
206 
207 	video_change_dialog();
208 	if (strcasecmp(new_video_driver, video_driver_name())) {
209 		video_setup(new_video_driver);
210 		video_startup();
211 	}
212 	if (new_fs_flag != video_is_fullscreen())
213 		video_fullscreen(new_fs_flag);
214 	palette_apply();
215 	font_init();
216 }
217 
218 /* --------------------------------------------------------------------- */
219 
config_draw_const(void)220 static void config_draw_const(void)
221 {
222 	int n;
223 
224 	draw_text("Channel Limit",4,15, 0, 2);
225 	draw_text("Mixing Rate",6,16, 0, 2);
226 	draw_text("Sample Size",6,17, 0, 2);
227 	draw_text("Output Channels",2,18, 0, 2);
228 
229 	draw_text("Visualization",4,20, 0, 2);
230 	draw_text("Classic Mode",5,21, 0, 2);
231 	draw_text("Accidentals",6,22, 0, 2);
232 	draw_text("Time Display",5,23, 0, 2);
233 
234 	draw_text("MIDI mode", 8,25, 0, 2);
235 
236 	draw_text("Video Driver:", 2, 28, 0, 2);
237 	draw_text("Full Screen:", 38, 28, 0, 2);
238 
239 	draw_fill_chars(18, 15, 34, 25, 0);
240 	draw_box(17,14,35,26, BOX_THIN | BOX_INNER | BOX_INSET);
241 
242 	for (n = 18; n < 35; n++) {
243 		draw_char(154, n, 19, 3, 0);
244 		draw_char(154, n, 24, 3, 0);
245 	}
246 
247 }
config_set_page(void)248 static void config_set_page(void)
249 {
250 	const char *nn;
251 
252 	widgets_config[0].d.thumbbar.value = audio_settings.channel_limit;
253 	widgets_config[1].d.numentry.value = audio_settings.sample_rate;
254 	widgets_config[2].d.menutoggle.state = !!(audio_settings.bits == 16);
255 	widgets_config[3].d.menutoggle.state = audio_settings.channels-1;
256 
257 	widgets_config[4].d.menutoggle.state = status.vis_style;
258 	widgets_config[5].d.toggle.state = !!(status.flags & CLASSIC_MODE);
259 	widgets_config[6].d.menutoggle.state = !!(status.flags & ACCIDENTALS_AS_FLATS);
260 	widgets_config[7].d.menutoggle.state = status.time_display;
261 
262 	widgets_config[8].d.toggle.state = !!(status.flags & MIDI_LIKE_TRACKER);
263 
264 	widgets_config[9].d.togglebutton.state = video_is_fullscreen();
265 	widgets_config[10].d.togglebutton.state = !video_is_fullscreen();
266 
267 	nn = video_driver_name();
268 	widgets_config[11].d.togglebutton.state = (strcasecmp(nn,"sdl") == 0);
269 	widgets_config[12].d.togglebutton.state = (strcasecmp(nn,"yuv") == 0);
270 	widgets_config[13].d.togglebutton.state = (strcasecmp(nn,"opengl") == 0);
271 	widgets_config[14].d.togglebutton.state = (strcasecmp(nn,"directdraw") == 0);
272 }
273 
274 /* --------------------------------------------------------------------- */
config_load_page(struct page * page)275 void config_load_page(struct page *page)
276 {
277 	page->title = "System Configuration (Ctrl-F1)";
278 	page->draw_const = config_draw_const;
279 	page->set_page = config_set_page;
280 	page->total_widgets = 15;
281 	page->widgets = widgets_config;
282 	page->help_index = HELP_GLOBAL;
283 
284 	create_thumbbar(widgets_config+0,
285 			18, 15, 17,
286 			0,1,1,
287 			change_mixer_limits, 4, 256);
288 	create_numentry(widgets_config+1,
289 			18, 16, 7,
290 			0,2,2,
291 			change_mixer_limits,
292 			4000, 192000,
293 			&sample_rate_cursor);
294 	create_menutoggle(widgets_config+2,
295 			18, 17,
296 			1,3,2,2,3,
297 			change_mixer_limits,
298 			bit_rates);
299 	create_menutoggle(widgets_config+3,
300 			18, 18,
301 			2,4,3,3,4,
302 			change_mixer_limits,
303 			output_channels);
304     ////
305 	create_menutoggle(widgets_config+4,
306 			18, 20,
307 			3,5,4,4,5,
308 			change_ui_settings,
309 			vis_styles);
310 	create_toggle(widgets_config+5,
311 			18, 21,
312 			4,6,5,5,6,
313 			change_ui_settings);
314 	create_menutoggle(widgets_config+6,
315 			18, 22,
316 			5,7,6,6,7,
317 			change_ui_settings,
318 			sharp_flat);
319 	create_menutoggle(widgets_config+7,
320 			18, 23,
321 			6,8,7,7,8,
322 			change_ui_settings,
323 			time_displays);
324     ////
325 	create_menutoggle(widgets_config+8,
326 			18, 25,
327 			7,11,8,8,11,
328 			change_ui_settings,
329 			midi_modes);
330     ////
331 	create_togglebutton(widgets_config+9,
332 			44, 30, 5,
333 			8,9,11,10,10,
334 			change_video_settings,
335 			"Yes",
336 			2, video_fs_group);
337 	create_togglebutton(widgets_config+10,
338 			54, 30, 5,
339 			10,10,9,10,0,
340 			change_video_settings,
341 			"No",
342 			2, video_fs_group);
343     ////
344 	create_togglebutton(widgets_config+11,
345 			6, 30, 26,
346 			8,12,11,9,12,
347 			change_video_settings,
348 			"SDL Video Surface",
349 			2, video_group);
350 
351 	create_togglebutton(widgets_config+12,
352 			6, 33, 26,
353 			11,13,12,9,13,
354 			change_video_settings,
355 			"YUV Video Overlay",
356 			2, video_group);
357 
358 	create_togglebutton(widgets_config+13,
359 			6, 36, 26,
360 			12,14,13,9,14,
361 			change_video_settings,
362 			"OpenGL Graphic Context",
363 			2, video_group);
364 
365 	create_togglebutton(widgets_config+14,
366 			6, 39, 26,
367 			13,14,14,9,9,
368 			change_video_settings,
369 			"DirectDraw Surface",
370 			2, video_group);
371 #ifndef WIN32
372 	/* patch ddraw out */
373 	video_group[3] = -1;
374 	widgets_config[14].d.togglebutton.state = 0;
375 	widgets_config[13].next.down = 13;
376 	widgets_config[13].next.tab = 9;
377 	page->total_widgets--;
378 #endif
379 
380 }
381