/* $Id: options.c,v 1.4 2006/09/15 13:34:06 toad32767 Exp $ */ /** ** 2005, 2006 by Marco Trillo ** This file is part of UModPlayer, and is released by ** its autors to the Public Domain. ** In case it's not legally possible, its autors grant ** anyone the right to use, redistribute and modify ** this software for any purpose, without any conditions, ** unless such conditions are required by law. ** ** THIS FILE COMES WITHOUT ANY WARRANTY. THE AUTHORS ** SHALL NOT BE LIABLE FOR ANY DAMAGE RESULTING BY THE ** USE OR MISUSE OF THIS SOFTWARE. **/ /* * ===================== * OPTIONS-RELATED STUFF * ===================== */ #include #include #include #include /* * Try to detect the local endianness */ LOCAL Endian DetectEndian() { union cio { uint16_t w; uint8_t b[2]; } d; d.w = 0xCAFE; if (d.b[0] == 0xCA && d.b[1] == 0xFE) { return BIG_ENDIAN; } else if (d.b[0] == 0xFE && d.b[1] == 0xCA) { return LTE_ENDIAN; } else { fputs(">>> WARNING: CAN'T detect local endianness!\n", stderr); fputs(">>> Please set it manually with the `setadvanced' command\n", stderr); return UNKNOWN_ENDIAN; } /* NOTREACHED */ return UNKNOWN_ENDIAN; } EXPORT void DefaultOptions(struct oFlags * ops) { ops->samplerate = DEFAULT_SAMPLERATE; ops->flags = MODPLUG_ENABLE_OVERSAMPLING; ops->resampling = MODPLUG_RESAMPLE_SPLINE; ops->vol = 128; ops->channels = 2; ops->reverbDepth = 20; ops->reverbDelay = 60; ops->bassAmount = 40; ops->bassRange = 50; ops->surroundDepth = 50; ops->surroundDelay = 20; ops->appareance = TABLE_THEME_CLASSIC; ops->endianness = DetectEndian(); ops->verbosity = 1; return; } EXPORT void InitOptions(struct oFlags * ops) { char *path, *home; int fd, bytes_in, dodefaults = 1; home = getenv("HOME"); if (home != NULL) { path = (char *) malloc(strlen(home) + strlen(PREFS_FILE) + 2); if (path == NULL) { error("%s", MESSAGE_NO_MEMORY); UFreeFile(); exit(UM_ERR_MEMORY); } strcpy(path, home); strcat(path, "/"); strcat(path, PREFS_FILE); fd = open(path, O_RDONLY); if (fd != -1) { bytes_in = read(fd, ops, sizeof(struct oFlags)); if (bytes_in == sizeof(struct oFlags)) dodefaults = 0; close(fd); } free(path); } if (dodefaults == 1) { DefaultOptions(ops); } return; } EXPORT void SaveOptions(struct oFlags * ops) { char *path, *home; int fd; home = getenv("HOME"); if (home != NULL) { path = (char *) malloc(strlen(home) + strlen(PREFS_FILE) + 2); if (path == NULL) { error("%s", MESSAGE_NO_MEMORY); UFreeFile(); exit(UM_ERR_MEMORY); } strcpy(path, home); strcat(path, "/"); strcat(path, PREFS_FILE); fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, 0600); if (fd != -1) { (void) write(fd, ops, sizeof(struct oFlags)); close(fd); } free(path); } return; } EXPORT void AdvancedConfig() { static char vbuf[4]; WTable table; int i; rr = (char **) malloc(9 * sizeof(char *)); rr[0] = (char *) malloc(8); sprintf(rr[0], "%d", sets.reverbDepth); rr[1] = (char *) malloc(8); sprintf(rr[1], "%d ms", sets.reverbDelay); rr[2] = (char *) malloc(8); sprintf(rr[2], "%d", sets.bassAmount); rr[3] = (char *) malloc(8); sprintf(rr[3], "%d Hz", sets.bassRange); rr[4] = (char *) malloc(8); sprintf(rr[4], "%d", sets.surroundDepth); rr[5] = (char *) malloc(16); sprintf(rr[5], "%d ms", sets.surroundDelay); if (sets.endianness == BIG_ENDIAN) { rr[6] = "big-endian"; } else if (sets.endianness == LTE_ENDIAN) { rr[6] = "little-endian"; } else { rr[6] = "unknown!"; } if (sets.appareance == TABLE_THEME_CLASSIC) { rr[7] = "classic"; } else if (sets.appareance == TABLE_THEME_STRONG) { rr[7] = "strong"; } else { rr[7] = "boxed"; } snprintf(vbuf, 4, "%d", sets.verbosity); rr[8] = vbuf; TableSetOptions(&table, 2, 9, 2, 16, 0, TABLE_LEFT_ALIGN); TableInitCallback(&table, MyTextCallback); TableUseTheme(&table, sets.appareance); DrawTable(table); for (i = 0; i < 6; ++i) free(rr[i]); free(rr); return; } LOCAL void AskUserForData(const char *str, int minvalue, int maxvalue, int *putdata) { char *e; int k; for (;;) { fputs(str, stdout); fflush(stdout); e = ReadString(); if (e == NULL) { error("%s", MESSAGE_NO_MEMORY); return; } TrimString(e); if (*e == 0) return; k = atoi(e); free(e); if (k < minvalue || k > maxvalue) { continue; } *putdata = k; break; } return; } EXPORT void SetAdvancedConfig() { char *response; AskUserForData("Reverb Depth [0-100]? ", 0, 100, &(sets.reverbDepth)); AskUserForData("Reverb Delay in ms. [40-200]? ", 40, 200, &(sets.reverbDelay)); AskUserForData("Bass Amount [0-100]? ", 0, 100, &(sets.bassAmount)); AskUserForData("Bass Range in Hz. [10-100]? ", 10, 100, &(sets.bassRange)); AskUserForData("Surround Depth [0-100]? ", 0, 100, &(sets.surroundDepth)); AskUserForData("Surround Delay in ms. [5-40]? ", 5, 40, &(sets.surroundDelay)); endian1: fputs("local endianness [little-endian, big-endian]? ", stdout); fflush(stdout); response = ReadString(); if (response == NULL) { error("%s", MESSAGE_NO_MEMORY); } else if (*response == '\0') { /* * skip to the next question */ free(response); goto appareance1; } else { /* * Use memcmp() instead of strcmp() * to match only the beginning of the string. * * I.e., any string starting with "little" will match * little-endian, no matter if its "little-endian", "littleendian", * "little", or whatever. */ if (memcmp(response, "little", 6) == 0) { sets.endianness = LTE_ENDIAN; } else if (memcmp(response, "big", 3) == 0) { sets.endianness = BIG_ENDIAN; } else { free(response); goto endian1; /* ask again until a valid response is found! */ } free(response); } appareance1: fputs("appareance [classic, strong, boxed]? ", stdout); fflush(stdout); response = ReadString(); if (response == NULL) { error("%s", MESSAGE_NO_MEMORY); } else if (*response == '\0') { /* * skip to the next question */ free(response); goto end; } else { if (strcmp(response, "classic") == 0) { sets.appareance = TABLE_THEME_CLASSIC; } else if (strcmp(response, "strong") == 0) { sets.appareance = TABLE_THEME_STRONG; } else if (strcmp(response, "boxed") == 0) { sets.appareance = TABLE_THEME_BOXED; } else { free(response); goto appareance1; } free(response); } end: AskUserForData("verbosity level? ", 0, 3, &(sets.verbosity)); }