1 // for finding memory leaks in debug mode with Visual Studio
2 #if defined _DEBUG && defined _MSC_VER
3 #include <crtdbg.h>
4 #endif
5 
6 #include <stdint.h>
7 #include <stdio.h>
8 #include <math.h>
9 #ifdef _WIN32
10 #define _WIN32_IE 0x0500
11 #define WIN32_MEAN_AND_LEAN
12 #include <windows.h>
13 #include <shlobj.h>
14 #include <direct.h>
15 #else
16 #include <sys/stat.h>
17 #include <unistd.h>
18 #endif
19 #include "ft2_header.h"
20 #include "ft2_video.h"
21 #include "ft2_audio.h"
22 #include "ft2_config.h"
23 #include "ft2_gui.h"
24 #include "ft2_pattern_ed.h"
25 #include "ft2_mouse.h"
26 #include "ft2_wav_renderer.h"
27 #include "ft2_sampling.h"
28 #include "ft2_audioselector.h"
29 #include "ft2_midi.h"
30 #include "ft2_palette.h"
31 #include "ft2_pattern_draw.h"
32 #include "ft2_tables.h"
33 #include "ft2_bmp.h"
34 #include "ft2_structs.h"
35 #include "ft2_cpu.h"
36 
37 config_t config; // globalized
38 
39 #ifdef _MSC_VER // hide POSIX warnings
40 #pragma warning(disable: 4996)
41 #endif
42 
43 static uint8_t configBuffer[CONFIG_FILE_SIZE];
44 
xorConfigBuffer(uint8_t * ptr8)45 static void xorConfigBuffer(uint8_t *ptr8)
46 {
47 	for (int32_t i = 0; i < CONFIG_FILE_SIZE; i++)
48 		ptr8[i] ^= i*7;
49 }
50 
calcChecksum(const uint8_t * p,uint16_t len)51 static int32_t calcChecksum(const uint8_t *p, uint16_t len) // for Nibbles highscore data
52 {
53 	if (len == 0)
54 		return 0;
55 
56 	uint16_t data = 0;
57 	uint32_t checksum = 0;
58 
59 	for (uint16_t i = len; i > 0; i--)
60 	{
61 		data = ((data | *p++) + i) ^ i;
62 		checksum += data;
63 		data <<= 8;
64 	}
65 
66 	return checksum;
67 }
68 
loadConfigFromBuffer(bool defaults)69 static void loadConfigFromBuffer(bool defaults)
70 {
71 	lockMixerCallback();
72 
73 	assert(sizeof(config) == CONFIG_FILE_SIZE);
74 	memcpy(&config, configBuffer, CONFIG_FILE_SIZE);
75 
76 	if (defaults)
77 		config.audioFreq = DEFAULT_AUDIO_FREQ;
78 
79 	if (config.audioFreq > MAX_AUDIO_FREQ)
80 		config.audioFreq = MAX_AUDIO_FREQ;
81 
82 	// if Nibbles highscore checksum is incorrect, load default highscores instead
83 	const int32_t newChecksum = calcChecksum((uint8_t *)&config.NI_HighScore, sizeof (config.NI_HighScore));
84 	if (newChecksum != config.NI_HighScoreChecksum)
85 		memcpy(&config.NI_HighScore, &defConfigData[636], sizeof (config.NI_HighScore));
86 
87 	// sanitize Nibbles highscore names
88 	for (int32_t i = 0; i < 10; i++)
89 	{
90 		config.NI_HighScore[i].name[21] = '\0';
91 		if (config.NI_HighScore[i].nameLen > 21)
92 			config.NI_HighScore[i].nameLen = 21;
93 	}
94 
95 	// clamp user palette values
96 	for (int32_t i = 0; i < 16; i++)
97 	{
98 		config.userPal->r = palMax(config.userPal->r);
99 		config.userPal->g = palMax(config.userPal->g);
100 		config.userPal->b = palMax(config.userPal->b);
101 	}
102 
103 	// copy over user palette
104 	memcpy(palTable[11], config.userPal, sizeof (pal16) * 16);
105 
106 	// sanitize certain values
107 
108 	config.modulesPath[80-1] = '\0';
109 	config.instrPath[80-1] = '\0';
110 	config.samplesPath[80-1] = '\0';
111 	config.patternsPath[80-1] = '\0';
112 	config.tracksPath[80-1] = '\0';
113 
114 	// clear data after the actual Pascal string length. FT2 can save garbage in that area.
115 
116 	if (config.modulesPathLen < 80)
117 		memset(&config.modulesPath[config.modulesPathLen], 0, 80-config.modulesPathLen);
118 
119 	if (config.instrPathLen < 80)
120 		memset(&config.instrPath[config.instrPathLen], 0, 80-config.instrPathLen);
121 
122 	if (config.samplesPathLen < 80)
123 		memset(&config.samplesPath[config.samplesPathLen], 0, 80-config.samplesPathLen);
124 
125 	if (config.patternsPathLen < 80)
126 		memset(&config.patternsPath[config.patternsPathLen], 0, 80-config.patternsPathLen);
127 
128 	if (config.tracksPathLen < 80)
129 		memset(&config.tracksPath[config.tracksPathLen], 0, 80-config.tracksPathLen);
130 
131 	config.boostLevel = CLAMP(config.boostLevel, 1, 32);
132 	config.masterVol = CLAMP(config.masterVol, 0, 256);
133 	config.ptnMaxChannels = CLAMP(config.ptnMaxChannels, 0, 3);
134 	config.ptnFont = CLAMP(config.ptnFont, 0, 3);
135 	config.mouseType = CLAMP(config.mouseType, 0, 3);
136 	config.cfg_StdPalNum = CLAMP(config.cfg_StdPalNum, 0, 11);
137 	config.cfg_SortPriority = CLAMP(config.cfg_SortPriority, 0, 1);
138 	config.NI_NumPlayers = CLAMP(config.NI_NumPlayers, 0, 1);
139 	config.NI_Speed = CLAMP(config.NI_Speed, 0, 3);
140 	config.recMIDIVolSens = CLAMP(config.recMIDIVolSens, 0, 200);
141 	config.recMIDIChn  = CLAMP(config.recMIDIChn, 1, 16);
142 
143 	config.interpolation &= 3; // one extra bit used in FT2 clone (off, sinc, linear)
144 
145 	if (config.recTrueInsert > 1)
146 		config.recTrueInsert = 1;
147 
148 	if (config.mouseAnimType != 0 && config.mouseAnimType != 2)
149 		config.mouseAnimType = 0;
150 
151 	if (config.recQuantRes != 1 && config.recQuantRes != 2 && config.recQuantRes != 4 &&
152 		config.recQuantRes != 8 && config.recQuantRes != 16)
153 	{
154 		config.recQuantRes = 16;
155 	}
156 
157 #if CPU_64BIT
158 	if (config.audioFreq != 44100 && config.audioFreq != 48000 && config.audioFreq != 96000 && config.audioFreq != 192000)
159 #else
160 	if (config.audioFreq != 44100 && config.audioFreq != 48000)
161 #endif
162 		config.audioFreq = DEFAULT_AUDIO_FREQ;
163 
164 	if (config.audioInputFreq <= 1) // default value from FT2 (this was cdr_Sync) - set defaults
165 		config.audioInputFreq = INPUT_FREQ_48KHZ;
166 
167 	if (config.specialFlags == 64) // default value from FT2 (this was ptnDefaultLen byte #1) - set defaults
168 		config.specialFlags = BUFFSIZE_1024 | BITDEPTH_16;
169 
170 	if (config.specialFlags & 64) // deprecated BUFFSIZE_4096 ("Very large") setting
171 	{
172 		// set to current highest setting ("Large" aka. 2048)
173 		config.specialFlags &= ~(BUFFSIZE_1024 + 64);
174 		config.specialFlags |= BUFFSIZE_2048;
175 	}
176 
177 	if (config.windowFlags == 0) // default value from FT2 (this was ptnDefaultLen byte #2) - set defaults
178 		config.windowFlags = WINSIZE_AUTO;
179 
180 	// audio bit depth - remove 32-bit flag if both are enabled
181 	if ((config.specialFlags & BITDEPTH_16) && (config.specialFlags & BITDEPTH_32))
182 		config.specialFlags &= ~BITDEPTH_32;
183 
184 	if (audio.dev != 0)
185 		setNewAudioSettings();
186 
187 	audioSetInterpolationType(config.interpolation);
188 	audioSetVolRamp((config.specialFlags & NO_VOLRAMP_FLAG) ? false : true);
189 	setAudioAmp(config.boostLevel, config.masterVol, !!(config.specialFlags & BITDEPTH_32));
190 	setMouseShape(config.mouseType);
191 	changeLogoType(config.id_FastLogo);
192 	changeBadgeType(config.id_TritonProd);
193 	ui.maxVisibleChannels = (uint8_t)(2 + ((config.ptnMaxChannels + 1) * 2));
194 	setPal16(palTable[config.cfg_StdPalNum], true);
195 	updatePattFontPtrs();
196 
197 	unlockMixerCallback();
198 }
199 
configDrawAmp(void)200 static void configDrawAmp(void)
201 {
202 	char str[8];
203 	sprintf(str, "%02d", config.boostLevel);
204 	textOutFixed(607, 120, PAL_FORGRND, PAL_DESKTOP, str);
205 }
206 
setDefaultConfigSettings(void)207 static void setDefaultConfigSettings(void)
208 {
209 	memcpy(configBuffer, defConfigData, CONFIG_FILE_SIZE);
210 	loadConfigFromBuffer(true);
211 }
212 
resetConfig(void)213 void resetConfig(void)
214 {
215 	if (okBox(2, "System request", "Are you sure you want to reset your FT2 configuration?") != 1)
216 		return;
217 
218 	const uint8_t oldWindowFlags = config.windowFlags;
219 
220 	setDefaultConfigSettings();
221 	setToDefaultAudioOutputDevice();
222 	setToDefaultAudioInputDevice();
223 
224 	saveConfig(false);
225 
226 	// redraw new changes
227 	showTopScreen(false);
228 	showBottomScreen();
229 
230 	setWindowSizeFromConfig(true);
231 
232 	// handle pixel filter change
233 	if ((oldWindowFlags & PIXEL_FILTER) != (config.windowFlags & PIXEL_FILTER))
234 	{
235 		recreateTexture();
236 		if (video.fullscreen)
237 		{
238 			leaveFullScreen();
239 			enterFullscreen();
240 		}
241 	}
242 
243 	if (config.specialFlags2 & HARDWARE_MOUSE)
244 		SDL_ShowCursor(SDL_TRUE);
245 	else
246 		SDL_ShowCursor(SDL_FALSE);
247 }
248 
loadConfig(bool showErrorFlag)249 bool loadConfig(bool showErrorFlag)
250 {
251 	// this routine can be called at any time, so make sure we free these first...
252 
253 	if (audio.currOutputDevice != NULL)
254 	{
255 		free(audio.currOutputDevice);
256 		audio.currOutputDevice = NULL;
257 	}
258 
259 	if (audio.currInputDevice != NULL)
260 	{
261 		free(audio.currInputDevice);
262 		audio.currInputDevice = NULL;
263 	}
264 
265 	// now we can get the audio devices from audiodev.ini
266 
267 	audio.currOutputDevice = getAudioOutputDeviceFromConfig();
268 	audio.currInputDevice = getAudioInputDeviceFromConfig();
269 
270 #ifdef HAS_MIDI
271 	if (midi.initThreadDone)
272 	{
273 		setMidiInputDeviceFromConfig();
274 		if (ui.configScreenShown && editor.currConfigScreen == CONFIG_SCREEN_MIDI_INPUT)
275 			drawMidiInputList();
276 	}
277 #endif
278 
279 	if (editor.configFileLocationU == NULL)
280 	{
281 		if (showErrorFlag)
282 			okBox(0, "System message", "Error opening config file for reading!");
283 
284 		return false;
285 	}
286 
287 	FILE *f = UNICHAR_FOPEN(editor.configFileLocationU, "rb");
288 	if (f == NULL)
289 	{
290 		if (showErrorFlag)
291 			okBox(0, "System message", "Error opening config file for reading!");
292 
293 		return false;
294 	}
295 
296 	fseek(f, 0, SEEK_END);
297 	const size_t fileSize = ftell(f);
298 	rewind(f);
299 
300 	// check if it's a valid FT2 config file (FT2.CFG filesize varies depending on version)
301 	if (fileSize < 1732 || fileSize > CONFIG_FILE_SIZE)
302 	{
303 		fclose(f);
304 		if (showErrorFlag)
305 			okBox(0, "System message", "Error loading config: the config file is not valid!");
306 
307 		return false;
308 	}
309 
310 	if (fileSize < CONFIG_FILE_SIZE) // old version, make sure unloaded entries are zeroed out
311 		memset(configBuffer, 0, CONFIG_FILE_SIZE);
312 
313 	// read to config buffer and close file handle
314 	if (fread(configBuffer, fileSize, 1, f) != 1)
315 	{
316 		fclose(f);
317 		if (showErrorFlag)
318 			okBox(0, "System message", "Error opening config file for reading!");
319 
320 		return false;
321 	}
322 
323 	fclose(f);
324 
325 	xorConfigBuffer(configBuffer); // decrypt config buffer
326 
327 	if (memcmp(&configBuffer[0], CFG_ID_STR, 35) != 0)
328 	{
329 		if (showErrorFlag)
330 			okBox(0, "System message", "Error loading config: the config file is not valid!");
331 
332 		return false;
333 	}
334 
335 	loadConfigFromBuffer(false);
336 	return true;
337 }
338 
loadConfig2(void)339 void loadConfig2(void) // called by "Load config" button
340 {
341 	const uint8_t oldWindowFlags = config.windowFlags;
342 
343 	loadConfig(CONFIG_SHOW_ERRORS);
344 
345 	// redraw new changes
346 	showTopScreen(false);
347 	showBottomScreen();
348 
349 	// handle pixel filter change
350 	if ((oldWindowFlags & PIXEL_FILTER) != (config.windowFlags & PIXEL_FILTER))
351 	{
352 		recreateTexture();
353 		if (video.fullscreen)
354 		{
355 			leaveFullScreen();
356 			enterFullscreen();
357 		}
358 	}
359 
360 	if (config.specialFlags2 & HARDWARE_MOUSE)
361 		SDL_ShowCursor(SDL_TRUE);
362 	else
363 		SDL_ShowCursor(SDL_FALSE);
364 }
365 
saveConfig(bool showErrorFlag)366 bool saveConfig(bool showErrorFlag)
367 {
368 	if (editor.configFileLocationU == NULL)
369 	{
370 		if (showErrorFlag)
371 			okBox(0, "System message", "General I/O error during saving! Is the file in use?");
372 
373 		return false;
374 	}
375 
376 	saveAudioDevicesToConfig(audio.currOutputDevice, audio.currInputDevice);
377 #ifdef HAS_MIDI
378 	saveMidiInputDeviceToConfig();
379 #endif
380 
381 	FILE *f = UNICHAR_FOPEN(editor.configFileLocationU, "wb");
382 	if (f == NULL)
383 	{
384 		if (showErrorFlag)
385 			okBox(0, "System message", "General I/O error during config saving! Is the file in use?");
386 
387 		return false;
388 	}
389 
390 	config.NI_HighScoreChecksum = calcChecksum((uint8_t *)config.NI_HighScore, sizeof (config.NI_HighScore));
391 
392 	// set default path lengths (Pascal strings)
393 	config.modulesPathLen = (uint8_t)strlen(config.modulesPath);
394 	config.instrPathLen = (uint8_t)strlen(config.instrPath);
395 	config.samplesPathLen = (uint8_t)strlen(config.samplesPath);
396 	config.patternsPathLen = (uint8_t)strlen(config.patternsPath);
397 	config.tracksPathLen = (uint8_t)strlen(config.tracksPath);
398 
399 	// copy over user palette
400 	memcpy(config.userPal, palTable[11], sizeof (pal16) * 16);
401 
402 	// copy config to buffer and encrypt it
403 	memcpy(configBuffer, &config, CONFIG_FILE_SIZE);
404 	xorConfigBuffer(configBuffer);
405 
406 	if (fwrite(configBuffer, 1, CONFIG_FILE_SIZE, f) != CONFIG_FILE_SIZE)
407 	{
408 		fclose(f);
409 
410 		if (showErrorFlag)
411 			okBox(0, "System message", "General I/O error during config saving! Is the file in use?");
412 
413 		return false;
414 	}
415 
416 	fclose(f);
417 	return true;
418 }
419 
saveConfig2(void)420 void saveConfig2(void) // called by "Save config" button
421 {
422 	saveConfig(CONFIG_SHOW_ERRORS);
423 }
424 
getFullAudDevConfigPathU(void)425 static UNICHAR *getFullAudDevConfigPathU(void) // kinda hackish
426 {
427 	int32_t audiodevDotIniStrLen, ft2DotCfgStrLen;
428 
429 	if (editor.configFileLocationU == NULL)
430 		return NULL;
431 
432 	const int32_t ft2ConfPathLen = (int32_t)UNICHAR_STRLEN(editor.configFileLocationU);
433 
434 #ifdef _WIN32
435 	audiodevDotIniStrLen = (int32_t)UNICHAR_STRLEN(L"audiodev.ini");
436 	ft2DotCfgStrLen = (int32_t)UNICHAR_STRLEN(L"FT2.CFG");
437 #else
438 	audiodevDotIniStrLen = (int32_t)UNICHAR_STRLEN("audiodev.ini");
439 	ft2DotCfgStrLen = (int32_t)UNICHAR_STRLEN("FT2.CFG");
440 #endif
441 
442 	UNICHAR *filePathU = (UNICHAR *)malloc((ft2ConfPathLen + audiodevDotIniStrLen + 1) * sizeof (UNICHAR));
443 	filePathU[0] = 0;
444 
445 	UNICHAR_STRCPY(filePathU, editor.configFileLocationU);
446 	filePathU[ft2ConfPathLen-ft2DotCfgStrLen] = 0;
447 
448 #ifdef _WIN32
449 	UNICHAR_STRCAT(filePathU, L"audiodev.ini");
450 #else
451 	UNICHAR_STRCAT(filePathU, "audiodev.ini");
452 #endif
453 
454 	return filePathU;
455 }
456 
getFullMidiDevConfigPathU(void)457 static UNICHAR *getFullMidiDevConfigPathU(void) // kinda hackish
458 {
459 	int32_t mididevDotIniStrLen, ft2DotCfgStrLen;
460 
461 	if (editor.configFileLocationU == NULL)
462 		return NULL;
463 
464 	const int32_t ft2ConfPathLen = (int32_t)UNICHAR_STRLEN(editor.configFileLocationU);
465 
466 #ifdef _WIN32
467 	mididevDotIniStrLen = (int32_t)UNICHAR_STRLEN(L"mididev.ini");
468 	ft2DotCfgStrLen = (int32_t)UNICHAR_STRLEN(L"FT2.CFG");
469 #else
470 	mididevDotIniStrLen = (int32_t)UNICHAR_STRLEN("mididev.ini");
471 	ft2DotCfgStrLen = (int32_t)UNICHAR_STRLEN("FT2.CFG");
472 #endif
473 
474 	UNICHAR *filePathU = (UNICHAR *)malloc((ft2ConfPathLen + mididevDotIniStrLen + 1) * sizeof (UNICHAR));
475 	filePathU[0] = 0;
476 
477 	UNICHAR_STRCPY(filePathU, editor.configFileLocationU);
478 	filePathU[ft2ConfPathLen-ft2DotCfgStrLen] = 0;
479 
480 #ifdef _WIN32
481 	UNICHAR_STRCAT(filePathU, L"mididev.ini");
482 #else
483 	UNICHAR_STRCAT(filePathU, "mididev.ini");
484 #endif
485 
486 	return filePathU;
487 }
488 
setConfigFileLocation(void)489 static void setConfigFileLocation(void) // kinda hackish
490 {
491 	// Windows
492 #ifdef _WIN32
493 	int32_t ft2DotCfgStrLen = (int32_t)UNICHAR_STRLEN(L"FT2.CFG");
494 
495 	UNICHAR *oldPathU = (UNICHAR *)malloc((PATH_MAX + 8 + 1) * sizeof (UNICHAR));
496 	UNICHAR *tmpPathU = (UNICHAR *)malloc((PATH_MAX + 8 + 1) * sizeof (UNICHAR));
497 	editor.configFileLocationU = (UNICHAR *)malloc((PATH_MAX + ft2DotCfgStrLen + 1) * sizeof (UNICHAR));
498 
499 	if (oldPathU == NULL || tmpPathU == NULL || editor.configFileLocationU == NULL)
500 	{
501 		if (oldPathU != NULL) free(oldPathU);
502 		if (tmpPathU != NULL) free(tmpPathU);
503 		if (editor.configFileLocationU != NULL) free(editor.configFileLocationU);
504 
505 		editor.configFileLocationU = NULL;
506 		showErrorMsgBox("Error: Couldn't set config file location. You can't load/save the config!");
507 		return;
508 	}
509 
510 	oldPathU[0] = 0;
511 	tmpPathU[0] = 0;
512 
513 	if (GetCurrentDirectoryW(PATH_MAX - ft2DotCfgStrLen - 1, oldPathU) == 0)
514 	{
515 		free(oldPathU);
516 		free(tmpPathU);
517 		free(editor.configFileLocationU);
518 
519 		editor.configFileLocationU = NULL;
520 		showErrorMsgBox("Error: Couldn't set config file location. You can't load/save the config!");
521 		return;
522 	}
523 
524 	UNICHAR_STRCPY(editor.configFileLocationU, oldPathU);
525 
526 	FILE *f = fopen("FT2.CFG", "rb");
527 	if (f == NULL) // FT2.CFG not found in current dir, try default config dir
528 	{
529 		int32_t result = SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, tmpPathU);
530 		if (result == S_OK)
531 		{
532 			if (SetCurrentDirectoryW(tmpPathU) != 0)
533 			{
534 				result = chdir("FT2 clone");
535 				if (result != 0)
536 				{
537 					_mkdir("FT2 clone");
538 					result = chdir("FT2 clone");
539 				}
540 
541 				if (result == 0)
542 					GetCurrentDirectoryW(PATH_MAX - ft2DotCfgStrLen - 1, editor.configFileLocationU); // we can, set it
543 			}
544 		}
545 	}
546 	else
547 	{
548 		fclose(f);
549 	}
550 
551 	free(tmpPathU);
552 	SetCurrentDirectoryW(oldPathU);
553 	free(oldPathU);
554 
555 	UNICHAR_STRCAT(editor.configFileLocationU, L"\\FT2.CFG");
556 
557 	// OS X / macOS
558 #elif defined __APPLE__
559 	int32_t ft2DotCfgStrLen = (int32_t)UNICHAR_STRLEN("FT2.CFG");
560 
561 	editor.configFileLocationU = (UNICHAR *)malloc((PATH_MAX + ft2DotCfgStrLen + 1) * sizeof (UNICHAR));
562 	if (editor.configFileLocationU == NULL)
563 	{
564 		showErrorMsgBox("Error: Couldn't set config file location. You can't load/save the config!");
565 		return;
566 	}
567 
568 	editor.configFileLocationU[0] = 0;
569 
570 	if (getcwd(editor.configFileLocationU, PATH_MAX - ft2DotCfgStrLen - 1) == NULL)
571 	{
572 		free(editor.configFileLocationU);
573 		editor.configFileLocationU = NULL;
574 		showErrorMsgBox("Error: Couldn't set config file location. You can't load/save the config!");
575 		return;
576 	}
577 
578 	FILE *f = fopen("FT2.CFG", "rb");
579 	if (f == NULL) // FT2.CFG not found in current dir, try default config dir
580 	{
581 		if (chdir(getenv("HOME")) == 0)
582 		{
583 			int32_t result = chdir("Library/Application Support");
584 			if (result == 0)
585 			{
586 				result = chdir("FT2 clone");
587 				if (result != 0)
588 				{
589 					mkdir("FT2 clone", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
590 					result = chdir("FT2 clone");
591 				}
592 
593 				if (result == 0)
594 					getcwd(editor.configFileLocationU, PATH_MAX - ft2DotCfgStrLen - 1);
595 			}
596 		}
597 	}
598 	else
599 	{
600 		fclose(f);
601 	}
602 
603 	strcat(editor.configFileLocationU, "/FT2.CFG");
604 
605 	// Linux etc
606 #else
607 	int32_t ft2DotCfgStrLen = (int32_t)UNICHAR_STRLEN("FT2.CFG");
608 
609 	editor.configFileLocationU = (UNICHAR *)malloc((PATH_MAX + ft2DotCfgStrLen + 1) * sizeof (UNICHAR));
610 	if (editor.configFileLocationU == NULL)
611 	{
612 		showErrorMsgBox("Error: Couldn't set config file location. You can't load/save the config!");
613 		return;
614 	}
615 
616 	editor.configFileLocationU[0] = 0;
617 
618 	if (getcwd(editor.configFileLocationU, PATH_MAX - ft2DotCfgStrLen - 1) == NULL)
619 	{
620 		free(editor.configFileLocationU);
621 		editor.configFileLocationU = NULL;
622 		showErrorMsgBox("Error: Couldn't set config file location. You can't load/save the config!");
623 		return;
624 	}
625 
626 	FILE *f = fopen("FT2.CFG", "rb");
627 	if (f == NULL) // FT2.CFG not found in current dir, try default config dir
628 	{
629 		int32_t result = -1;
630 
631 		// try to use $XDG_CONFIG_HOME first. If not set, use $HOME
632 		const char *xdgConfigHome = getenv("XDG_CONFIG_HOME");
633 		const char *home = getenv("HOME");
634 
635 		if (xdgConfigHome != NULL)
636 			result = chdir(xdgConfigHome);
637 		else if (home != NULL && chdir(home) == 0)
638 			result = chdir(".config");
639 
640 		if (result == 0)
641 		{
642 			result = chdir("FT2 clone");
643 			if (result != 0)
644 			{
645 				mkdir("FT2 clone", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
646 				result = chdir("FT2 clone");
647 			}
648 
649 			if (result == 0)
650 				getcwd(editor.configFileLocationU, PATH_MAX - ft2DotCfgStrLen - 1);
651 		}
652 	}
653 	else
654 	{
655 		fclose(f);
656 	}
657 
658 	strcat(editor.configFileLocationU, "/FT2.CFG");
659 #endif
660 
661 	editor.midiConfigFileLocationU = getFullMidiDevConfigPathU();
662 	editor.audioDevConfigFileLocationU = getFullAudDevConfigPathU();
663 }
664 
loadConfigOrSetDefaults(void)665 void loadConfigOrSetDefaults(void)
666 {
667 	setConfigFileLocation();
668 	if (editor.configFileLocationU == NULL)
669 	{
670 		setDefaultConfigSettings();
671 		return;
672 	}
673 
674 	FILE *f = UNICHAR_FOPEN(editor.configFileLocationU, "rb");
675 	if (f == NULL)
676 	{
677 		setDefaultConfigSettings();
678 		return;
679 	}
680 
681 	fseek(f, 0, SEEK_END);
682 	const size_t fileSize = ftell(f);
683 	rewind(f);
684 
685 	// not a valid FT2 config file (FT2.CFG filesize varies depending on version)
686 	if (fileSize < 1732 || fileSize > CONFIG_FILE_SIZE)
687 	{
688 		fclose(f);
689 		setDefaultConfigSettings();
690 		showErrorMsgBox("The configuration file (FT2.CFG) was corrupt, default settings were loaded.");
691 		return;
692 	}
693 
694 	if (fileSize < CONFIG_FILE_SIZE)
695 		memset(configBuffer, 0, CONFIG_FILE_SIZE);
696 
697 	if (fread(configBuffer, fileSize, 1, f) != 1)
698 	{
699 		fclose(f);
700 		setDefaultConfigSettings();
701 		showErrorMsgBox("I/O error while reading FT2.CFG, default settings were loaded.");
702 		return;
703 	}
704 
705 	fclose(f);
706 
707 	// decrypt config buffer
708 	xorConfigBuffer(configBuffer);
709 
710 	if (memcmp(&configBuffer[0], CFG_ID_STR, 35) != 0)
711 	{
712 		setDefaultConfigSettings();
713 		showErrorMsgBox("The configuration file (FT2.CFG) was corrupt, default settings were loaded.");
714 		return;
715 	}
716 
717 	loadConfigFromBuffer(false);
718 }
719 
720 // GUI-related code
721 
drawQuantValue(void)722 static void drawQuantValue(void)
723 {
724 	char str[8];
725 	sprintf(str, "%02d", config.recQuantRes);
726 	textOutFixed(354, 123, PAL_FORGRND, PAL_DESKTOP, str);
727 }
728 
drawMIDIChanValue(void)729 static void drawMIDIChanValue(void)
730 {
731 	char str[8];
732 	sprintf(str, "%02d", config.recMIDIChn);
733 	textOutFixed(578, 109, PAL_FORGRND, PAL_DESKTOP, str);
734 }
735 
drawMIDITransp(void)736 static void drawMIDITransp(void)
737 {
738 	fillRect(571, 123, 20, 8, PAL_DESKTOP);
739 
740 	const char sign = (config.recMIDITranspVal < 0) ? '-' : '+';
741 
742 	const int8_t val = (int8_t)(ABS(config.recMIDITranspVal));
743 	if (val >= 10)
744 	{
745 		charOut(571, 123, PAL_FORGRND, sign);
746 		charOut(578, 123, PAL_FORGRND, '0' + ((val / 10) % 10));
747 		charOut(585, 123, PAL_FORGRND, '0' + (val % 10));
748 	}
749 	else
750 	{
751 		if (val > 0)
752 			charOut(578, 123, PAL_FORGRND, sign);
753 
754 		charOut(585, 123, PAL_FORGRND, '0' + (val % 10));
755 	}
756 }
757 
drawMIDISens(void)758 static void drawMIDISens(void)
759 {
760 	char str[8];
761 	sprintf(str, "%03d", config.recMIDIVolSens);
762 	textOutFixed(525, 160, PAL_FORGRND, PAL_DESKTOP, str);
763 }
764 
setConfigRadioButtonStates(void)765 static void setConfigRadioButtonStates(void)
766 {
767 	uint16_t tmpID;
768 
769 	uncheckRadioButtonGroup(RB_GROUP_CONFIG_SELECT);
770 	switch (editor.currConfigScreen)
771 	{
772 		default:
773 		case CONFIG_SCREEN_IO_DEVICES:    tmpID = RB_CONFIG_IO_DEVICES;    break;
774 		case CONFIG_SCREEN_LAYOUT:        tmpID = RB_CONFIG_LAYOUT;        break;
775 		case CONFIG_SCREEN_MISCELLANEOUS: tmpID = RB_CONFIG_MISCELLANEOUS; break;
776 #ifdef HAS_MIDI
777 		case CONFIG_SCREEN_MIDI_INPUT:    tmpID = RB_CONFIG_MIDI_INPUT;    break;
778 #endif
779 	}
780 	radioButtons[tmpID].state = RADIOBUTTON_CHECKED;
781 
782 	showRadioButtonGroup(RB_GROUP_CONFIG_SELECT);
783 }
784 
setConfigIORadioButtonStates(void)785 void setConfigIORadioButtonStates(void) // accessed by other .c files
786 {
787 	uint16_t tmpID;
788 
789 	// AUDIO BUFFER SIZE
790 	uncheckRadioButtonGroup(RB_GROUP_CONFIG_SOUND_BUFF_SIZE);
791 
792 	tmpID = RB_CONFIG_SBS_1024;
793 	if (config.specialFlags & BUFFSIZE_512)
794 		tmpID = RB_CONFIG_SBS_512;
795 	else if (config.specialFlags & BUFFSIZE_2048)
796 		tmpID = RB_CONFIG_SBS_2048;
797 
798 	radioButtons[tmpID].state = RADIOBUTTON_CHECKED;
799 
800 	// AUDIO BIT DEPTH
801 	uncheckRadioButtonGroup(RB_GROUP_CONFIG_AUDIO_BIT_DEPTH);
802 
803 	tmpID = RB_CONFIG_AUDIO_16BIT;
804 	if (config.specialFlags & BITDEPTH_32)
805 		tmpID = RB_CONFIG_AUDIO_24BIT;
806 
807 	radioButtons[tmpID].state = RADIOBUTTON_CHECKED;
808 
809 	// AUDIO INTERPOLATION
810 	uncheckRadioButtonGroup(RB_GROUP_CONFIG_AUDIO_INTERPOLATION);
811 
812 	if (config.interpolation == INTERPOLATION_NONE)
813 		tmpID = RB_CONFIG_AUDIO_INTRP_NONE;
814 	else if (config.interpolation == INTERPOLATION_LINEAR)
815 		tmpID = RB_CONFIG_AUDIO_INTRP_LINEAR;
816 	else
817 		tmpID = RB_CONFIG_AUDIO_INTRP_SINC;
818 
819 	radioButtons[tmpID].state = RADIOBUTTON_CHECKED;
820 
821 	// AUDIO FREQUENCY
822 	uncheckRadioButtonGroup(RB_GROUP_CONFIG_AUDIO_FREQ);
823 	switch (config.audioFreq)
824 	{
825 		         case 44100:  tmpID = RB_CONFIG_AUDIO_44KHZ;  break;
826 		default: case 48000:  tmpID = RB_CONFIG_AUDIO_48KHZ;  break;
827 #if CPU_64BIT
828 		         case 96000:  tmpID = RB_CONFIG_AUDIO_96KHZ;  break;
829 		         case 192000: tmpID = RB_CONFIG_AUDIO_192KHZ; break;
830 #endif
831 	}
832 	radioButtons[tmpID].state = RADIOBUTTON_CHECKED;
833 
834 	// AUDIO INPUT FREQUENCY
835 	uncheckRadioButtonGroup(RB_GROUP_CONFIG_AUDIO_INPUT_FREQ);
836 	switch (config.audioInputFreq)
837 	{
838 		         case INPUT_FREQ_44KHZ: tmpID = RB_CONFIG_AUDIO_INPUT_44KHZ; break;
839 		default: case INPUT_FREQ_48KHZ: tmpID = RB_CONFIG_AUDIO_INPUT_48KHZ; break;
840 		         case INPUT_FREQ_96KHZ: tmpID = RB_CONFIG_AUDIO_INPUT_96KHZ; break;
841 	}
842 	radioButtons[tmpID].state = RADIOBUTTON_CHECKED;
843 
844 	// FREQUENCY TABLE
845 	uncheckRadioButtonGroup(RB_GROUP_CONFIG_FREQ_TABLE);
846 	tmpID = audio.linearPeriodsFlag ? RB_CONFIG_FREQ_LINEAR : RB_CONFIG_FREQ_AMIGA;
847 	radioButtons[tmpID].state = RADIOBUTTON_CHECKED;
848 
849 	// show result
850 
851 	showRadioButtonGroup(RB_GROUP_CONFIG_SOUND_BUFF_SIZE);
852 	showRadioButtonGroup(RB_GROUP_CONFIG_AUDIO_BIT_DEPTH);
853 	showRadioButtonGroup(RB_GROUP_CONFIG_AUDIO_INTERPOLATION);
854 	showRadioButtonGroup(RB_GROUP_CONFIG_AUDIO_FREQ);
855 	showRadioButtonGroup(RB_GROUP_CONFIG_AUDIO_INPUT_FREQ);
856 	showRadioButtonGroup(RB_GROUP_CONFIG_FREQ_TABLE);
857 }
858 
setConfigIOCheckButtonStates(void)859 static void setConfigIOCheckButtonStates(void)
860 {
861 	checkBoxes[CB_CONF_VOL_RAMP].checked = (config.specialFlags & NO_VOLRAMP_FLAG) ? false : true;
862 	showCheckBox(CB_CONF_VOL_RAMP);
863 }
864 
setConfigLayoutCheckButtonStates(void)865 static void setConfigLayoutCheckButtonStates(void)
866 {
867 	checkBoxes[CB_CONF_PATTSTRETCH].checked = config.ptnStretch;
868 	checkBoxes[CB_CONF_HEXCOUNT].checked = config.ptnHex;
869 	checkBoxes[CB_CONF_ACCIDENTAL].checked = config.ptnAcc ? true : false;
870 	checkBoxes[CB_CONF_SHOWZEROES].checked = config.ptnInstrZero;
871 	checkBoxes[CB_CONF_FRAMEWORK].checked = config.ptnFrmWrk;
872 	checkBoxes[CB_CONF_LINECOLORS].checked = config.ptnLineLight;
873 	checkBoxes[CB_CONF_CHANNUMS].checked = config.ptnChnNumbers;
874 	checkBoxes[CB_CONF_SHOW_VOLCOL].checked = config.ptnShowVolColumn;
875 	checkBoxes[CB_CONF_SOFTWARE_MOUSE].checked = (config.specialFlags2 & HARDWARE_MOUSE) ? false : true;
876 
877 	showCheckBox(CB_CONF_PATTSTRETCH);
878 	showCheckBox(CB_CONF_HEXCOUNT);
879 	showCheckBox(CB_CONF_ACCIDENTAL);
880 	showCheckBox(CB_CONF_SHOWZEROES);
881 	showCheckBox(CB_CONF_FRAMEWORK);
882 	showCheckBox(CB_CONF_LINECOLORS);
883 	showCheckBox(CB_CONF_CHANNUMS);
884 	showCheckBox(CB_CONF_SHOW_VOLCOL);
885 	showCheckBox(CB_CONF_SOFTWARE_MOUSE);
886 }
887 
setConfigLayoutRadioButtonStates(void)888 static void setConfigLayoutRadioButtonStates(void)
889 {
890 	uint16_t tmpID;
891 
892 	// MOUSE SHAPE
893 	uncheckRadioButtonGroup(RB_GROUP_CONFIG_MOUSE);
894 	switch (config.mouseType)
895 	{
896 		default:
897 		case MOUSE_IDLE_SHAPE_NICE:   tmpID = RB_CONFIG_MOUSE_NICE;    break;
898 		case MOUSE_IDLE_SHAPE_UGLY:   tmpID = RB_CONFIG_MOUSE_UGLY;    break;
899 		case MOUSE_IDLE_SHAPE_AWFUL:  tmpID = RB_CONFIG_MOUSE_AWFUL;   break;
900 		case MOUSE_IDLE_SHAPE_USABLE: tmpID = RB_CONFIG_MOUSE_USABLE;  break;
901 	}
902 	radioButtons[tmpID].state = RADIOBUTTON_CHECKED;
903 
904 	// MOUSE BUSY SHAPE
905 	uncheckRadioButtonGroup(RB_GROUP_CONFIG_MOUSE_BUSY);
906 	switch (config.mouseAnimType)
907 	{
908 		default:
909 		case MOUSE_BUSY_SHAPE_CLOCK: tmpID = RB_CONFIG_MOUSE_BUSY_CLOCK; break;
910 		case MOUSE_BUSY_SHAPE_GLASS: tmpID = RB_CONFIG_MOUSE_BUSY_GLASS; break;
911 	}
912 	radioButtons[tmpID].state = RADIOBUTTON_CHECKED;
913 
914 	// SCOPE STYLE
915 	uncheckRadioButtonGroup(RB_GROUP_CONFIG_SCOPE);
916 	tmpID = RB_CONFIG_SCOPE_NORMAL;
917 	if (config.specialFlags & LINED_SCOPES) tmpID = RB_CONFIG_SCOPE_LINED;
918 	radioButtons[tmpID].state = RADIOBUTTON_CHECKED;
919 
920 	switch (config.mouseType)
921 	{
922 		default:
923 		case MOUSE_IDLE_SHAPE_NICE:    tmpID = RB_CONFIG_MOUSE_NICE;    break;
924 		case MOUSE_IDLE_SHAPE_UGLY:    tmpID = RB_CONFIG_MOUSE_UGLY;    break;
925 		case MOUSE_IDLE_SHAPE_AWFUL:   tmpID = RB_CONFIG_MOUSE_AWFUL;   break;
926 		case MOUSE_IDLE_SHAPE_USABLE:  tmpID = RB_CONFIG_MOUSE_USABLE;  break;
927 	}
928 	radioButtons[tmpID].state = RADIOBUTTON_CHECKED;
929 
930 	// MAX VISIBLE CHANNELS
931 	uncheckRadioButtonGroup(RB_GROUP_CONFIG_PATTERN_CHANS);
932 	switch (config.ptnMaxChannels)
933 	{
934 		default:
935 		case MAX_CHANS_SHOWN_4:  tmpID = RB_CONFIG_MAXCHAN_4;  break;
936 		case MAX_CHANS_SHOWN_6:  tmpID = RB_CONFIG_MAXCHAN_6;  break;
937 		case MAX_CHANS_SHOWN_8:  tmpID = RB_CONFIG_MAXCHAN_8;  break;
938 		case MAX_CHANS_SHOWN_12: tmpID = RB_CONFIG_MAXCHAN_12; break;
939 	}
940 	radioButtons[tmpID].state = RADIOBUTTON_CHECKED;
941 
942 	// PATTERN FONT
943 	uncheckRadioButtonGroup(RB_GROUP_CONFIG_FONT);
944 	switch (config.ptnFont)
945 	{
946 		default:
947 		case PATT_FONT_CAPITALS:  tmpID = RB_CONFIG_FONT_CAPITALS;  break;
948 		case PATT_FONT_LOWERCASE: tmpID = RB_CONFIG_FONT_LOWERCASE; break;
949 		case PATT_FONT_FUTURE:    tmpID = RB_CONFIG_FONT_FUTURE;    break;
950 		case PATT_FONT_BOLD:      tmpID = RB_CONFIG_FONT_BOLD;      break;
951 	}
952 	radioButtons[tmpID].state = RADIOBUTTON_CHECKED;
953 
954 	// PALETTE ENTRIES
955 	uncheckRadioButtonGroup(RB_GROUP_CONFIG_PAL_ENTRIES);
956 	radioButtons[RB_CONFIG_PAL_PATTERNTEXT + cfg_ColorNum].state = RADIOBUTTON_CHECKED;
957 	showRadioButtonGroup(RB_GROUP_CONFIG_PAL_ENTRIES);
958 
959 	// PALETTE PRESET
960 	uncheckRadioButtonGroup(RB_GROUP_CONFIG_PAL_PRESET);
961 	switch (config.cfg_StdPalNum)
962 	{
963 		default:
964 		case PAL_ARCTIC:          tmpID = RB_CONFIG_PAL_ARCTIC;          break;
965 		case PAL_AURORA_BOREALIS: tmpID = RB_CONFIG_PAL_AURORA_BOREALIS; break;
966 		case PAL_BLUES:           tmpID = RB_CONFIG_PAL_BLUES;           break;
967 		case PAL_GOLD:            tmpID = RB_CONFIG_PAL_GOLD;            break;
968 		case PAL_HEAVY_METAL:     tmpID = RB_CONFIG_PAL_HEAVY_METAL;     break;
969 		case PAL_JUNGLE:          tmpID = RB_CONFIG_PAL_JUNGLE;          break;
970 		case PAL_LITHE_DARK:      tmpID = RB_CONFIG_PAL_LITHE_DARK;      break;
971 		case PAL_ROSE:            tmpID = RB_CONFIG_PAL_ROSE;            break;
972 		case PAL_DARK_MODE:       tmpID = RB_CONFIG_PAL_DARK_MODE;       break;
973 		case PAL_VIOLENT:         tmpID = RB_CONFIG_PAL_VIOLENT;         break;
974 		case PAL_WHY_COLORS:      tmpID = RB_CONFIG_PAL_WHY_COLORS;      break;
975 		case PAL_USER_DEFINED:    tmpID = RB_CONFIG_PAL_USER_DEFINED;    break;
976 	}
977 	radioButtons[tmpID].state = RADIOBUTTON_CHECKED;
978 
979 	// show result
980 
981 	showRadioButtonGroup(RB_GROUP_CONFIG_MOUSE);
982 	showRadioButtonGroup(RB_GROUP_CONFIG_MOUSE_BUSY);
983 	showRadioButtonGroup(RB_GROUP_CONFIG_SCOPE);
984 	showRadioButtonGroup(RB_GROUP_CONFIG_PATTERN_CHANS);
985 	showRadioButtonGroup(RB_GROUP_CONFIG_FONT);
986 	showRadioButtonGroup(RB_GROUP_CONFIG_PAL_PRESET);
987 }
988 
setConfigMiscCheckButtonStates(void)989 static void setConfigMiscCheckButtonStates(void)
990 {
991 	checkBoxes[CB_CONF_SAMP_CUT_TO_BUF].checked = config.smpCutToBuffer;
992 	checkBoxes[CB_CONF_PATT_CUT_TO_BUF].checked = config.ptnCutToBuffer;
993 	checkBoxes[CB_CONF_KILL_NOTES_AT_STOP].checked = config.killNotesOnStopPlay;
994 	checkBoxes[CB_CONF_FILE_OVERWRITE_WARN].checked = config.cfg_OverwriteWarning;
995 	checkBoxes[CB_CONF_MULTICHAN_REC].checked = config.multiRec;
996 	checkBoxes[CB_CONF_MULTICHAN_JAZZ].checked = config.multiKeyJazz;
997 	checkBoxes[CB_CONF_MULTICHAN_EDIT].checked = config.multiEdit;
998 	checkBoxes[CB_CONF_REC_KEYOFF].checked = config.recRelease;
999 	checkBoxes[CB_CONF_QUANTIZATION].checked = config.recQuant;
1000 	checkBoxes[CB_CONF_CHANGE_PATTLEN_INS_DEL].checked = config.recTrueInsert;
1001 	checkBoxes[CB_CONF_MIDI_ALLOW_PC].checked = config.recMIDIAllowPC;
1002 #ifdef HAS_MIDI
1003 	checkBoxes[CB_CONF_MIDI_ENABLE].checked = midi.enable;
1004 #else
1005 	checkBoxes[CB_CONF_MIDI_ENABLE].checked = false;
1006 #endif
1007 	checkBoxes[CB_CONF_MIDI_REC_ALL].checked = config.recMIDIAllChn;
1008 	checkBoxes[CB_CONF_MIDI_REC_TRANS].checked = config.recMIDITransp;
1009 	checkBoxes[CB_CONF_MIDI_REC_VELOC].checked = config.recMIDIVelocity;
1010 	checkBoxes[CB_CONF_MIDI_REC_AFTERTOUCH].checked = config.recMIDIAftert;
1011 	checkBoxes[CB_CONF_FORCE_VSYNC_OFF].checked = (config.windowFlags & FORCE_VSYNC_OFF) ? true : false;
1012 	checkBoxes[CB_CONF_START_IN_FULLSCREEN].checked = (config.windowFlags & START_IN_FULLSCR) ? true : false;
1013 	checkBoxes[CB_CONF_PIXEL_FILTER].checked = (config.windowFlags & PIXEL_FILTER) ? true : false;
1014 	checkBoxes[CB_CONF_STRETCH_IMAGE].checked = (config.specialFlags2 & STRETCH_IMAGE) ? true : false;
1015 
1016 	showCheckBox(CB_CONF_SAMP_CUT_TO_BUF);
1017 	showCheckBox(CB_CONF_PATT_CUT_TO_BUF);
1018 	showCheckBox(CB_CONF_KILL_NOTES_AT_STOP);
1019 	showCheckBox(CB_CONF_FILE_OVERWRITE_WARN);
1020 	showCheckBox(CB_CONF_MULTICHAN_REC);
1021 	showCheckBox(CB_CONF_MULTICHAN_JAZZ);
1022 	showCheckBox(CB_CONF_MULTICHAN_EDIT);
1023 	showCheckBox(CB_CONF_REC_KEYOFF);
1024 	showCheckBox(CB_CONF_QUANTIZATION);
1025 	showCheckBox(CB_CONF_CHANGE_PATTLEN_INS_DEL);
1026 	showCheckBox(CB_CONF_MIDI_ALLOW_PC);
1027 	showCheckBox(CB_CONF_MIDI_ENABLE);
1028 	showCheckBox(CB_CONF_MIDI_REC_ALL);
1029 	showCheckBox(CB_CONF_MIDI_REC_TRANS);
1030 	showCheckBox(CB_CONF_MIDI_REC_VELOC);
1031 	showCheckBox(CB_CONF_MIDI_REC_AFTERTOUCH);
1032 	showCheckBox(CB_CONF_FORCE_VSYNC_OFF);
1033 	showCheckBox(CB_CONF_START_IN_FULLSCREEN);
1034 	showCheckBox(CB_CONF_PIXEL_FILTER);
1035 	showCheckBox(CB_CONF_STRETCH_IMAGE);
1036 }
1037 
setConfigMiscRadioButtonStates(void)1038 static void setConfigMiscRadioButtonStates(void)
1039 {
1040 	uint16_t tmpID;
1041 
1042 	// FILE SORTING
1043 	uncheckRadioButtonGroup(RB_GROUP_CONFIG_FILESORT);
1044 	switch (config.cfg_SortPriority)
1045 	{
1046 		default:
1047 		case FILESORT_EXT:  tmpID = RB_CONFIG_FILESORT_EXT;  break;
1048 		case FILESORT_NAME: tmpID = RB_CONFIG_FILESORT_NAME; break;
1049 	}
1050 	radioButtons[tmpID].state = RADIOBUTTON_CHECKED;
1051 
1052 	// WINDOW SIZE
1053 	uncheckRadioButtonGroup(RB_GROUP_CONFIG_WIN_SIZE);
1054 
1055 	     if (config.windowFlags & WINSIZE_AUTO) tmpID = RB_CONFIG_WIN_SIZE_AUTO;
1056 	else if (config.windowFlags & WINSIZE_1X) tmpID = RB_CONFIG_WIN_SIZE_1X;
1057 	else if (config.windowFlags & WINSIZE_2X) tmpID = RB_CONFIG_WIN_SIZE_2X;
1058 	else if (config.windowFlags & WINSIZE_3X) tmpID = RB_CONFIG_WIN_SIZE_3X;
1059 	else if (config.windowFlags & WINSIZE_4X) tmpID = RB_CONFIG_WIN_SIZE_4X;
1060 
1061 	radioButtons[tmpID].state = RADIOBUTTON_CHECKED;
1062 
1063 	// show result
1064 
1065 	showRadioButtonGroup(RB_GROUP_CONFIG_FILESORT);
1066 	showRadioButtonGroup(RB_GROUP_CONFIG_WIN_SIZE);
1067 }
1068 
showConfigScreen(void)1069 void showConfigScreen(void)
1070 {
1071 	if (ui.extended)
1072 		exitPatternEditorExtended();
1073 
1074 	hideTopScreen();
1075 	ui.configScreenShown = true;
1076 
1077 	drawFramework(0, 0, 110, 173, FRAMEWORK_TYPE1);
1078 
1079 	setConfigRadioButtonStates();
1080 
1081 	checkBoxes[CB_CONF_AUTOSAVE].checked = config.cfg_AutoSave;
1082 	showCheckBox(CB_CONF_AUTOSAVE);
1083 
1084 	showPushButton(PB_CONFIG_RESET);
1085 	showPushButton(PB_CONFIG_LOAD);
1086 	showPushButton(PB_CONFIG_SAVE);
1087 	showPushButton(PB_CONFIG_EXIT);
1088 
1089 	textOutShadow(4,   4, PAL_FORGRND, PAL_DSKTOP2, "Configuration:");
1090 	textOutShadow(21, 19, PAL_FORGRND, PAL_DSKTOP2, "I/O devices");
1091 	textOutShadow(21, 35, PAL_FORGRND, PAL_DSKTOP2, "Layout");
1092 	textOutShadow(21, 51, PAL_FORGRND, PAL_DSKTOP2, "Miscellaneous");
1093 #ifdef HAS_MIDI
1094 	textOutShadow(21, 67, PAL_FORGRND, PAL_DSKTOP2, "MIDI input");
1095 #endif
1096 	textOutShadow(20, 93, PAL_FORGRND, PAL_DSKTOP2, "Auto save");
1097 
1098 	switch (editor.currConfigScreen)
1099 	{
1100 		default:
1101 		case CONFIG_SCREEN_IO_DEVICES:
1102 		{
1103 			drawFramework(110,   0, 276, 87, FRAMEWORK_TYPE1);
1104 			drawFramework(110,  87, 276, 86, FRAMEWORK_TYPE1);
1105 
1106 			drawFramework(386,   0, 119,  58, FRAMEWORK_TYPE1);
1107 			drawFramework(386,  58, 119,  44, FRAMEWORK_TYPE1);
1108 			drawFramework(386, 102, 119,  71, FRAMEWORK_TYPE1);
1109 
1110 			drawFramework(505,   0, 127,  73, FRAMEWORK_TYPE1);
1111 			drawFramework(505, 117, 127,  56, FRAMEWORK_TYPE1);
1112 			drawFramework(505,  73, 127,  44, FRAMEWORK_TYPE1);
1113 
1114 			drawFramework(112,  16, AUDIO_SELECTORS_BOX_WIDTH+4, 69, FRAMEWORK_TYPE2);
1115 			drawFramework(112, 103, AUDIO_SELECTORS_BOX_WIDTH+4, 47, FRAMEWORK_TYPE2);
1116 
1117 			drawAudioOutputList();
1118 			drawAudioInputList();
1119 
1120 			if (audio.rescanAudioDevicesSupported)
1121 				showPushButton(PB_CONFIG_AUDIO_RESCAN);
1122 
1123 			showPushButton(PB_CONFIG_AUDIO_OUTPUT_DOWN);
1124 			showPushButton(PB_CONFIG_AUDIO_OUTPUT_UP);
1125 			showPushButton(PB_CONFIG_AUDIO_INPUT_DOWN);
1126 			showPushButton(PB_CONFIG_AUDIO_INPUT_UP);
1127 			showPushButton(PB_CONFIG_AMP_DOWN);
1128 			showPushButton(PB_CONFIG_AMP_UP);
1129 			showPushButton(PB_CONFIG_MASTVOL_DOWN);
1130 			showPushButton(PB_CONFIG_MASTVOL_UP);
1131 
1132 			textOutShadow(114,   4, PAL_FORGRND, PAL_DSKTOP2, "Audio output devices:");
1133 			textOutShadow(114,  91, PAL_FORGRND, PAL_DSKTOP2, "Audio input devices (sampling):");
1134 
1135 			textOutShadow(114, 157, PAL_FORGRND, PAL_DSKTOP2, "Input rate:");
1136 			textOutShadow(194, 157, PAL_FORGRND, PAL_DSKTOP2, "44.1kHz");
1137 			textOutShadow(265, 157, PAL_FORGRND, PAL_DSKTOP2, "48.0kHz");
1138 			textOutShadow(336, 157, PAL_FORGRND, PAL_DSKTOP2, "96.0kHz");
1139 
1140 			textOutShadow(390,   3, PAL_FORGRND, PAL_DSKTOP2, "Audio buffer size:");
1141 			textOutShadow(406,  17, PAL_FORGRND, PAL_DSKTOP2, "Small");
1142 			textOutShadow(406,  31, PAL_FORGRND, PAL_DSKTOP2, "Medium (default)");
1143 			textOutShadow(406,  45, PAL_FORGRND, PAL_DSKTOP2, "Large");
1144 
1145 			textOutShadow(390,  61, PAL_FORGRND, PAL_DSKTOP2, "Audio bit depth:");
1146 			textOutShadow(406,  75, PAL_FORGRND, PAL_DSKTOP2, "16-bit (default)");
1147 			textOutShadow(406,  89, PAL_FORGRND, PAL_DSKTOP2, "32-bit float");
1148 
1149 			textOutShadow(390, 105, PAL_FORGRND, PAL_DSKTOP2, "Interpolation:");
1150 			textOutShadow(406, 118, PAL_FORGRND, PAL_DSKTOP2, "None");
1151 			textOutShadow(406, 132, PAL_FORGRND, PAL_DSKTOP2, "Linear (FT2)");
1152 			textOutShadow(406, 146, PAL_FORGRND, PAL_DSKTOP2, "Windowed-sinc");
1153 			textOutShadow(406, 161, PAL_FORGRND, PAL_DSKTOP2, "Volume ramping");
1154 
1155 			textOutShadow(509,   3, PAL_FORGRND, PAL_DSKTOP2, "Mixing frequency:");
1156 			textOutShadow(525,  17, PAL_FORGRND, PAL_DSKTOP2, "44100Hz");
1157 			textOutShadow(525,  31, PAL_FORGRND, PAL_DSKTOP2, "48000Hz (default)");
1158 #if CPU_64BIT
1159 			textOutShadow(525,  45, PAL_FORGRND, PAL_DSKTOP2, "96000Hz");
1160 			textOutShadow(525,  59, PAL_FORGRND, PAL_DSKTOP2, "192000Hz");
1161 #endif
1162 			textOutShadow(509,  76, PAL_FORGRND, PAL_DSKTOP2, "Frequency table:");
1163 			textOutShadow(525,  90, PAL_FORGRND, PAL_DSKTOP2, "Amiga freq. table");
1164 			textOutShadow(525, 104, PAL_FORGRND, PAL_DSKTOP2, "Linear freq. table");
1165 
1166 			textOutShadow(509, 120, PAL_FORGRND, PAL_DSKTOP2, "Amplification:");
1167 			charOutShadow(621, 120, PAL_FORGRND, PAL_DSKTOP2, 'X');
1168 			textOutShadow(509, 148, PAL_FORGRND, PAL_DSKTOP2, "Master volume:");
1169 
1170 			setConfigIORadioButtonStates();
1171 			setConfigIOCheckButtonStates();
1172 
1173 			configDrawAmp();
1174 
1175 			setScrollBarPos(SB_AMP_SCROLL,       config.boostLevel - 1, false);
1176 			setScrollBarPos(SB_MASTERVOL_SCROLL, config.masterVol,      false);
1177 
1178 			showScrollBar(SB_AUDIO_INPUT_SCROLL);
1179 			showScrollBar(SB_AUDIO_OUTPUT_SCROLL);
1180 			showScrollBar(SB_AMP_SCROLL);
1181 			showScrollBar(SB_MASTERVOL_SCROLL);
1182 		}
1183 		break;
1184 
1185 		case CONFIG_SCREEN_LAYOUT:
1186 		{
1187 			drawFramework(110,   0, 142, 106, FRAMEWORK_TYPE1);
1188 			drawFramework(252,   0, 142,  98, FRAMEWORK_TYPE1);
1189 			drawFramework(394,   0, 238,  86, FRAMEWORK_TYPE1);
1190 			drawFramework(110, 106, 142,  67, FRAMEWORK_TYPE1);
1191 			drawFramework(252,  98, 142,  45, FRAMEWORK_TYPE1);
1192 			drawFramework(394,  86, 238, 87, FRAMEWORK_TYPE1);
1193 
1194 			drawFramework(252, 143, 142,  30, FRAMEWORK_TYPE1);
1195 
1196 			textOutShadow(114, 109, PAL_FORGRND, PAL_DSKTOP2, "Mouse shape:");
1197 			textOutShadow(130, 121, PAL_FORGRND, PAL_DSKTOP2, "Nice");
1198 			textOutShadow(194, 121, PAL_FORGRND, PAL_DSKTOP2, "Ugly");
1199 			textOutShadow(130, 135, PAL_FORGRND, PAL_DSKTOP2, "Awful");
1200 			textOutShadow(194, 135, PAL_FORGRND, PAL_DSKTOP2, "Usable");
1201 			textOutShadow(114, 148, PAL_FORGRND, PAL_DSKTOP2, "Mouse busy shape:");
1202 			textOutShadow(130, 160, PAL_FORGRND, PAL_DSKTOP2, "Vogue");
1203 			textOutShadow(194, 160, PAL_FORGRND, PAL_DSKTOP2, "Mr. H");
1204 
1205 			textOutShadow(114,   3, PAL_FORGRND, PAL_DSKTOP2, "Pattern layout:");
1206 			textOutShadow(130,  16, PAL_FORGRND, PAL_DSKTOP2, "Pattern stretch");
1207 			textOutShadow(130,  29, PAL_FORGRND, PAL_DSKTOP2, "Hex line numbers");
1208 			textOutShadow(130,  42, PAL_FORGRND, PAL_DSKTOP2, "Accidential");
1209 			textOutShadow(130,  55, PAL_FORGRND, PAL_DSKTOP2, "Show zeroes");
1210 			textOutShadow(130,  68, PAL_FORGRND, PAL_DSKTOP2, "Framework");
1211 			textOutShadow(130,  81, PAL_FORGRND, PAL_DSKTOP2, "Line number colors");
1212 			textOutShadow(130,  94, PAL_FORGRND, PAL_DSKTOP2, "Channel numbering");
1213 
1214 			textOutShadow(256,   3, PAL_FORGRND, PAL_DSKTOP2, "Pattern modes:");
1215 			textOutShadow(271,  16, PAL_FORGRND, PAL_DSKTOP2, "Show volume column");
1216 			textOutShadow(256,  30, PAL_FORGRND, PAL_DSKTOP2, "Maximum visible chn.:");
1217 			textOutShadow(272,  43, PAL_FORGRND, PAL_DSKTOP2, "4 channels");
1218 			textOutShadow(272,  57, PAL_FORGRND, PAL_DSKTOP2, "6 channels");
1219 			textOutShadow(272,  71, PAL_FORGRND, PAL_DSKTOP2, "8 channels");
1220 			textOutShadow(272,  85, PAL_FORGRND, PAL_DSKTOP2, "12 channels");
1221 
1222 			textOutShadow(257, 101, PAL_FORGRND, PAL_DSKTOP2, "Pattern font:");
1223 			textOutShadow(272, 115, PAL_FORGRND, PAL_DSKTOP2, "Capitals");
1224 			textOutShadow(338, 114, PAL_FORGRND, PAL_DSKTOP2, "Lower-c.");
1225 			textOutShadow(272, 130, PAL_FORGRND, PAL_DSKTOP2, "Future");
1226 			textOutShadow(338, 129, PAL_FORGRND, PAL_DSKTOP2, "Bold");
1227 
1228 			textOutShadow(256, 146, PAL_FORGRND, PAL_DSKTOP2, "Scopes:");
1229 			textOutShadow(319, 146, PAL_FORGRND, PAL_DSKTOP2, "Std.");
1230 			textOutShadow(360, 146, PAL_FORGRND, PAL_DSKTOP2, "Lined");
1231 
1232 			textOutShadow(272, 160, PAL_FORGRND, PAL_DSKTOP2, "Software mouse");
1233 
1234 			textOutShadow(414,   3, PAL_FORGRND, PAL_DSKTOP2, "Pattern text");
1235 			textOutShadow(414,  17, PAL_FORGRND, PAL_DSKTOP2, "Block mark");
1236 			textOutShadow(414,  31, PAL_FORGRND, PAL_DSKTOP2, "Text on block");
1237 			textOutShadow(414,  45, PAL_FORGRND, PAL_DSKTOP2, "Mouse");
1238 			textOutShadow(414,  59, PAL_FORGRND, PAL_DSKTOP2, "Desktop");
1239 			textOutShadow(414,  73, PAL_FORGRND, PAL_DSKTOP2, "Buttons");
1240 
1241 			textOutShadow(414,  90, PAL_FORGRND, PAL_DSKTOP2, "Arctic");
1242 			textOutShadow(528,  90, PAL_FORGRND, PAL_DSKTOP2, "LiTHe dark");
1243 			textOutShadow(414, 104, PAL_FORGRND, PAL_DSKTOP2, "Aurora Borealis");
1244 			textOutShadow(528, 104, PAL_FORGRND, PAL_DSKTOP2, "Rose");
1245 			textOutShadow(414, 118, PAL_FORGRND, PAL_DSKTOP2, "Blues");
1246 			textOutShadow(528, 118, PAL_FORGRND, PAL_DSKTOP2, "Dark mode");
1247 			textOutShadow(414, 132, PAL_FORGRND, PAL_DSKTOP2, "Gold");
1248 			textOutShadow(528, 132, PAL_FORGRND, PAL_DSKTOP2, "Violent");
1249 			textOutShadow(414, 146, PAL_FORGRND, PAL_DSKTOP2, "Heavy Metal");
1250 			textOutShadow(528, 146, PAL_FORGRND, PAL_DSKTOP2, "Why colors?");
1251 			textOutShadow(414, 160, PAL_FORGRND, PAL_DSKTOP2, "Jungle");
1252 			textOutShadow(528, 160, PAL_FORGRND, PAL_DSKTOP2, "User defined");
1253 
1254 			showPaletteEditor();
1255 
1256 			setConfigLayoutCheckButtonStates();
1257 			setConfigLayoutRadioButtonStates();
1258 		}
1259 		break;
1260 
1261 		case CONFIG_SCREEN_MISCELLANEOUS:
1262 		{
1263 			drawFramework(110,   0,  99,  43, FRAMEWORK_TYPE1);
1264 			drawFramework(209,   0, 199,  55, FRAMEWORK_TYPE1);
1265 			drawFramework(408,   0, 224,  91, FRAMEWORK_TYPE1);
1266 
1267 			drawFramework(110,  43,  99,  57, FRAMEWORK_TYPE1);
1268 			drawFramework(209,  55, 199, 118, FRAMEWORK_TYPE1);
1269 			drawFramework(408,  91, 224,  82, FRAMEWORK_TYPE1);
1270 
1271 			drawFramework(110, 100,  99,  73, FRAMEWORK_TYPE1);
1272 
1273 			// text boxes
1274 			drawFramework(485,  15, 145,  14, FRAMEWORK_TYPE2);
1275 			drawFramework(485,  30, 145,  14, FRAMEWORK_TYPE2);
1276 			drawFramework(485,  45, 145,  14, FRAMEWORK_TYPE2);
1277 			drawFramework(485,  60, 145,  14, FRAMEWORK_TYPE2);
1278 			drawFramework(485,  75, 145,  14, FRAMEWORK_TYPE2);
1279 
1280 			textOutShadow(114,   3, PAL_FORGRND, PAL_DSKTOP2, "Dir. sorting pri.:");
1281 			textOutShadow(130,  16, PAL_FORGRND, PAL_DSKTOP2, "Ext.");
1282 			textOutShadow(130,  30, PAL_FORGRND, PAL_DSKTOP2, "Name");
1283 
1284 			textOutShadow(228,   4, PAL_FORGRND, PAL_DSKTOP2, "Sample \"cut to buffer\"");
1285 			textOutShadow(228,  17, PAL_FORGRND, PAL_DSKTOP2, "Pattern \"cut to buffer\"");
1286 			textOutShadow(228,  30, PAL_FORGRND, PAL_DSKTOP2, "Kill voices at music stop");
1287 			textOutShadow(228,  43, PAL_FORGRND, PAL_DSKTOP2, "File-overwrite warning");
1288 
1289 			textOutShadow(464,   3, PAL_FORGRND, PAL_DSKTOP2, "Default directories:");
1290 			textOutShadow(413,  17, PAL_FORGRND, PAL_DSKTOP2, "Modules");
1291 			textOutShadow(413,  32, PAL_FORGRND, PAL_DSKTOP2, "Instruments");
1292 			textOutShadow(413,  47, PAL_FORGRND, PAL_DSKTOP2, "Samples");
1293 			textOutShadow(413,  62, PAL_FORGRND, PAL_DSKTOP2, "Patterns");
1294 			textOutShadow(413,  77, PAL_FORGRND, PAL_DSKTOP2, "Tracks");
1295 
1296 			textOutShadow(114,  46, PAL_FORGRND, PAL_DSKTOP2, "Window size:");
1297 			textOutShadow(130,  59, PAL_FORGRND, PAL_DSKTOP2, "Auto fit");
1298 			textOutShadow(130,  73, PAL_FORGRND, PAL_DSKTOP2, "1x");
1299 			textOutShadow(172,  73, PAL_FORGRND, PAL_DSKTOP2, "3x");
1300 			textOutShadow(130,  87, PAL_FORGRND, PAL_DSKTOP2, "2x");
1301 			textOutShadow(172,  87, PAL_FORGRND, PAL_DSKTOP2, "4x");
1302 			textOutShadow(114, 103, PAL_FORGRND, PAL_DSKTOP2, "Video settings:");
1303 			textOutShadow(130, 117, PAL_FORGRND, PAL_DSKTOP2, "VSync off");
1304 			textOutShadow(130, 130, PAL_FORGRND, PAL_DSKTOP2, "Fullscreen");
1305 			textOutShadow(130, 143, PAL_FORGRND, PAL_DSKTOP2, "Stretched");
1306 			textOutShadow(130, 156, PAL_FORGRND, PAL_DSKTOP2, "Pixel filter");
1307 
1308 			textOutShadow(213,  58, PAL_FORGRND, PAL_DSKTOP2, "Rec./Edit/Play:");
1309 			textOutShadow(228,  71, PAL_FORGRND, PAL_DSKTOP2, "Multichannel record");
1310 			textOutShadow(228,  84, PAL_FORGRND, PAL_DSKTOP2, "Multichannel \"key jazz\"");
1311 			textOutShadow(228,  97, PAL_FORGRND, PAL_DSKTOP2, "Multichannel edit");
1312 			textOutShadow(228, 110, PAL_FORGRND, PAL_DSKTOP2, "Record key-off notes");
1313 			textOutShadow(228, 123, PAL_FORGRND, PAL_DSKTOP2, "Quantization");
1314 			textOutShadow(338, 123, PAL_FORGRND, PAL_DSKTOP2, "1/");
1315 			textOutShadow(228, 136, PAL_FORGRND, PAL_DSKTOP2, "Change pattern length when");
1316 			textOutShadow(228, 147, PAL_FORGRND, PAL_DSKTOP2, "inserting/deleting line.");
1317 			textOutShadow(228, 161, PAL_FORGRND, PAL_DSKTOP2, "Allow MIDI-in program change");
1318 
1319 			textOutShadow(428,  95, PAL_FORGRND, PAL_DSKTOP2, "Enable MIDI");
1320 			textOutShadow(412, 108, PAL_FORGRND, PAL_DSKTOP2, "Record MIDI chn.");
1321 			charOutShadow(523, 108, PAL_FORGRND, PAL_DSKTOP2, '(');
1322 			textOutShadow(546, 108, PAL_FORGRND, PAL_DSKTOP2, "all )");
1323 			textOutShadow(428, 121, PAL_FORGRND, PAL_DSKTOP2, "Record transpose");
1324 			textOutShadow(428, 134, PAL_FORGRND, PAL_DSKTOP2, "Record velocity");
1325 			textOutShadow(428, 147, PAL_FORGRND, PAL_DSKTOP2, "Record aftertouch");
1326 			textOutShadow(412, 160, PAL_FORGRND, PAL_DSKTOP2, "Vel./A.t. senstvty.");
1327 			charOutShadow(547, 160, PAL_FORGRND, PAL_DSKTOP2, '%');
1328 
1329 			setConfigMiscCheckButtonStates();
1330 			setConfigMiscRadioButtonStates();
1331 
1332 			drawQuantValue();
1333 			drawMIDIChanValue();
1334 			drawMIDITransp();
1335 			drawMIDISens();
1336 
1337 			showPushButton(PB_CONFIG_QUANTIZE_UP);
1338 			showPushButton(PB_CONFIG_QUANTIZE_DOWN);
1339 			showPushButton(PB_CONFIG_MIDICHN_UP);
1340 			showPushButton(PB_CONFIG_MIDICHN_DOWN);
1341 			showPushButton(PB_CONFIG_MIDITRANS_UP);
1342 			showPushButton(PB_CONFIG_MIDITRANS_DOWN);
1343 			showPushButton(PB_CONFIG_MIDISENS_DOWN);
1344 			showPushButton(PB_CONFIG_MIDISENS_UP);
1345 
1346 			showTextBox(TB_CONF_DEF_MODS_DIR);
1347 			showTextBox(TB_CONF_DEF_INSTRS_DIR);
1348 			showTextBox(TB_CONF_DEF_SAMPS_DIR);
1349 			showTextBox(TB_CONF_DEF_PATTS_DIR);
1350 			showTextBox(TB_CONF_DEF_TRACKS_DIR);
1351 			drawTextBox(TB_CONF_DEF_MODS_DIR);
1352 			drawTextBox(TB_CONF_DEF_INSTRS_DIR);
1353 			drawTextBox(TB_CONF_DEF_SAMPS_DIR);
1354 			drawTextBox(TB_CONF_DEF_PATTS_DIR);
1355 			drawTextBox(TB_CONF_DEF_TRACKS_DIR);
1356 
1357 			setScrollBarPos(SB_MIDI_SENS, config.recMIDIVolSens, false);
1358 			showScrollBar(SB_MIDI_SENS);
1359 		}
1360 		break;
1361 
1362 		case CONFIG_SCREEN_MIDI_INPUT:
1363 		{
1364 			drawFramework(110, 0, 394, 173, FRAMEWORK_TYPE1);
1365 			drawFramework(112, 2, 369, 169, FRAMEWORK_TYPE2);
1366 			drawFramework(504, 0, 128, 173, FRAMEWORK_TYPE1);
1367 
1368 			textOutShadow(528, 112, PAL_FORGRND, PAL_DSKTOP2, "Input Devices");
1369 
1370 			blitFast(517, 51, bmp.midiLogo, 103, 55);
1371 
1372 #ifdef HAS_MIDI
1373 			showPushButton(PB_CONFIG_MIDI_INPUT_DOWN);
1374 			showPushButton(PB_CONFIG_MIDI_INPUT_UP);
1375 			rescanMidiInputDevices();
1376 			drawMidiInputList();
1377 			showScrollBar(SB_MIDI_INPUT_SCROLL);
1378 #endif
1379 		}
1380 		break;
1381 	}
1382 }
1383 
hideConfigScreen(void)1384 void hideConfigScreen(void)
1385 {
1386 	// CONFIG LEFT SIDE
1387 	hideRadioButtonGroup(RB_GROUP_CONFIG_SELECT);
1388 	hideCheckBox(CB_CONF_AUTOSAVE);
1389 	hidePushButton(PB_CONFIG_RESET);
1390 	hidePushButton(PB_CONFIG_LOAD);
1391 	hidePushButton(PB_CONFIG_SAVE);
1392 	hidePushButton(PB_CONFIG_EXIT);
1393 
1394 	// CONFIG AUDIO
1395 	hideRadioButtonGroup(RB_GROUP_CONFIG_SOUND_BUFF_SIZE);
1396 	hideRadioButtonGroup(RB_GROUP_CONFIG_AUDIO_BIT_DEPTH);
1397 	hideRadioButtonGroup(RB_GROUP_CONFIG_AUDIO_INTERPOLATION);
1398 	hideRadioButtonGroup(RB_GROUP_CONFIG_AUDIO_FREQ);
1399 	hideRadioButtonGroup(RB_GROUP_CONFIG_AUDIO_INPUT_FREQ);
1400 	hideRadioButtonGroup(RB_GROUP_CONFIG_FREQ_TABLE);
1401 	hideCheckBox(CB_CONF_VOL_RAMP);
1402 	hidePushButton(PB_CONFIG_AUDIO_RESCAN);
1403 	hidePushButton(PB_CONFIG_AUDIO_OUTPUT_DOWN);
1404 	hidePushButton(PB_CONFIG_AUDIO_OUTPUT_UP);
1405 	hidePushButton(PB_CONFIG_AUDIO_INPUT_DOWN);
1406 	hidePushButton(PB_CONFIG_AUDIO_INPUT_UP);
1407 	hidePushButton(PB_CONFIG_AMP_DOWN);
1408 	hidePushButton(PB_CONFIG_AMP_UP);
1409 	hidePushButton(PB_CONFIG_MASTVOL_DOWN);
1410 	hidePushButton(PB_CONFIG_MASTVOL_UP);
1411 	hideScrollBar(SB_AUDIO_INPUT_SCROLL);
1412 	hideScrollBar(SB_AUDIO_OUTPUT_SCROLL);
1413 	hideScrollBar(SB_AMP_SCROLL);
1414 	hideScrollBar(SB_MASTERVOL_SCROLL);
1415 
1416 	// CONFIG LAYOUT
1417 	hideRadioButtonGroup(RB_GROUP_CONFIG_MOUSE);
1418 	hideRadioButtonGroup(RB_GROUP_CONFIG_MOUSE_BUSY);
1419 	hideRadioButtonGroup(RB_GROUP_CONFIG_SCOPE);
1420 	hideRadioButtonGroup(RB_GROUP_CONFIG_PATTERN_CHANS);
1421 	hideRadioButtonGroup(RB_GROUP_CONFIG_FONT);
1422 	hideRadioButtonGroup(RB_GROUP_CONFIG_PAL_ENTRIES);
1423 	hideRadioButtonGroup(RB_GROUP_CONFIG_PAL_PRESET);
1424 	hideCheckBox(CB_CONF_PATTSTRETCH);
1425 	hideCheckBox(CB_CONF_HEXCOUNT);
1426 	hideCheckBox(CB_CONF_ACCIDENTAL);
1427 	hideCheckBox(CB_CONF_SHOWZEROES);
1428 	hideCheckBox(CB_CONF_FRAMEWORK);
1429 	hideCheckBox(CB_CONF_LINECOLORS);
1430 	hideCheckBox(CB_CONF_CHANNUMS);
1431 	hideCheckBox(CB_CONF_SHOW_VOLCOL);
1432 	hideCheckBox(CB_CONF_SOFTWARE_MOUSE);
1433 	hidePushButton(PB_CONFIG_PAL_R_DOWN);
1434 	hidePushButton(PB_CONFIG_PAL_R_UP);
1435 	hidePushButton(PB_CONFIG_PAL_G_DOWN);
1436 	hidePushButton(PB_CONFIG_PAL_G_UP);
1437 	hidePushButton(PB_CONFIG_PAL_B_DOWN);
1438 	hidePushButton(PB_CONFIG_PAL_B_UP);
1439 	hidePushButton(PB_CONFIG_PAL_CONT_DOWN);
1440 	hidePushButton(PB_CONFIG_PAL_CONT_UP);
1441 	hideScrollBar(SB_PAL_R);
1442 	hideScrollBar(SB_PAL_G);
1443 	hideScrollBar(SB_PAL_B);
1444 	hideScrollBar(SB_PAL_CONTRAST);
1445 
1446 	// CONFIG MISCELLANEOUS
1447 	hideRadioButtonGroup(RB_GROUP_CONFIG_FILESORT);
1448 	hideRadioButtonGroup(RB_GROUP_CONFIG_WIN_SIZE);
1449 	hidePushButton(PB_CONFIG_QUANTIZE_UP);
1450 	hidePushButton(PB_CONFIG_QUANTIZE_DOWN);
1451 	hidePushButton(PB_CONFIG_MIDICHN_UP);
1452 	hidePushButton(PB_CONFIG_MIDICHN_DOWN);
1453 	hidePushButton(PB_CONFIG_MIDITRANS_UP);
1454 	hidePushButton(PB_CONFIG_MIDITRANS_DOWN);
1455 	hidePushButton(PB_CONFIG_MIDISENS_DOWN);
1456 	hidePushButton(PB_CONFIG_MIDISENS_UP);
1457 	hideCheckBox(CB_CONF_FORCE_VSYNC_OFF);
1458 	hideCheckBox(CB_CONF_START_IN_FULLSCREEN);
1459 	hideCheckBox(CB_CONF_PIXEL_FILTER);
1460 	hideCheckBox(CB_CONF_STRETCH_IMAGE);
1461 	hideCheckBox(CB_CONF_SAMP_CUT_TO_BUF);
1462 	hideCheckBox(CB_CONF_PATT_CUT_TO_BUF);
1463 	hideCheckBox(CB_CONF_KILL_NOTES_AT_STOP);
1464 	hideCheckBox(CB_CONF_FILE_OVERWRITE_WARN);
1465 	hideCheckBox(CB_CONF_MULTICHAN_REC);
1466 	hideCheckBox(CB_CONF_MULTICHAN_JAZZ);
1467 	hideCheckBox(CB_CONF_MULTICHAN_EDIT);
1468 	hideCheckBox(CB_CONF_REC_KEYOFF);
1469 	hideCheckBox(CB_CONF_QUANTIZATION);
1470 	hideCheckBox(CB_CONF_CHANGE_PATTLEN_INS_DEL);
1471 	hideCheckBox(CB_CONF_MIDI_ALLOW_PC);
1472 	hideCheckBox(CB_CONF_MIDI_ENABLE);
1473 	hideCheckBox(CB_CONF_MIDI_REC_ALL);
1474 	hideCheckBox(CB_CONF_MIDI_REC_TRANS);
1475 	hideCheckBox(CB_CONF_MIDI_REC_VELOC);
1476 	hideCheckBox(CB_CONF_MIDI_REC_AFTERTOUCH);
1477 	hideTextBox(TB_CONF_DEF_MODS_DIR);
1478 	hideTextBox(TB_CONF_DEF_INSTRS_DIR);
1479 	hideTextBox(TB_CONF_DEF_SAMPS_DIR);
1480 	hideTextBox(TB_CONF_DEF_PATTS_DIR);
1481 	hideTextBox(TB_CONF_DEF_TRACKS_DIR);
1482 	hideScrollBar(SB_MIDI_SENS);
1483 
1484 #ifdef HAS_MIDI
1485 	// CONFIG MIDI
1486 	hidePushButton(PB_CONFIG_MIDI_INPUT_DOWN);
1487 	hidePushButton(PB_CONFIG_MIDI_INPUT_UP);
1488 	hideScrollBar(SB_MIDI_INPUT_SCROLL);
1489 #endif
1490 
1491 	ui.configScreenShown = false;
1492 }
1493 
exitConfigScreen(void)1494 void exitConfigScreen(void)
1495 {
1496 	hideConfigScreen();
1497 	showTopScreen(true);
1498 }
1499 
1500 // CONFIG AUDIO
1501 
configToggleImportWarning(void)1502 void configToggleImportWarning(void)
1503 {
1504 	config.dontShowAgainFlags ^= DONT_SHOW_IMPORT_WARNING_FLAG;
1505 }
1506 
configToggleNotYetAppliedWarning(void)1507 void configToggleNotYetAppliedWarning(void)
1508 {
1509 	config.dontShowAgainFlags ^= DONT_SHOW_NOT_YET_APPLIED_WARNING_FLAG;
1510 }
1511 
rbConfigIODevices(void)1512 void rbConfigIODevices(void)
1513 {
1514 	checkRadioButton(RB_CONFIG_IO_DEVICES);
1515 	editor.currConfigScreen = CONFIG_SCREEN_IO_DEVICES;
1516 
1517 	hideConfigScreen();
1518 	showConfigScreen();
1519 }
1520 
rbConfigLayout(void)1521 void rbConfigLayout(void)
1522 {
1523 	checkRadioButton(RB_CONFIG_LAYOUT);
1524 	editor.currConfigScreen = CONFIG_SCREEN_LAYOUT;
1525 
1526 	hideConfigScreen();
1527 	showConfigScreen();
1528 }
1529 
rbConfigMiscellaneous(void)1530 void rbConfigMiscellaneous(void)
1531 {
1532 	checkRadioButton(RB_CONFIG_MISCELLANEOUS);
1533 	editor.currConfigScreen = CONFIG_SCREEN_MISCELLANEOUS;
1534 
1535 	hideConfigScreen();
1536 	showConfigScreen();
1537 }
1538 
1539 #ifdef HAS_MIDI
rbConfigMidiInput(void)1540 void rbConfigMidiInput(void)
1541 {
1542 	checkRadioButton(RB_CONFIG_MIDI_INPUT);
1543 	editor.currConfigScreen = CONFIG_SCREEN_MIDI_INPUT;
1544 
1545 	hideConfigScreen();
1546 	showConfigScreen();
1547 }
1548 #endif
1549 
rbConfigSbs512(void)1550 void rbConfigSbs512(void)
1551 {
1552 	config.specialFlags &= ~(BUFFSIZE_1024 + BUFFSIZE_2048);
1553 	config.specialFlags |= BUFFSIZE_512;
1554 
1555 	setNewAudioSettings();
1556 }
1557 
rbConfigSbs1024(void)1558 void rbConfigSbs1024(void)
1559 {
1560 	config.specialFlags &= ~(BUFFSIZE_512 + BUFFSIZE_2048);
1561 	config.specialFlags |= BUFFSIZE_1024;
1562 
1563 	setNewAudioSettings();
1564 }
1565 
rbConfigSbs2048(void)1566 void rbConfigSbs2048(void)
1567 {
1568 	config.specialFlags &= ~(BUFFSIZE_512 + BUFFSIZE_1024);
1569 	config.specialFlags |= BUFFSIZE_2048;
1570 
1571 	setNewAudioSettings();
1572 }
1573 
rbConfigAudio16bit(void)1574 void rbConfigAudio16bit(void)
1575 {
1576 	config.specialFlags &= ~BITDEPTH_32;
1577 	config.specialFlags |=  BITDEPTH_16;
1578 
1579 	setNewAudioSettings();
1580 }
1581 
rbConfigAudio24bit(void)1582 void rbConfigAudio24bit(void)
1583 {
1584 	config.specialFlags &= ~BITDEPTH_16;
1585 	config.specialFlags |=  BITDEPTH_32;
1586 
1587 	setNewAudioSettings();
1588 }
1589 
rbConfigAudioIntrpNone(void)1590 void rbConfigAudioIntrpNone(void)
1591 {
1592 	config.interpolation = INTERPOLATION_NONE;
1593 	audioSetInterpolationType(config.interpolation);
1594 	checkRadioButton(RB_CONFIG_AUDIO_INTRP_NONE);
1595 }
1596 
rbConfigAudioIntrpLinear(void)1597 void rbConfigAudioIntrpLinear(void)
1598 {
1599 	config.interpolation = INTERPOLATION_LINEAR;
1600 	audioSetInterpolationType(config.interpolation);
1601 	checkRadioButton(RB_CONFIG_AUDIO_INTRP_LINEAR);
1602 }
1603 
rbConfigAudioIntrpSinc(void)1604 void rbConfigAudioIntrpSinc(void)
1605 {
1606 	config.interpolation = INTERPOLATION_SINC;
1607 	audioSetInterpolationType(config.interpolation);
1608 	checkRadioButton(RB_CONFIG_AUDIO_INTRP_SINC);
1609 }
1610 
rbConfigAudio44kHz(void)1611 void rbConfigAudio44kHz(void)
1612 {
1613 	config.audioFreq = 44100;
1614 	setNewAudioSettings();
1615 }
1616 
rbConfigAudio48kHz(void)1617 void rbConfigAudio48kHz(void)
1618 {
1619 	config.audioFreq = 48000;
1620 	setNewAudioSettings();
1621 }
1622 
1623 #if CPU_64BIT
rbConfigAudio96kHz(void)1624 void rbConfigAudio96kHz(void)
1625 {
1626 	config.audioFreq = 96000;
1627 	setNewAudioSettings();
1628 }
1629 
rbConfigAudio192kHz(void)1630 void rbConfigAudio192kHz(void)
1631 {
1632 	config.audioFreq = 192000;
1633 	setNewAudioSettings();
1634 }
1635 #endif
1636 
rbConfigAudioInput44kHz(void)1637 void rbConfigAudioInput44kHz(void)
1638 {
1639 	config.audioInputFreq = INPUT_FREQ_44KHZ;
1640 	checkRadioButton(RB_CONFIG_AUDIO_INPUT_44KHZ);
1641 }
1642 
rbConfigAudioInput48kHz(void)1643 void rbConfigAudioInput48kHz(void)
1644 {
1645 	config.audioInputFreq = INPUT_FREQ_48KHZ;
1646 	checkRadioButton(RB_CONFIG_AUDIO_INPUT_48KHZ);
1647 }
1648 
rbConfigAudioInput96kHz(void)1649 void rbConfigAudioInput96kHz(void)
1650 {
1651 	config.audioInputFreq = INPUT_FREQ_96KHZ;
1652 	checkRadioButton(RB_CONFIG_AUDIO_INPUT_96KHZ);
1653 }
1654 
rbConfigFreqTableAmiga(void)1655 void rbConfigFreqTableAmiga(void)
1656 {
1657 	lockMixerCallback();
1658 	setFrequencyTable(false);
1659 	unlockMixerCallback();
1660 }
1661 
rbConfigFreqTableLinear(void)1662 void rbConfigFreqTableLinear(void)
1663 {
1664 	lockMixerCallback();
1665 	setFrequencyTable(true);
1666 	unlockMixerCallback();
1667 }
1668 
cbToggleAutoSaveConfig(void)1669 void cbToggleAutoSaveConfig(void)
1670 {
1671 	config.cfg_AutoSave ^= 1;
1672 }
cbConfigVolRamp(void)1673 void cbConfigVolRamp(void)
1674 {
1675 	config.specialFlags ^= NO_VOLRAMP_FLAG;
1676 	audioSetVolRamp((config.specialFlags & NO_VOLRAMP_FLAG) ? false : true);
1677 }
1678 
1679 // CONFIG LAYOUT
1680 
redrawPatternEditor(void)1681 static void redrawPatternEditor(void) // called after changing some pattern editor settings in config
1682 {
1683 	// if the cursor was on the volume column while we turned volume column off, move it to effect type slot
1684 	if (!config.ptnShowVolColumn && (cursor.object == CURSOR_VOL1 || cursor.object == CURSOR_VOL2))
1685 		cursor.object = CURSOR_EFX0;
1686 
1687 	updateChanNums();
1688 	ui.updatePatternEditor = true;
1689 }
1690 
cbConfigPattStretch(void)1691 void cbConfigPattStretch(void)
1692 {
1693 	config.ptnStretch ^= 1;
1694 	redrawPatternEditor();
1695 }
1696 
cbConfigHexCount(void)1697 void cbConfigHexCount(void)
1698 {
1699 	config.ptnHex ^= 1;
1700 	redrawPatternEditor();
1701 }
1702 
cbConfigAccidential(void)1703 void cbConfigAccidential(void)
1704 {
1705 	config.ptnAcc ^= 1;
1706 	showCheckBox(CB_CONF_ACCIDENTAL);
1707 	redrawPatternEditor();
1708 }
1709 
cbConfigShowZeroes(void)1710 void cbConfigShowZeroes(void)
1711 {
1712 	config.ptnInstrZero ^= 1;
1713 	redrawPatternEditor();
1714 }
1715 
cbConfigFramework(void)1716 void cbConfigFramework(void)
1717 {
1718 	config.ptnFrmWrk ^= 1;
1719 	redrawPatternEditor();
1720 }
1721 
cbConfigLineColors(void)1722 void cbConfigLineColors(void)
1723 {
1724 	config.ptnLineLight ^= 1;
1725 	redrawPatternEditor();
1726 }
1727 
cbConfigChanNums(void)1728 void cbConfigChanNums(void)
1729 {
1730 	config.ptnChnNumbers ^= 1;
1731 	redrawPatternEditor();
1732 }
1733 
cbConfigShowVolCol(void)1734 void cbConfigShowVolCol(void)
1735 {
1736 	config.ptnShowVolColumn ^= 1;
1737 	redrawPatternEditor();
1738 }
1739 
cbSoftwareMouse(void)1740 void cbSoftwareMouse(void)
1741 {
1742 	config.specialFlags2 ^= HARDWARE_MOUSE;
1743 	if (!createMouseCursors())
1744 		okBox(0, "System message", "Error: Couldn't create/show mouse cursor!");
1745 
1746 	if (config.specialFlags2 & HARDWARE_MOUSE)
1747 	{
1748 		checkBoxes[CB_CONF_SOFTWARE_MOUSE].checked = false;
1749 		drawCheckBox(CB_CONF_SOFTWARE_MOUSE);
1750 		SDL_ShowCursor(SDL_TRUE);
1751 	}
1752 	else
1753 	{
1754 		checkBoxes[CB_CONF_SOFTWARE_MOUSE].checked = true;
1755 		drawCheckBox(CB_CONF_SOFTWARE_MOUSE);
1756 		SDL_ShowCursor(SDL_FALSE);
1757 	}
1758 }
1759 
rbConfigMouseNice(void)1760 void rbConfigMouseNice(void)
1761 {
1762 	config.mouseType = MOUSE_IDLE_SHAPE_NICE;
1763 	checkRadioButton(RB_CONFIG_MOUSE_NICE);
1764 	createMouseCursors();
1765 	setMouseShape(config.mouseType);
1766 }
1767 
rbConfigMouseUgly(void)1768 void rbConfigMouseUgly(void)
1769 {
1770 	config.mouseType = MOUSE_IDLE_SHAPE_UGLY;
1771 	checkRadioButton(RB_CONFIG_MOUSE_UGLY);
1772 	createMouseCursors();
1773 	setMouseShape(config.mouseType);
1774 }
1775 
rbConfigMouseAwful(void)1776 void rbConfigMouseAwful(void)
1777 {
1778 	config.mouseType = MOUSE_IDLE_SHAPE_AWFUL;
1779 	checkRadioButton(RB_CONFIG_MOUSE_AWFUL);
1780 	createMouseCursors();
1781 	setMouseShape(config.mouseType);
1782 }
1783 
rbConfigMouseUsable(void)1784 void rbConfigMouseUsable(void)
1785 {
1786 	config.mouseType = MOUSE_IDLE_SHAPE_USABLE;
1787 	checkRadioButton(RB_CONFIG_MOUSE_USABLE);
1788 	createMouseCursors();
1789 	setMouseShape(config.mouseType);
1790 }
1791 
rbConfigMouseBusyVogue(void)1792 void rbConfigMouseBusyVogue(void)
1793 {
1794 	config.mouseAnimType = MOUSE_BUSY_SHAPE_GLASS;
1795 	checkRadioButton(RB_CONFIG_MOUSE_BUSY_GLASS);
1796 	resetMouseBusyAnimation();
1797 }
1798 
rbConfigMouseBusyMrH(void)1799 void rbConfigMouseBusyMrH(void)
1800 {
1801 	config.mouseAnimType = MOUSE_BUSY_SHAPE_CLOCK;
1802 	checkRadioButton(RB_CONFIG_MOUSE_BUSY_CLOCK);
1803 	resetMouseBusyAnimation();
1804 }
1805 
rbConfigScopeStandard(void)1806 void rbConfigScopeStandard(void)
1807 {
1808 	config.specialFlags &= ~LINED_SCOPES;
1809 	checkRadioButton(RB_CONFIG_SCOPE_NORMAL);
1810 }
1811 
rbConfigScopeLined(void)1812 void rbConfigScopeLined(void)
1813 {
1814 	config.specialFlags |= LINED_SCOPES;
1815 	checkRadioButton(RB_CONFIG_SCOPE_LINED);
1816 }
1817 
rbConfigPatt4Chans(void)1818 void rbConfigPatt4Chans(void)
1819 {
1820 	config.ptnMaxChannels = MAX_CHANS_SHOWN_4;
1821 	checkRadioButton(RB_CONFIG_MAXCHAN_4);
1822 	ui.maxVisibleChannels = 2 + (((uint8_t)config.ptnMaxChannels + 1) * 2);
1823 	redrawPatternEditor();
1824 }
1825 
rbConfigPatt6Chans(void)1826 void rbConfigPatt6Chans(void)
1827 {
1828 	config.ptnMaxChannels = MAX_CHANS_SHOWN_6;
1829 	checkRadioButton(RB_CONFIG_MAXCHAN_6);
1830 	ui.maxVisibleChannels = 2 + (((uint8_t)config.ptnMaxChannels + 1) * 2);
1831 	redrawPatternEditor();
1832 }
1833 
rbConfigPatt8Chans(void)1834 void rbConfigPatt8Chans(void)
1835 {
1836 	config.ptnMaxChannels = MAX_CHANS_SHOWN_8;
1837 	checkRadioButton(RB_CONFIG_MAXCHAN_8);
1838 	ui.maxVisibleChannels = 2 + (((uint8_t)config.ptnMaxChannels + 1) * 2);
1839 	redrawPatternEditor();
1840 }
1841 
rbConfigPatt12Chans(void)1842 void rbConfigPatt12Chans(void)
1843 {
1844 	config.ptnMaxChannels = MAX_CHANS_SHOWN_12;
1845 	checkRadioButton(RB_CONFIG_MAXCHAN_12);
1846 	ui.maxVisibleChannels = 2 + (((uint8_t)config.ptnMaxChannels + 1) * 2);
1847 	redrawPatternEditor();
1848 }
1849 
rbConfigFontCapitals(void)1850 void rbConfigFontCapitals(void)
1851 {
1852 	config.ptnFont = PATT_FONT_CAPITALS;
1853 	checkRadioButton(RB_CONFIG_FONT_CAPITALS);
1854 	updatePattFontPtrs();
1855 	redrawPatternEditor();
1856 }
1857 
rbConfigFontLowerCase(void)1858 void rbConfigFontLowerCase(void)
1859 {
1860 	config.ptnFont = PATT_FONT_LOWERCASE;
1861 	checkRadioButton(RB_CONFIG_FONT_LOWERCASE);
1862 	updatePattFontPtrs();
1863 	redrawPatternEditor();
1864 }
1865 
rbConfigFontFuture(void)1866 void rbConfigFontFuture(void)
1867 {
1868 	config.ptnFont = PATT_FONT_FUTURE;
1869 	checkRadioButton(RB_CONFIG_FONT_FUTURE);
1870 	updatePattFontPtrs();
1871 	redrawPatternEditor();
1872 }
1873 
rbConfigFontBold(void)1874 void rbConfigFontBold(void)
1875 {
1876 	config.ptnFont = PATT_FONT_BOLD;
1877 	checkRadioButton(RB_CONFIG_FONT_BOLD);
1878 	updatePattFontPtrs();
1879 	redrawPatternEditor();
1880 }
1881 
rbFileSortExt(void)1882 void rbFileSortExt(void)
1883 {
1884 	config.cfg_SortPriority = FILESORT_EXT;
1885 	checkRadioButton(RB_CONFIG_FILESORT_EXT);
1886 	editor.diskOpReadOnOpen = true;
1887 }
1888 
rbFileSortName(void)1889 void rbFileSortName(void)
1890 {
1891 	config.cfg_SortPriority = FILESORT_NAME;
1892 	checkRadioButton(RB_CONFIG_FILESORT_NAME);
1893 	editor.diskOpReadOnOpen = true;
1894 }
1895 
rbWinSizeAuto(void)1896 void rbWinSizeAuto(void)
1897 {
1898 	if (video.fullscreen)
1899 	{
1900 		okBox(0, "System message", "You can't change the window size while in fullscreen mode!");
1901 		return;
1902 	}
1903 
1904 	config.windowFlags &= ~(WINSIZE_1X + WINSIZE_2X + WINSIZE_3X + WINSIZE_4X);
1905 	config.windowFlags |= WINSIZE_AUTO;
1906 	setWindowSizeFromConfig(true);
1907 	checkRadioButton(RB_CONFIG_WIN_SIZE_AUTO);
1908 }
1909 
rbWinSize1x(void)1910 void rbWinSize1x(void)
1911 {
1912 	if (video.fullscreen)
1913 	{
1914 		okBox(0, "System message", "You can't change the window size while in fullscreen mode!");
1915 		return;
1916 	}
1917 
1918 	config.windowFlags &= ~(WINSIZE_AUTO + WINSIZE_2X + WINSIZE_3X + WINSIZE_4X);
1919 	config.windowFlags |= WINSIZE_1X;
1920 	setWindowSizeFromConfig(true);
1921 	checkRadioButton(RB_CONFIG_WIN_SIZE_1X);
1922 }
1923 
rbWinSize2x(void)1924 void rbWinSize2x(void)
1925 {
1926 	if (video.fullscreen)
1927 	{
1928 		okBox(0, "System message", "You can't change the window size while in fullscreen mode!");
1929 		return;
1930 	}
1931 
1932 	config.windowFlags &= ~(WINSIZE_AUTO + WINSIZE_1X + WINSIZE_3X + WINSIZE_4X);
1933 	config.windowFlags |= WINSIZE_2X;
1934 	setWindowSizeFromConfig(true);
1935 	checkRadioButton(RB_CONFIG_WIN_SIZE_2X);
1936 }
1937 
rbWinSize3x(void)1938 void rbWinSize3x(void)
1939 {
1940 	if (video.fullscreen)
1941 	{
1942 		okBox(0, "System message", "You can't change the window size while in fullscreen mode!");
1943 		return;
1944 	}
1945 
1946 #ifdef __arm__
1947 	okBox(0, "System message", "3x video upscaling is not supported on ARM devices for performance reasons.");
1948 #else
1949 	config.windowFlags &= ~(WINSIZE_AUTO + WINSIZE_1X + WINSIZE_2X + WINSIZE_4X);
1950 	config.windowFlags |= WINSIZE_3X;
1951 	setWindowSizeFromConfig(true);
1952 	checkRadioButton(RB_CONFIG_WIN_SIZE_3X);
1953 #endif
1954 }
1955 
rbWinSize4x(void)1956 void rbWinSize4x(void)
1957 {
1958 	if (video.fullscreen)
1959 	{
1960 		okBox(0, "System message", "You can't change the window size while in fullscreen mode!");
1961 		return;
1962 	}
1963 
1964 #ifdef __arm__
1965 	okBox(0, "System message", "4x video upscaling is not supported on ARM devices for performance reasons.");
1966 #else
1967 	config.windowFlags &= ~(WINSIZE_AUTO + WINSIZE_1X + WINSIZE_2X + WINSIZE_3X);
1968 	config.windowFlags |= WINSIZE_4X;
1969 	setWindowSizeFromConfig(true);
1970 	checkRadioButton(RB_CONFIG_WIN_SIZE_4X);
1971 #endif
1972 }
1973 
cbSampCutToBuff(void)1974 void cbSampCutToBuff(void)
1975 {
1976 	config.smpCutToBuffer ^= 1;
1977 }
1978 
cbPattCutToBuff(void)1979 void cbPattCutToBuff(void)
1980 {
1981 	config.ptnCutToBuffer ^= 1;
1982 }
1983 
cbKillNotesAtStop(void)1984 void cbKillNotesAtStop(void)
1985 {
1986 	config.killNotesOnStopPlay ^= 1;
1987 }
1988 
cbFileOverwriteWarn(void)1989 void cbFileOverwriteWarn(void)
1990 {
1991 	config.cfg_OverwriteWarning ^= 1;
1992 }
1993 
cbMultiChanRec(void)1994 void cbMultiChanRec(void)
1995 {
1996 	config.multiRec ^= 1;
1997 }
1998 
cbMultiChanKeyJazz(void)1999 void cbMultiChanKeyJazz(void)
2000 {
2001 	config.multiKeyJazz ^= 1;
2002 }
2003 
cbMultiChanEdit(void)2004 void cbMultiChanEdit(void)
2005 {
2006 	config.multiEdit ^= 1;
2007 }
2008 
cbRecKeyOff(void)2009 void cbRecKeyOff(void)
2010 {
2011 	config.recRelease ^= 1;
2012 }
2013 
cbQuantization(void)2014 void cbQuantization(void)
2015 {
2016 	config.recQuant ^= 1;
2017 }
2018 
cbChangePattLenInsDel(void)2019 void cbChangePattLenInsDel(void)
2020 {
2021 	config.recTrueInsert ^= 1;
2022 }
2023 
cbMIDIAllowPC(void)2024 void cbMIDIAllowPC(void)
2025 {
2026 	config.recMIDIAllowPC ^= 1;
2027 }
2028 
cbMIDIEnable(void)2029 void cbMIDIEnable(void)
2030 {
2031 #ifdef HAS_MIDI
2032 	midi.enable ^= 1;
2033 #else
2034 	checkBoxes[CB_CONF_MIDI_ENABLE].checked = false;
2035 	drawCheckBox(CB_CONF_MIDI_ENABLE);
2036 
2037 	okBox(0, "System message", "This program was not compiled with MIDI functionality!");
2038 #endif
2039 }
2040 
cbMIDIRecTransp(void)2041 void cbMIDIRecTransp(void)
2042 {
2043 	config.recMIDITransp ^= 1;
2044 }
2045 
cbMIDIRecAllChn(void)2046 void cbMIDIRecAllChn(void)
2047 {
2048 	config.recMIDIAllChn ^= 1;
2049 }
2050 
cbMIDIRecVelocity(void)2051 void cbMIDIRecVelocity(void)
2052 {
2053 	config.recMIDIVelocity ^= 1;
2054 }
2055 
cbMIDIRecAftert(void)2056 void cbMIDIRecAftert(void)
2057 {
2058 	config.recMIDIAftert ^= 1;
2059 }
2060 
cbVsyncOff(void)2061 void cbVsyncOff(void)
2062 {
2063 	config.windowFlags ^= FORCE_VSYNC_OFF;
2064 
2065 	if (!(config.dontShowAgainFlags & DONT_SHOW_NOT_YET_APPLIED_WARNING_FLAG))
2066 		okBox(7, "System message", "This setting is not applied until you close and reopen the program.");
2067 }
2068 
cbFullScreen(void)2069 void cbFullScreen(void)
2070 {
2071 	config.windowFlags ^= START_IN_FULLSCR;
2072 
2073 	if (!(config.dontShowAgainFlags & DONT_SHOW_NOT_YET_APPLIED_WARNING_FLAG))
2074 		okBox(7, "System message", "This setting is not applied until you close and reopen the program.");
2075 }
2076 
cbPixelFilter(void)2077 void cbPixelFilter(void)
2078 {
2079 	config.windowFlags ^= PIXEL_FILTER;
2080 
2081 	recreateTexture();
2082 	if (video.fullscreen)
2083 	{
2084 		leaveFullScreen();
2085 		enterFullscreen();
2086 	}
2087 }
2088 
cbStretchImage(void)2089 void cbStretchImage(void)
2090 {
2091 	config.specialFlags2 ^= STRETCH_IMAGE;
2092 
2093 	if (video.fullscreen)
2094 	{
2095 		leaveFullScreen();
2096 		enterFullscreen();
2097 	}
2098 }
2099 
configQuantizeUp(void)2100 void configQuantizeUp(void)
2101 {
2102 	if (config.recQuantRes <= 8)
2103 	{
2104 		config.recQuantRes *= 2;
2105 		drawQuantValue();
2106 	}
2107 }
2108 
configQuantizeDown(void)2109 void configQuantizeDown(void)
2110 {
2111 	if (config.recQuantRes > 1)
2112 	{
2113 		config.recQuantRes /= 2;
2114 		drawQuantValue();
2115 	}
2116 }
2117 
configMIDIChnUp(void)2118 void configMIDIChnUp(void)
2119 {
2120 	config.recMIDIChn++;
2121 	config.recMIDIChn = ((config.recMIDIChn - 1) & 15) + 1;
2122 
2123 	drawMIDIChanValue();
2124 }
2125 
configMIDIChnDown(void)2126 void configMIDIChnDown(void)
2127 {
2128 	config.recMIDIChn--;
2129 	config.recMIDIChn = (((uint16_t)(config.recMIDIChn - 1)) & 15) + 1;
2130 
2131 	drawMIDIChanValue();
2132 }
2133 
configMIDITransUp(void)2134 void configMIDITransUp(void)
2135 {
2136 	if (config.recMIDITranspVal < 72)
2137 	{
2138 		config.recMIDITranspVal++;
2139 		drawMIDITransp();
2140 	}
2141 }
2142 
configMIDITransDown(void)2143 void configMIDITransDown(void)
2144 {
2145 	if (config.recMIDITranspVal > -72)
2146 	{
2147 		config.recMIDITranspVal--;
2148 		drawMIDITransp();
2149 	}
2150 }
2151 
configMIDISensDown(void)2152 void configMIDISensDown(void)
2153 {
2154 	scrollBarScrollLeft(SB_MIDI_SENS, 1);
2155 }
2156 
configMIDISensUp(void)2157 void configMIDISensUp(void)
2158 {
2159 	scrollBarScrollRight(SB_MIDI_SENS, 1);
2160 }
2161 
sbMIDISens(uint32_t pos)2162 void sbMIDISens(uint32_t pos)
2163 {
2164 	if (config.recMIDIVolSens != (int16_t)pos)
2165 	{
2166 		config.recMIDIVolSens = (int16_t)pos;
2167 		drawMIDISens();
2168 	}
2169 }
2170 
sbAmp(uint32_t pos)2171 void sbAmp(uint32_t pos)
2172 {
2173 	if (config.boostLevel != (int8_t)pos + 1)
2174 	{
2175 		config.boostLevel = (int8_t)pos + 1;
2176 		setAudioAmp(config.boostLevel, config.masterVol, !!(config.specialFlags & BITDEPTH_32));
2177 		configDrawAmp();
2178 		updateWavRendererSettings();
2179 	}
2180 }
2181 
configAmpDown(void)2182 void configAmpDown(void)
2183 {
2184 	scrollBarScrollLeft(SB_AMP_SCROLL, 1);
2185 }
2186 
configAmpUp(void)2187 void configAmpUp(void)
2188 {
2189 	scrollBarScrollRight(SB_AMP_SCROLL, 1);
2190 }
2191 
sbMasterVol(uint32_t pos)2192 void sbMasterVol(uint32_t pos)
2193 {
2194 	if (config.masterVol != (int16_t)pos)
2195 	{
2196 		config.masterVol = (int16_t)pos;
2197 		setAudioAmp(config.boostLevel, config.masterVol, !!(config.specialFlags & BITDEPTH_32));
2198 	}
2199 }
2200 
configMasterVolDown(void)2201 void configMasterVolDown(void)
2202 {
2203 	scrollBarScrollLeft(SB_MASTERVOL_SCROLL, 1);
2204 }
2205 
configMasterVolUp(void)2206 void configMasterVolUp(void)
2207 {
2208 	scrollBarScrollRight(SB_MASTERVOL_SCROLL, 1);
2209 }
2210