|
|
1.1 ! root 1: /* Generator is (c) James Ponder, 1997-2001 http://www.squish.net/generator/ */ ! 2: ! 3: /* gtk options loading/saving */ ! 4: ! 5: #define _GNU_SOURCE 1 ! 6: #define _BSD_SOURCE 1 ! 7: #define __EXTENSIONS__ 1 ! 8: ! 9: #include <stdio.h> ! 10: #include <string.h> ! 11: #include <errno.h> ! 12: #include <stdlib.h> ! 13: ! 14: #include "generator.h" ! 15: #include "gtkopts.h" ! 16: ! 17: t_conf *gtkopts_conf = NULL; ! 18: ! 19: static const char *gtkopts_default(const char *key); ! 20: ! 21: #define CONFLINELEN 1024 ! 22: ! 23: typedef struct { ! 24: char *key; ! 25: char *vals; ! 26: char *def; ! 27: char *desc; ! 28: } t_opts; ! 29: ! 30: /* *INDENT-OFF* */ ! 31: ! 32: static t_opts gtkopts_opts[] = { ! 33: { "view", "100, 200", "100", ! 34: "view mode to use in percent" }, ! 35: { "region", "domestic, overseas", "overseas", ! 36: "hardware region" }, ! 37: { "videostd", "ntsc, pal", "ntsc", ! 38: "video standard" }, ! 39: { "autodetect", "on, off", "on", ! 40: "automatic region, videostd detection" }, ! 41: { "plotter", "line, cell", "line", ! 42: "plotter style - line is slower but much more accurate" }, ! 43: { "interlace", "bob, weave, weave-filter", "weave-filter", ! 44: "style of de-interlacing to use in 200% view mode" }, ! 45: { "frameskip", "auto, 1..10", "auto", ! 46: "skip frames to keep up - auto setting needs sound turned on" }, ! 47: { "hborder", "0..32", "8", ! 48: "horizontal over-scan border surrounding main playing area" }, ! 49: { "vborder", "0..32", "8", ! 50: "vertical retrace border surrounding main playing area" }, ! 51: { "sound", "on, off", "on", ! 52: "sound system toggle, also turns off fm and psg (not z80)" }, ! 53: { "z80", "on, off", "on", ! 54: "z80 cpu" }, ! 55: { "fm", "on, off", "on", ! 56: "frequency modulation sound generation" }, ! 57: { "psg", "on, off", "on", ! 58: "programmable sound generation" }, ! 59: { "sound_minfields", "integer", "5", ! 60: "try to buffer this many fields of sound" }, ! 61: { "sound_maxfields", "integer", "10", ! 62: "maximum buffered sound fields before blocking (waiting)" }, ! 63: { "loglevel", "integer (0-7)", "1", ! 64: "logging level" }, ! 65: { "debugsound", "on, off", "off", ! 66: "extra sound debug logging" }, ! 67: { "statusbar", "on, off", "off", ! 68: "status bar on main window (fps counter)" }, ! 69: { "key1_a", "gdk keysym", "a", ! 70: "keyboard player 1 'A' button" }, ! 71: { "key1_b", "gdk keysym", "s", ! 72: "keyboard player 1 'B' button" }, ! 73: { "key1_c", "gdk keysym", "d", ! 74: "keyboard player 1 'C' button" }, ! 75: { "key1_up", "gdk keysym", "Up", ! 76: "keyboard player 1 up" }, ! 77: { "key1_down", "gdk keysym", "Down", ! 78: "keyboard player 1 down" }, ! 79: { "key1_left", "gdk keysym", "Left", ! 80: "keyboard player 1 left" }, ! 81: { "key1_right", "gdk keysym", "Right", ! 82: "keyboard player 1 right" }, ! 83: { "key1_start", "gdk keysym", "Return", ! 84: "keyboard player 1 start button" }, ! 85: { "key2_a", "gdk keysym", "KP_Divide", ! 86: "keyboard player 2 'A' button" }, ! 87: { "key2_b", "gdk keysym", "KP_Multiply", ! 88: "keyboard player 2 'B' button" }, ! 89: { "key2_c", "gdk keysym", "KP_Subtract", ! 90: "keyboard player 2 'C' button" }, ! 91: { "key2_up", "gdk keysym", "KP_8", ! 92: "keyboard player 2 up" }, ! 93: { "key2_down", "gdk keysym", "KP_5", ! 94: "keyboard player 2 down" }, ! 95: { "key2_left", "gdk keysym", "KP_4", ! 96: "keyboard player 2 left" }, ! 97: { "key2_right", "gdk keysym", "KP_6", ! 98: "keyboard player 2 right" }, ! 99: { "key2_start", "gdk keysym", "KP_Enter", ! 100: "keyboard player 2 start button" }, ! 101: { NULL, NULL, NULL, NULL } ! 102: }; ! 103: ! 104: /* *INDENT-ON* */ ! 105: ! 106: int gtkopts_load(const char *file) ! 107: { ! 108: char buffer[CONFLINELEN]; ! 109: FILE *fd; ! 110: char *a, *p, *q, *t; ! 111: int line = 0; ! 112: t_conf *conf, *confi; ! 113: ! 114: if ((fd = fopen(file, "r")) == NULL) { ! 115: fprintf(stderr, "%s: unable to open conf '%s' for reading: %s\n", ! 116: PACKAGE, file, strerror(errno)); ! 117: return -1; ! 118: } ! 119: while (fgets(buffer, CONFLINELEN, fd)) { ! 120: line++; ! 121: if (buffer[strlen(buffer) - 1] != '\n') { ! 122: fprintf(stderr, "%s: line %d too long in conf file, ignoring.\n", ! 123: PACKAGE, line); ! 124: while ((a = fgets(buffer, CONFLINELEN, fd))) { ! 125: if (buffer[strlen(buffer) - 1] == '\n') ! 126: continue; ! 127: } ! 128: if (!a) ! 129: goto finished; ! 130: continue; ! 131: } ! 132: buffer[strlen(buffer) - 1] = '\0'; ! 133: /* remove whitespace off start and end */ ! 134: p = buffer + strlen(buffer) - 1; ! 135: while (p > buffer && *p == ' ') ! 136: *p-- = '\0'; ! 137: p = buffer; ! 138: while (*p == ' ') ! 139: p++; ! 140: /* check for comment */ ! 141: if (!*p || *p == '#' || *p == ';') ! 142: continue; ! 143: if ((conf = malloc(sizeof(t_conf))) == NULL) { ! 144: fprintf(stderr, "%s: Out of memory adding to conf\n", PACKAGE); ! 145: goto error; ! 146: } ! 147: q = p; ! 148: strsep(&q, "="); ! 149: if (q == NULL) { ! 150: fprintf(stderr, "%s: line %d not understood in conf file\n", PACKAGE, ! 151: line); ! 152: goto error; ! 153: } ! 154: /* remove whitespace off end of p and start of q */ ! 155: t = p + strlen(p) - 1; ! 156: while (t > p && *t == ' ') ! 157: *t-- = '\0'; ! 158: while (*q == ' ') ! 159: q++; ! 160: if ((conf->key = malloc(strlen(p) + 1)) == NULL || ! 161: (conf->value = malloc(strlen(q) + 1)) == NULL) { ! 162: fprintf(stderr, "%s: Out of memory building conf\n", PACKAGE); ! 163: goto error; ! 164: } ! 165: strcpy(conf->key, p); ! 166: strcpy(conf->value, q); ! 167: conf->next = NULL; ! 168: for (confi = gtkopts_conf; confi && confi->next; confi = confi->next); ! 169: if (!confi) ! 170: gtkopts_conf = conf; ! 171: else ! 172: confi->next = conf; ! 173: } ! 174: finished: ! 175: if (ferror(fd) || fclose(fd)) { ! 176: fprintf(stderr, "%s: error whilst reading conf: %s\n", PACKAGE, ! 177: strerror(errno)); ! 178: return -1; ! 179: } ! 180: return 0; ! 181: error: ! 182: fclose(fd); ! 183: return -1; ! 184: } ! 185: ! 186: const char *gtkopts_getvalue(const char *key) ! 187: { ! 188: t_conf *c; ! 189: const char *v; ! 190: ! 191: for (c = gtkopts_conf; c; c = c->next) { ! 192: if (!strcasecmp(key, c->key)) ! 193: return c->value; ! 194: } ! 195: v = gtkopts_default(key); ! 196: if (!v) ! 197: printf("Warning: invalid option '%s' requested.\n", key); ! 198: return v; ! 199: } ! 200: ! 201: int gtkopts_setvalue(const char *key, const char *value) ! 202: { ! 203: t_conf *c; ! 204: char *n; ! 205: ! 206: for (c = gtkopts_conf; c; c = c->next) { ! 207: if (!strcasecmp(key, c->key)) { ! 208: if ((n = malloc(strlen(value) + 1)) == NULL) ! 209: return -1; ! 210: strcpy(n, value); ! 211: free(c->value); ! 212: c->value = n; ! 213: return 0; ! 214: } ! 215: } ! 216: if ((c = malloc(sizeof(t_conf))) == NULL || ! 217: (c->key = malloc(strlen(key) + 1)) == NULL || ! 218: (c->value = malloc(strlen(value) + 1)) == NULL) ! 219: return -1; ! 220: strcpy(c->key, key); ! 221: strcpy(c->value, value); ! 222: c->next = gtkopts_conf; ! 223: gtkopts_conf = c; ! 224: return 0; ! 225: } ! 226: ! 227: int gtkopts_save(const char *file) ! 228: { ! 229: FILE *fd; ! 230: t_opts *o; ! 231: ! 232: if ((fd = fopen(file, "w")) == NULL) { ! 233: fprintf(stderr, "%s: unable to open conf '%s' for writing: %s\n", ! 234: PACKAGE, file, strerror(errno)); ! 235: return -1; ! 236: } ! 237: fprintf(fd, "; Generator " VERSION " configuration file\n\n"); ! 238: fprintf(fd, "; for GTK keysyms see include/gtk-1.2/gdk/gdkkeysyms.h\n\n"); ! 239: for (o = gtkopts_opts; o->key; o++) { ! 240: fprintf(fd, "; %s\n; values: %s\n", o->desc, o->vals); ! 241: fprintf(fd, "%s = %s\n\n", o->key, gtkopts_getvalue(o->key)); ! 242: } ! 243: if (fclose(fd)) { ! 244: fprintf(stderr, "%s: error whilst writing conf: %s\n", PACKAGE, ! 245: strerror(errno)); ! 246: return -1; ! 247: } ! 248: return 0; ! 249: } ! 250: ! 251: static const char *gtkopts_default(const char *key) ! 252: { ! 253: t_opts *o; ! 254: ! 255: for (o = gtkopts_opts; o->key; o++) { ! 256: if (!strcasecmp(key, o->key)) ! 257: return o->def; ! 258: } ! 259: return NULL; ! 260: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.