|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * Config file handling
5: * This still needs some thought before it's complete...
6: *
7: * Copyright 1998 Brian King, Bernd Schmidt
8: */
9:
10: #include "sysconfig.h"
11: #include "sysdeps.h"
12:
13: #include <ctype.h>
14:
15: #include "options.h"
1.1.1.10 root 16: #include "threaddep/thread.h"
1.1 root 17: #include "uae.h"
18: #include "autoconf.h"
1.1.1.18! root 19: #include "filesys.h"
1.1.1.8 root 20: #include "events.h"
1.1.1.3 root 21: #include "custom.h"
1.1.1.18! root 22: #include "audio.h"
1.1.1.16 root 23: #include "inputdevice.h"
1.1.1.18! root 24: #include "romlist.h"
! 25: #include "gui.h"
1.1.1.16 root 26:
27: #define cfgfile_write fprintf
1.1 root 28:
29: /* @@@ need to get rid of this... just cut part of the manual and print that
30: * as a help text. */
31: struct cfg_lines
32: {
33: const char *config_label, *config_help;
34: };
35:
36: static struct cfg_lines opttable[] =
37: {
38: {"help", "Prints this help" },
39: {"config_description", "" },
40: {"use_gui", "Enable the GUI? If no, then goes straight to emulator" },
41: {"use_debugger", "Enable the debugger?" },
42: {"cpu_speed", "can be max, real, or a number between 1 and 20" },
43: {"cpu_type", "Can be 68000, 68010, 68020, 68020/68881" },
44: {"cpu_24bit_addressing", "must be set to 'no' in order for Z3mem or P96mem to work" },
45: {"log_illegal_mem", "print illegal memory access by Amiga software?" },
46: {"fastmem_size", "Size in megabytes of fast-memory" },
47: {"chipmem_size", "Size in megabytes of chip-memory" },
48: {"bogomem_size", "Size in megabytes of bogo-memory at 0xC00000" },
49: {"a3000mem_size", "Size in megabytes of A3000 memory" },
50: {"gfxcard_size", "Size in megabytes of Picasso96 graphics-card memory" },
51: {"z3mem_size", "Size in megabytes of Zorro-III expansion memory" },
52: {"gfx_test_speed", "Test graphics speed?" },
53: {"framerate", "Print every nth frame" },
54: {"gfx_width", "Screen width" },
55: {"gfx_height", "Screen height" },
56: {"gfx_lores", "Treat display as lo-res?" },
57: {"gfx_linemode", "Can be none, double, or scanlines" },
58: {"gfx_fullscreen_amiga", "Amiga screens are fullscreen?" },
59: {"gfx_fullscreen_picasso", "Picasso screens are fullscreen?" },
60: {"gfx_correct_aspect", "Correct aspect ratio?" },
61: {"gfx_center_horizontal", "Center display horizontally?" },
62: {"gfx_center_vertical", "Center display vertically?" },
63: {"gfx_colour_mode", "" },
64: {"32bit_blits", "Enable 32 bit blitter emulation" },
65: {"immediate_blits", "Perform blits immediately" },
1.1.1.15 root 66: {"show_leds", "LED display" },
1.1 root 67: {"sound_output", "" },
68: {"sound_frequency", "" },
69: {"sound_channels", "" },
70: {"sound_max_buff", "" },
71: {"parallel_on_demand", "" },
72: {"serial_on_demand", "" },
73: {"joyport0", "" },
74: {"joyport1", "" },
75: {"kickstart_rom_file", "Kickstart ROM image, (C) Copyright Amiga, Inc." },
1.1.1.12 root 76: {"kickstart_ext_rom_file", "Extended Kickstart ROM image, (C) Copyright Amiga, Inc." },
1.1 root 77: {"kickstart_key_file", "Key-file for encrypted ROM images (from Cloanto's Amiga Forever)" },
78: {"floppy0", "Diskfile for drive 0" },
79: {"floppy1", "Diskfile for drive 1" },
80: {"floppy2", "Diskfile for drive 2" },
81: {"floppy3", "Diskfile for drive 3" },
82: {"hardfile", "access,sectors, surfaces, reserved, blocksize, path format" },
83: {"filesystem", "access,'Amiga volume-name':'host directory path' - where 'access' can be 'read-only' or 'read-write'" }
84: };
85:
1.1.1.10 root 86: static const char *guimode1[] = { "no", "yes", "nowait", 0 };
87: static const char *guimode2[] = { "false", "true", "nowait", 0 };
88: static const char *guimode3[] = { "0", "1", "nowait", 0 };
89: static const char *csmode[] = { "ocs", "ecs_agnus", "ecs_denise", "ecs", "aga", 0 };
1.1 root 90: static const char *linemode1[] = { "none", "double", "scanlines", 0 };
91: static const char *linemode2[] = { "n", "d", "s", 0 };
92: static const char *speedmode[] = { "max", "real", 0 };
1.1.1.7 root 93: static const char *cpumode[] = {
1.1.1.18! root 94: "68000", "68010",
! 95: "68ec020", "68ec020/68881", "68ec020/68882",
! 96: "68020", "68020/68881", "68020/68882",
! 97: "68030", "68030/68881", "68030/68882",
! 98: "68040", "68060", 0
! 99: };
! 100: static int mode_to_cpumodel[] = {
! 101: 68000, 68010,
! 102: 68020, 68020, 68020,
! 103: 68020, 68020, 68020,
! 104: 68030, 68030, 68030,
! 105: 68040, 68060
! 106: };
! 107: static int mode_to_fpumodel[] = {
! 108: 0, 0,
! 109: 0, 68881, 68882,
! 110: 0, 68881, 68882,
! 111: 0, 68881, 68882,
! 112: 68040, 68060
1.1.1.7 root 113: };
1.1 root 114: static const char *colormode1[] = { "8bit", "15bit", "16bit", "8bit_dither", "4bit_dither", "32bit", 0 };
115: static const char *colormode2[] = { "8", "15", "16", "8d", "4d", "32", 0 };
116: static const char *soundmode[] = { "none", "interrupts", "normal", "exact", 0 };
1.1.1.2 root 117: static const char *centermode1[] = { "none", "simple", "smart", 0 };
118: static const char *centermode2[] = { "false", "true", "smart", 0 };
1.1.1.18! root 119: static const char *stereomode[] = { "mono", "stereo", "mixed", 0 };
! 120: static const char *interpolmode[] = { "none", "rh", "crux", "sinc", "anti", 0 };
! 121: static const char *soundfiltermode1[] = { "off", "emulated", "on", 0 };
! 122: static const char *soundfiltermode2[] = { "standard", "enhanced", 0 };
1.1.1.9 root 123: static const char *collmode[] = { "none", "sprites", "playfields", "full", 0 };
1.1.1.18! root 124: static const char *idemode[] = { "none", "a600/a1200", "a4000", 0 };
! 125:
! 126: static const char *obsolete[] = {
! 127: "accuracy", "gfx_opengl", "gfx_32bit_blits", "32bit_blits",
! 128: "gfx_immediate_blits", "gfx_ntsc", "win32", "gfx_filter_bits",
! 129: "sound_pri_cutoff", "sound_pri_time", "sound_min_buff", "sound_bits",
! 130: "gfx_test_speed", "gfxlib_replacement", "enforcer", "catweasel_io",
! 131: "fast_copper", "sound_adjust", "serial_hardware_dtrdsr", "cpu_compatible",
! 132: 0
! 133: };
1.1 root 134:
135: #define UNEXPANDED "$(FILE_PATH)"
136:
137: static int match_string (const char *table[], const char *str)
138: {
139: int i;
140: for (i = 0; table[i] != 0; i++)
141: if (strcasecmp (table[i], str) == 0)
142: return i;
143: return -1;
144: }
145:
146: char *cfgfile_subst_path (const char *path, const char *subst, const char *file)
147: {
148: /* @@@ use strcasecmp for some targets. */
149: if (strlen (path) > 0 && strncmp (file, path, strlen (path)) == 0) {
150: int l;
151: char *p = xmalloc (strlen (file) + strlen (subst) + 2);
152: strcpy (p, subst);
153: l = strlen (p);
154: while (l > 0 && p[l - 1] == '/')
155: p[--l] = '\0';
156: l = strlen (path);
157: while (file[l] == '/')
158: l++;
159: strcat (p, "/"); strcat (p, file + l);
160: return p;
161: }
162: return my_strdup (file);
163: }
164:
1.1.1.18! root 165: static void write_gfx_params (FILE *f, const struct gfx_params *p, const char *suffix)
1.1.1.17 root 166: {
167: cfgfile_write (f, "gfx_width_%s=%d\n", suffix, p->width);
168: cfgfile_write (f, "gfx_height_%s=%d\n", suffix, p->height);
169: cfgfile_write (f, "gfx_lores_%s=%s\n", suffix, p->lores ? "true" : "false");
170: cfgfile_write (f, "gfx_linemode_%s=%s\n", suffix, linemode1[p->linedbl]);
171: cfgfile_write (f, "gfx_correct_aspect_%s=%s\n", suffix, p->correct_aspect ? "true" : "false");
172: cfgfile_write (f, "gfx_center_horizontal_%s=%s\n", suffix, centermode1[p->xcenter]);
173: cfgfile_write (f, "gfx_center_vertical_%s=%s\n", suffix, centermode1[p->ycenter]);
1.1.1.18! root 174: cfgfile_write (f, "gfx_show_leds_%s=%s\n", suffix, p->leds_on_screen ? "true" : "false");
1.1.1.17 root 175: }
176:
1.1.1.18! root 177: void save_options (FILE *f, const struct uae_prefs *p)
1.1 root 178: {
179: struct strlist *sl;
180: char *str;
181: int i;
182:
1.1.1.16 root 183: cfgfile_write (f, "config_description=%s\n", p->description);
1.1 root 184:
185: for (sl = p->unknown_lines; sl; sl = sl->next)
1.1.1.16 root 186: cfgfile_write (f, "%s\n", sl->str);
1.1 root 187:
1.1.1.16 root 188: cfgfile_write (f, "%s.rom_path=%s\n", TARGET_NAME, p->path_rom);
189: cfgfile_write (f, "%s.floppy_path=%s\n", TARGET_NAME, p->path_floppy);
190: cfgfile_write (f, "%s.hardfile_path=%s\n", TARGET_NAME, p->path_hardfile);
1.1 root 191:
1.1.1.2 root 192: target_save_options (f, p);
193:
1.1.1.16 root 194: cfgfile_write (f, "use_gui=%s\n", guimode1[p->start_gui]);
195: cfgfile_write (f, "use_debugger=%s\n", p->start_debugger ? "true" : "false");
1.1 root 196: str = cfgfile_subst_path (p->path_rom, UNEXPANDED, p->romfile);
1.1.1.16 root 197: cfgfile_write (f, "kickstart_rom_file=%s\n", str);
1.1 root 198: free (str);
1.1.1.18! root 199: if (currprefs.rom_crc32)
! 200: cfgfile_write (f, "kickstart_rom_crc=0x%x\n", currprefs.rom_crc32);
1.1.1.12 root 201: str = cfgfile_subst_path (p->path_rom, UNEXPANDED, p->romextfile);
1.1.1.16 root 202: cfgfile_write (f, "kickstart_ext_rom_file=%s\n", str);
1.1.1.12 root 203: free (str);
1.1 root 204: str = cfgfile_subst_path (p->path_rom, UNEXPANDED, p->keyfile);
1.1.1.16 root 205: cfgfile_write (f, "kickstart_key_file=%s\n", str);
1.1 root 206: free (str);
1.1.1.16 root 207: cfgfile_write (f, "kickshifter=%s\n", p->kickshifter ? "true" : "false");
1.1 root 208:
209: for (i = 0; i < 4; i++) {
210: str = cfgfile_subst_path (p->path_floppy, UNEXPANDED, p->df[i]);
1.1.1.16 root 211: cfgfile_write (f, "floppy%d=%s\n", i, str);
1.1 root 212: free (str);
1.1.1.18! root 213: cfgfile_write (f, "floppy%dtype=%d\n", i, p->dfxtype[i]);
1.1 root 214: }
1.1.1.16 root 215: cfgfile_write (f, "nr_floppies=%d\n", p->nr_floppies);
216: cfgfile_write (f, "parallel_on_demand=%s\n", p->parallel_demand ? "true" : "false");
217: cfgfile_write (f, "serial_on_demand=%s\n", p->serial_demand ? "true" : "false");
218:
219: cfgfile_write (f, "sound_output=%s\n", soundmode[p->produce_sound]);
1.1.1.18! root 220: cfgfile_write (f, "sound_channels=%s\n", stereomode[p->sound_stereo]);
! 221: cfgfile_write (f, "sound_stereo_separation=%d\n", p->sound_stereo_separation);
! 222: cfgfile_write (f, "sound_stereo_mixing_delay=%d\n", p->sound_mixed_stereo_delay >= 0 ? p->sound_mixed_stereo_delay : 0);
1.1.1.16 root 223: cfgfile_write (f, "sound_max_buff=%d\n", p->sound_maxbsiz);
224: cfgfile_write (f, "sound_frequency=%d\n", p->sound_freq);
225: cfgfile_write (f, "sound_interpol=%s\n", interpolmode[p->sound_interpol]);
1.1.1.18! root 226: cfgfile_write (f, "sound_filter=%s\n", soundfiltermode1[p->sound_filter]);
! 227: cfgfile_write (f, "sound_filter_type=%s\n", soundfiltermode2[p->sound_filter_type]);
1.1.1.16 root 228:
229: for (i = 0; i < 2; i++) {
230: int v = i == 0 ? p->jport0 : p->jport1;
231: char tmp1[100], tmp2[50];
232: if (v < JSEM_JOYS) {
233: sprintf (tmp2, "kbd%d", v + 1);
234: } else if (v < JSEM_MICE) {
235: sprintf (tmp2, "joy%d", v - JSEM_JOYS);
236: } else {
237: strcpy (tmp2, "mouse");
238: if (v - JSEM_MICE > 0)
239: sprintf (tmp2, "mouse%d", v - JSEM_MICE);
240: }
241: sprintf (tmp1, "joyport%d=%s\n", i, tmp2);
242: cfgfile_write (f, tmp1);
243: }
244:
245: cfgfile_write (f, "bsdsocket_emu=%s\n", p->socket_emu ? "true" : "false");
246:
247: cfgfile_write (f, "gfx_framerate=%d\n", p->gfx_framerate);
1.1.1.17 root 248: write_gfx_params (f, &p->gfx_w, "windowed");
249: write_gfx_params (f, &p->gfx_f, "fullscreen");
1.1.1.16 root 250: cfgfile_write (f, "gfx_fullscreen_amiga=%s\n", p->gfx_afullscreen ? "true" : "false");
251: cfgfile_write (f, "gfx_fullscreen_picasso=%s\n", p->gfx_pfullscreen ? "true" : "false");
252: cfgfile_write (f, "gfx_colour_mode=%s\n", colormode1[p->color_mode]);
253:
254: cfgfile_write (f, "immediate_blits=%s\n", p->immediate_blits ? "true" : "false");
255: cfgfile_write (f, "ntsc=%s\n", p->ntscmode ? "true" : "false");
1.1.1.3 root 256: if (p->chipset_mask & CSMASK_AGA)
1.1.1.16 root 257: cfgfile_write (f, "chipset=aga\n");
1.1.1.3 root 258: else if ((p->chipset_mask & CSMASK_ECS_AGNUS) && (p->chipset_mask & CSMASK_ECS_AGNUS))
1.1.1.16 root 259: cfgfile_write (f, "chipset=ecs\n");
1.1.1.3 root 260: else if (p->chipset_mask & CSMASK_ECS_AGNUS)
1.1.1.16 root 261: cfgfile_write (f, "chipset=ecs_agnus\n");
1.1.1.3 root 262: else if (p->chipset_mask & CSMASK_ECS_DENISE)
1.1.1.16 root 263: cfgfile_write (f, "chipset=ecs_denise\n");
1.1.1.3 root 264: else
1.1.1.16 root 265: cfgfile_write (f, "chipset=ocs\n");
266: cfgfile_write (f, "collision_level=%s\n", collmode[p->collision_level]);
1.1 root 267:
1.1.1.18! root 268: cfgfile_write (f, "ide=%s\n", p->cs_ide == 1 ? "a600/a1200" : (p->cs_ide == 2 ? "a4000" : "none"));
! 269: cfgfile_write (f, "a1000ram=%s\n", p->cs_a1000ram ? "true" : "false");
! 270: cfgfile_write (f, "fatgary=%d\n", p->cs_fatgaryrev);
! 271: cfgfile_write (f, "ramsey=%d\n", p->cs_ramseyrev);
! 272:
1.1.1.16 root 273: cfgfile_write (f, "fastmem_size=%d\n", p->fastmem_size / 0x100000);
1.1.1.18! root 274: cfgfile_write (f, "a3000mem_size=%d\n", p->mbresmem_low_size / 0x100000);
! 275: cfgfile_write (f, "mbresmem_size=%d\n", p->mbresmem_high_size / 0x100000);
1.1.1.16 root 276: cfgfile_write (f, "z3mem_size=%d\n", p->z3fastmem_size / 0x100000);
277: cfgfile_write (f, "bogomem_size=%d\n", p->bogomem_size / 0x40000);
278: cfgfile_write (f, "gfxcard_size=%d\n", p->gfxmem_size / 0x100000);
279: cfgfile_write (f, "chipmem_size=%d\n", p->chipmem_size / 0x80000);
1.1 root 280:
1.1.1.3 root 281: if (p->m68k_speed > 0)
1.1.1.16 root 282: cfgfile_write (f, "finegrain_cpu_speed=%d\n", p->m68k_speed);
1.1 root 283: else
1.1.1.16 root 284: cfgfile_write (f, "cpu_speed=%s\n", p->m68k_speed == -1 ? "max" : "real");
1.1 root 285:
1.1.1.18! root 286: for (i = 0; cpumode[i] != NULL; i++)
! 287: if (mode_to_cpumodel[i] == p->cpu_model && mode_to_fpumodel[i] == p->fpu_model) {
! 288: cfgfile_write (f, "cpu_type=%s\n", cpumode[i]);
! 289: break;
! 290: }
1.1 root 291:
1.1.1.16 root 292: cfgfile_write (f, "log_illegal_mem=%s\n", p->illegal_mem ? "true" : "false");
1.1 root 293:
1.1.1.16 root 294: cfgfile_write (f, "kbd_lang=%s\n", (p->keyboard_lang == KBD_LANG_DE ? "de"
1.1.1.18! root 295: : p->keyboard_lang == KBD_LANG_DK ? "dk"
! 296: : p->keyboard_lang == KBD_LANG_ES ? "es"
! 297: : p->keyboard_lang == KBD_LANG_US ? "us"
! 298: : p->keyboard_lang == KBD_LANG_SE ? "se"
! 299: : p->keyboard_lang == KBD_LANG_FR ? "fr"
! 300: : p->keyboard_lang == KBD_LANG_IT ? "it"
! 301: : "FOO"));
1.1 root 302:
303: write_filesys_config (p->mountinfo, UNEXPANDED, p->path_hardfile, f);
304:
305: /* Don't write gfxlib/gfx_test_speed options. */
306: }
307:
1.1.1.18! root 308: int cfgfile_yesno (const char *option, const char *value, const char *name, int *location)
1.1 root 309: {
310: if (strcmp (option, name) != 0)
311: return 0;
312: if (strcasecmp (value, "yes") == 0 || strcasecmp (value, "y") == 0
313: || strcasecmp (value, "true") == 0 || strcasecmp (value, "t") == 0)
314: *location = 1;
315: else if (strcasecmp (value, "no") == 0 || strcasecmp (value, "n") == 0
316: || strcasecmp (value, "false") == 0 || strcasecmp (value, "f") == 0)
317: *location = 0;
318: else
319: write_log ("Option `%s' requires a value of either `yes' or `no'.\n", option);
320: return 1;
321: }
322:
1.1.1.18! root 323: int cfgfile_intval (const char *option, const char *value, const char *name, int *location, int scale)
1.1 root 324: {
325: int base = 10;
326: char *endptr;
327: if (strcmp (option, name) != 0)
328: return 0;
329: if (value[0] == '0' && value[1] == 'x')
1.1.1.18! root 330: base = 16;
1.1 root 331: *location = strtol (value, &endptr, base) * scale;
332:
333: if (*endptr != '\0' || *value == '\0')
334: write_log ("Option `%s' requires a numeric argument.\n", option);
335: return 1;
336: }
337:
1.1.1.18! root 338: int cfgfile_uintval (const char *option, const char *value, const char *name, unsigned int *location, int scale)
! 339: {
! 340: int base = 10;
! 341: char *endptr;
! 342: if (strcmp (option, name) != 0)
! 343: return 0;
! 344: if (value[0] == '0' && value[1] == 'x')
! 345: base = 16;
! 346: *location = strtoul (value, &endptr, base) * scale;
! 347:
! 348: if (*endptr != '\0' || *value == '\0')
! 349: write_log ("Option `%s' requires a numeric argument.\n", option);
! 350: return 1;
! 351: }
! 352:
! 353: int cfgfile_strval (const char *option, const char *value, const char *name, int *location, const char *table[], int more)
1.1 root 354: {
355: int val;
356: if (strcmp (option, name) != 0)
357: return 0;
358: val = match_string (table, value);
359: if (val == -1) {
1.1.1.6 root 360: if (more)
361: return 0;
362:
363: write_log ("Unknown value for option `%s'.\n", option);
1.1 root 364: return 1;
365: }
366: *location = val;
367: return 1;
368: }
369:
1.1.1.18! root 370: int cfgfile_string (const char *option, const char *value, const char *name, char *location, int maxsz)
1.1 root 371: {
372: if (strcmp (option, name) != 0)
373: return 0;
374: strncpy (location, value, maxsz - 1);
375: location[maxsz - 1] = '\0';
376: return 1;
377: }
378:
379: static int getintval (char **p, int *result, int delim)
380: {
381: char *value = *p;
382: int base = 10;
383: char *endptr;
384: char *p2 = strchr (*p, delim);
385:
386: if (p2 == 0)
387: return 0;
388:
389: *p2++ = '\0';
390:
391: if (value[0] == '0' && value[1] == 'x')
392: value += 2, base = 16;
393: *result = strtol (value, &endptr, base);
394: *p = p2;
395:
396: if (*endptr != '\0' || *value == '\0')
397: return 0;
398:
399: return 1;
400: }
401:
1.1.1.8 root 402: static void set_chipset_mask (struct uae_prefs *p, int val)
1.1.1.5 root 403: {
404: p->chipset_mask = (val == 0 ? 0
405: : val == 1 ? CSMASK_ECS_AGNUS
406: : val == 2 ? CSMASK_ECS_DENISE
407: : val == 3 ? CSMASK_ECS_DENISE | CSMASK_ECS_AGNUS
408: : CSMASK_AGA | CSMASK_ECS_DENISE | CSMASK_ECS_AGNUS);
409: }
410:
1.1.1.18! root 411: static int cfgfile_parse_host (struct uae_prefs *p, char *option, char *value)
1.1 root 412: {
1.1.1.3 root 413: int tmpval;
1.1.1.9 root 414: int dummy;
1.1 root 415: char *section = 0;
416: char *tmpp;
1.1.1.3 root 417:
1.1.1.17 root 418: if (memcmp (option, "input.", 6) == 0) {
419: read_inputdevice_config (p, option, value);
420: return 1;
421: }
422:
1.1 root 423: for (tmpp = option; *tmpp != '\0'; tmpp++)
424: if (isupper (*tmpp))
425: *tmpp = tolower (*tmpp);
426: tmpp = strchr (option, '.');
427: if (tmpp) {
428: section = option;
429: option = tmpp + 1;
430: *tmpp = '\0';
431: if (strcmp (section, TARGET_NAME) == 0) {
432: /* We special case the various path options here. */
433: if (cfgfile_string (option, value, "rom_path", p->path_rom, 256)
434: || cfgfile_string (option, value, "floppy_path", p->path_floppy, 256)
435: || cfgfile_string (option, value, "hardfile_path", p->path_hardfile, 256))
436: return 1;
437: return target_parse_option (p, option, value);
438: }
439: return 0;
440: }
1.1.1.18! root 441:
1.1 root 442: if (cfgfile_yesno (option, value, "use_debugger", &p->start_debugger)
1.1.1.3 root 443: || cfgfile_yesno (option, value, "bsdsocket_emu", &p->socket_emu)
1.1.1.18! root 444:
1.1.1.17 root 445: || (cfgfile_yesno (option, value, "gfx_lores", &p->gfx_w.lores)
446: && cfgfile_yesno (option, value, "gfx_lores", &p->gfx_f.lores))
447: || cfgfile_yesno (option, value, "gfx_lores_windowed", &p->gfx_w.lores)
448: || cfgfile_yesno (option, value, "gfx_lores_fullscreen", &p->gfx_f.lores)
1.1.1.18! root 449:
1.1.1.17 root 450: || (cfgfile_yesno (option, value, "gfx_correct_aspect", &p->gfx_w.correct_aspect)
451: && cfgfile_yesno (option, value, "gfx_correct_aspect", &p->gfx_f.correct_aspect))
452: || cfgfile_yesno (option, value, "gfx_correct_aspect_windowed", &p->gfx_w.correct_aspect)
453: || cfgfile_yesno (option, value, "gfx_correct_aspect_fullscreen", &p->gfx_f.correct_aspect)
1.1.1.18! root 454:
! 455: || (cfgfile_yesno (option, value, "show_leds", &p->gfx_w.leds_on_screen)
! 456: && cfgfile_yesno (option, value, "show_leds", &p->gfx_f.leds_on_screen))
! 457: || cfgfile_yesno (option, value, "gfx_show_leds_windowed", &p->gfx_w.leds_on_screen)
! 458: || cfgfile_yesno (option, value, "gfx_show_leds_fullscreen", &p->gfx_f.leds_on_screen)
! 459:
1.1 root 460: || cfgfile_yesno (option, value, "gfx_fullscreen_amiga", &p->gfx_afullscreen)
461: || cfgfile_yesno (option, value, "gfx_fullscreen_picasso", &p->gfx_pfullscreen)
462: || cfgfile_yesno (option, value, "log_illegal_mem", &p->illegal_mem))
463: return 1;
1.1.1.18! root 464: if (cfgfile_intval (option, value, "sound_max_buff", &p->sound_maxbsiz, 1)
1.1 root 465: || cfgfile_intval (option, value, "sound_frequency", &p->sound_freq, 1)
1.1.1.18! root 466: || cfgfile_intval (option, value, "sound_stereo_separation", &p->sound_stereo_separation, 1)
! 467: || cfgfile_intval (option, value, "sound_stereo_mixing_delay", &p->sound_mixed_stereo_delay, 1)
! 468:
1.1.1.3 root 469: || cfgfile_intval (option, value, "gfx_framerate", &p->gfx_framerate, 1)
1.1.1.17 root 470: || (cfgfile_intval (option, value, "gfx_width", &p->gfx_w.width, 1)
471: && cfgfile_intval (option, value, "gfx_width", &p->gfx_f.width, 1))
472: || cfgfile_intval (option, value, "gfx_width_windowed", &p->gfx_w.width, 1)
473: || cfgfile_intval (option, value, "gfx_width_fullscreen", &p->gfx_f.width, 1)
474: || (cfgfile_intval (option, value, "gfx_height", &p->gfx_w.height, 1)
475: && cfgfile_intval (option, value, "gfx_height", &p->gfx_f.height, 1))
476: || cfgfile_intval (option, value, "gfx_height_windowed", &p->gfx_w.height, 1)
1.1.1.18! root 477: || cfgfile_intval (option, value, "gfx_height_fullscreen", &p->gfx_f.height, 1))
1.1 root 478: return 1;
479: if (cfgfile_strval (option, value, "sound_output", &p->produce_sound, soundmode, 0)
1.1.1.4 root 480: || cfgfile_strval (option, value, "sound_interpol", &p->sound_interpol, interpolmode, 0)
1.1.1.18! root 481: || cfgfile_strval (option, value, "sound_filter", &p->sound_filter, soundfiltermode1, 0)
! 482: || cfgfile_strval (option, value, "sound_filter_type", &p->sound_filter_type, soundfiltermode2, 0)
1.1.1.10 root 483: || cfgfile_strval (option, value, "use_gui", &p->start_gui, guimode1, 1)
484: || cfgfile_strval (option, value, "use_gui", &p->start_gui, guimode2, 1)
485: || cfgfile_strval (option, value, "use_gui", &p->start_gui, guimode3, 0)
1.1.1.17 root 486: || (cfgfile_strval (option, value, "gfx_linemode", &p->gfx_w.linedbl, linemode1, 1)
487: && cfgfile_strval (option, value, "gfx_linemode", &p->gfx_f.linedbl, linemode1, 1))
488: || (cfgfile_strval (option, value, "gfx_linemode", &p->gfx_w.linedbl, linemode2, 0)
489: && cfgfile_strval (option, value, "gfx_linemode", &p->gfx_f.linedbl, linemode2, 0))
490: || cfgfile_strval (option, value, "gfx_linemode_windowed", &p->gfx_w.linedbl, linemode1, 1)
491: || cfgfile_strval (option, value, "gfx_linemode_windowed", &p->gfx_w.linedbl, linemode2, 0)
492: || cfgfile_strval (option, value, "gfx_linemode_fullscreen", &p->gfx_f.linedbl, linemode1, 1)
493: || cfgfile_strval (option, value, "gfx_linemode_fullscreen", &p->gfx_f.linedbl, linemode2, 0)
494: || (cfgfile_strval (option, value, "gfx_center_horizontal", &p->gfx_w.xcenter, centermode1, 1)
495: && cfgfile_strval (option, value, "gfx_center_horizontal", &p->gfx_f.xcenter, centermode1, 1))
496: || (cfgfile_strval (option, value, "gfx_center_horizontal", &p->gfx_w.xcenter, centermode2, 0)
497: && cfgfile_strval (option, value, "gfx_center_horizontal", &p->gfx_f.xcenter, centermode2, 0))
498: || cfgfile_strval (option, value, "gfx_center_horizontal_windowed", &p->gfx_w.xcenter, centermode1, 1)
499: || cfgfile_strval (option, value, "gfx_center_horizontal_windowed", &p->gfx_w.xcenter, centermode2, 0)
500: || cfgfile_strval (option, value, "gfx_center_horizontal_fullscreen", &p->gfx_f.xcenter, centermode1, 1)
501: || cfgfile_strval (option, value, "gfx_center_horizontal_fullscreen", &p->gfx_f.xcenter, centermode2, 0)
502: || (cfgfile_strval (option, value, "gfx_center_vertical", &p->gfx_w.ycenter, centermode1, 1)
503: && cfgfile_strval (option, value, "gfx_center_vertical", &p->gfx_f.ycenter, centermode1, 1))
504: || (cfgfile_strval (option, value, "gfx_center_vertical", &p->gfx_w.ycenter, centermode2, 0)
505: && cfgfile_strval (option, value, "gfx_center_vertical", &p->gfx_f.ycenter, centermode2, 0))
506: || cfgfile_strval (option, value, "gfx_center_vertical_windowed", &p->gfx_w.ycenter, centermode1, 1)
507: || cfgfile_strval (option, value, "gfx_center_vertical_windowed", &p->gfx_w.ycenter, centermode2, 0)
508: || cfgfile_strval (option, value, "gfx_center_vertical_fullscreen", &p->gfx_f.ycenter, centermode1, 1)
509: || cfgfile_strval (option, value, "gfx_center_vertical_fullscreen", &p->gfx_f.ycenter, centermode2, 0)
1.1 root 510: || cfgfile_strval (option, value, "gfx_colour_mode", &p->color_mode, colormode1, 1)
511: || cfgfile_strval (option, value, "gfx_colour_mode", &p->color_mode, colormode2, 0)
512: || cfgfile_strval (option, value, "gfx_color_mode", &p->color_mode, colormode1, 1)
513: || cfgfile_strval (option, value, "gfx_color_mode", &p->color_mode, colormode2, 0))
514: return 1;
1.1.1.16 root 515:
516: if (strcmp (option, "joyport0") == 0 || strcmp (option, "joyport1") == 0) {
517: int port = strcmp (option, "joyport0") == 0 ? 0 : 1;
518: int start = -1;
519: char *pp = 0;
520: if (strncmp (value, "kbd", 3) == 0) {
521: start = JSEM_KBDLAYOUT;
522: pp = value + 3;
523: } else if (strncmp (value, "joy", 3) == 0) {
524: start = JSEM_JOYS;
525: pp = value + 3;
526: } else if (strncmp (value, "mouse", 5) == 0) {
527: start = JSEM_MICE;
528: pp = value + 5;
529: }
530: if (pp) {
531: int v = atol (pp);
532: if (start >= 0) {
533: if (start == JSEM_KBDLAYOUT)
534: v--;
535: if (v >= 0) {
536: start += v;
537: if (port)
538: p->jport1 = start;
539: else
540: p->jport0 = start;
541: }
542: }
543: }
544: return 1;
545: }
546:
1.1.1.18! root 547: if (cfgfile_string (option, value, "config_description", p->description, 256)
! 548: || cfgfile_string (option, value, "config_sortstr", p->sortstr, 256))
1.1 root 549: return 1;
550:
551: /* Tricky ones... */
1.1.1.18! root 552: if (cfgfile_strval (option, value, "sound_channels", &p->sound_stereo, stereomode, 1)) {
! 553: if (p->sound_stereo == SND_NONE) { /* "mixed stereo" compatibility hack */
! 554: p->sound_stereo = SND_STEREO;
! 555: p->sound_mixed_stereo_delay = 5;
! 556: p->sound_stereo_separation = 7;
1.1.1.9 root 557: }
1.1 root 558: return 1;
1.1.1.9 root 559: }
1.1 root 560:
561: if (strcmp (option, "kbd_lang") == 0) {
562: KbdLang l;
563: if ((l = KBD_LANG_DE, strcasecmp (value, "de") == 0)
1.1.1.9 root 564: || (l = KBD_LANG_DK, strcasecmp (value, "dk") == 0)
1.1 root 565: || (l = KBD_LANG_SE, strcasecmp (value, "se") == 0)
566: || (l = KBD_LANG_US, strcasecmp (value, "us") == 0)
567: || (l = KBD_LANG_FR, strcasecmp (value, "fr") == 0)
568: || (l = KBD_LANG_IT, strcasecmp (value, "it") == 0)
569: || (l = KBD_LANG_ES, strcasecmp (value, "es") == 0))
570: p->keyboard_lang = l;
571: else
572: write_log ("Unknown keyboard language\n");
573: return 1;
574: }
575:
576: if (strcmp (option, "filesystem") == 0
577: || strcmp (option, "hardfile") == 0)
578: {
1.1.1.18! root 579: int secs, heads, reserved, bs, ro, pri;
1.1.1.2 root 580: char *aname, *root;
1.1 root 581: char *tmpp = strchr (value, ',');
1.1.1.2 root 582: char *str;
1.1 root 583: if (tmpp == 0)
584: goto invalid_fs;
585:
586: *tmpp++ = '\0';
587: if (strcmp (value, "0") == 0 || strcasecmp (value, "ro") == 0
588: || strcasecmp (value, "readonly") == 0
589: || strcasecmp (value, "read-only") == 0)
1.1.1.2 root 590: ro = 1;
1.1 root 591: else if (strcmp (value, "1") == 0 || strcasecmp (value, "rw") == 0
592: || strcasecmp (value, "readwrite") == 0
593: || strcasecmp (value, "read-write") == 0)
1.1.1.2 root 594: ro = 0;
1.1 root 595: else
596: goto invalid_fs;
1.1.1.2 root 597: secs = 0; heads = 0; reserved = 0; bs = 0;
1.1 root 598:
599: value = tmpp;
600: if (strcmp (option, "filesystem") == 0) {
601: tmpp = strchr (value, ':');
602: if (tmpp == 0)
603: goto invalid_fs;
604: *tmpp++ = '\0';
1.1.1.2 root 605: aname = value;
606: root = tmpp;
1.1 root 607: } else {
1.1.1.2 root 608: if (! getintval (&value, &secs, ',')
609: || ! getintval (&value, &heads, ',')
610: || ! getintval (&value, &reserved, ',')
611: || ! getintval (&value, &bs, ','))
1.1 root 612: goto invalid_fs;
1.1.1.2 root 613: root = value;
614: aname = 0;
1.1 root 615: }
1.1.1.2 root 616: str = cfgfile_subst_path (UNEXPANDED, p->path_hardfile, root);
1.1.1.18! root 617: tmpp = add_filesys_unit (p->mountinfo, NULL, aname, str, ro, secs,
! 618: heads, reserved, bs, -1);
1.1.1.2 root 619: free (str);
620: if (tmpp)
1.1.1.18! root 621: gui_message (tmpp);
1.1 root 622: return 1;
623:
624: invalid_fs:
625: write_log ("Invalid filesystem/hardfile specification.\n");
626: return 1;
627: }
628:
629: return 0;
630: }
631:
1.1.1.18! root 632: static int cfgfile_parse_hardware (struct uae_prefs *p, char *option, char *value)
! 633: {
! 634: int tmpval, dummy, i;
! 635: unsigned int crc32;
! 636:
! 637: if (cfgfile_yesno (option, value, "immediate_blits", &p->immediate_blits)
! 638: || cfgfile_yesno (option, value, "a1000ram", &p->cs_a1000ram)
! 639: || cfgfile_yesno (option, value, "kickshifter", &p->kickshifter)
! 640: || cfgfile_yesno (option, value, "ntsc", &p->ntscmode)
! 641: || cfgfile_yesno (option, value, "cpu_24bit_addressing", &p->address_space_24)
! 642: || cfgfile_yesno (option, value, "parallel_on_demand", &p->parallel_demand)
! 643: || cfgfile_yesno (option, value, "serial_on_demand", &p->serial_demand))
! 644: return 1;
! 645:
! 646: if (cfgfile_intval (option, value, "fatgary", &p->cs_fatgaryrev, 1)
! 647: || cfgfile_intval (option, value, "ramsey", &p->cs_ramseyrev, 1)
! 648: || cfgfile_uintval (option, value, "fastmem_size", &p->fastmem_size, 0x100000)
! 649: || cfgfile_uintval (option, value, "a3000mem_size", &p->mbresmem_low_size, 0x100000)
! 650: || cfgfile_uintval (option, value, "mbresmem_size", &p->mbresmem_high_size, 0x100000)
! 651: || cfgfile_uintval (option, value, "z3mem_size", &p->z3fastmem_size, 0x100000)
! 652: || cfgfile_uintval (option, value, "bogomem_size", &p->bogomem_size, 0x40000)
! 653: || cfgfile_uintval (option, value, "gfxcard_size", &p->gfxmem_size, 0x100000)
! 654: || cfgfile_uintval (option, value, "chipmem_size", &p->chipmem_size, 0x80000)
! 655: || cfgfile_uintval (option, value, "kickstart_rom_crc", &p->rom_crc32, 1)
! 656: || cfgfile_intval (option, value, "nr_floppies", &p->nr_floppies, 1)
! 657: || cfgfile_intval (option, value, "floppy0type", &p->dfxtype[0], 1)
! 658: || cfgfile_intval (option, value, "floppy1type", &p->dfxtype[1], 1)
! 659: || cfgfile_intval (option, value, "floppy2type", &p->dfxtype[2], 1)
! 660: || cfgfile_intval (option, value, "floppy3type", &p->dfxtype[3], 1))
! 661: return 1;
! 662:
! 663: /* Default configurations want to allow multiple possible ROMs. For these,
! 664: * we have the following option, which validates the CRC32 against the list
! 665: * of available ROMs.
! 666: * Config files should sort these entries so that the most desired ROM appears
! 667: * last. */
! 668: if (cfgfile_uintval (option, value, "kickstart_rom_crc_attempt", &crc32, 1)) {
! 669: for (i = 0;; i++) {
! 670: struct romlist *rl = romlist_from_idx (i, ROMTYPE_KICK, 1);
! 671: if (!rl)
! 672: break;
! 673: if (rl->rd->crc32 == crc32) {
! 674: p->rom_crc32 = crc32;
! 675: break;
! 676: }
! 677: }
! 678: return 1;
! 679: }
! 680:
! 681: if (cfgfile_strval (option, value, "ide", &p->cs_ide, idemode, 0)
! 682: || cfgfile_strval (option, value, "collision_level", &p->collision_level, collmode, 0))
! 683: return 1;
! 684:
! 685: if (cfgfile_string (option, value, "floppy0", p->df[0], 256)
! 686: || cfgfile_string (option, value, "floppy1", p->df[1], 256)
! 687: || cfgfile_string (option, value, "floppy2", p->df[2], 256)
! 688: || cfgfile_string (option, value, "floppy3", p->df[3], 256)
! 689: || cfgfile_string (option, value, "kickstart_rom_file", p->romfile, 256)
! 690: || cfgfile_string (option, value, "kickstart_ext_rom_file", p->romextfile, 256)
! 691: || cfgfile_string (option, value, "kickstart_key_file", p->keyfile, 256))
! 692: return 1;
! 693:
! 694: if (cfgfile_strval (option, value, "chipset", &tmpval, csmode, 0)) {
! 695: set_chipset_mask (p, tmpval);
! 696: return 1;
! 697: }
! 698:
! 699: if (cfgfile_strval (option, value, "cpu_type", &tmpval, cpumode, 0)) {
! 700: p->fpu_model = 0;
! 701: p->address_space_24 = 0;
! 702: p->cpu_model = 68000;
! 703: switch (tmpval) {
! 704: case 0:
! 705: p->cpu_model = 68000;
! 706: break;
! 707: case 1:
! 708: p->cpu_model = 68010;
! 709: break;
! 710: case 2: case 3: case 4:
! 711: case 5: case 6: case 7:
! 712: p->cpu_model = 68020;
! 713: p->address_space_24 = tmpval < 5;
! 714: p->fpu_model = (tmpval == 3 || tmpval == 6 ? 68881
! 715: : tmpval == 4 || tmpval == 7 ? 68882
! 716: : 0);
! 717: break;
! 718: case 8: case 9: case 10:
! 719: p->cpu_model = 68030;
! 720: p->fpu_model = (tmpval == 9 ? 68881 : tmpval == 10 ? 68882 : 0);
! 721: break;
! 722: case 11:
! 723: p->cpu_model = 68040;
! 724: p->fpu_model = 68040;
! 725: break;
! 726: case 12:
! 727: p->cpu_model = 68060;
! 728: p->fpu_model = 68060;
! 729: break;
! 730: }
! 731: return 1;
! 732: }
! 733:
! 734: if (cfgfile_strval (option, value, "cpu_speed", &p->m68k_speed, speedmode, 1)
! 735: /* Broken earlier versions used to write this out as a string. */
! 736: || cfgfile_strval (option, value, "finegraincpu_speed", &p->m68k_speed, speedmode, 1))
! 737: {
! 738: p->m68k_speed--;
! 739: return 1;
! 740: }
! 741:
! 742: if (cfgfile_intval (option, value, "cpu_speed", &p->m68k_speed, 1)) {
! 743: p->m68k_speed *= CYCLE_UNIT;
! 744: return 1;
! 745: }
! 746:
! 747: if (cfgfile_intval (option, value, "finegrain_cpu_speed", &p->m68k_speed, 1)) {
! 748: if (OFFICIAL_CYCLE_UNIT > CYCLE_UNIT) {
! 749: int factor = OFFICIAL_CYCLE_UNIT / CYCLE_UNIT;
! 750: p->m68k_speed = (p->m68k_speed + factor - 1) / factor;
! 751: }
! 752: return 1;
! 753: }
! 754:
! 755: return 0;
! 756: }
! 757:
! 758: int cfgfile_parse_option (struct uae_prefs *p, char *option, char *value)
! 759: {
! 760: if (cfgfile_parse_hardware (p, option, value))
! 761: return 1;
! 762: if (cfgfile_parse_host (p, option, value))
! 763: return 1;
! 764:
! 765: return 0;
! 766: }
! 767:
1.1.1.2 root 768: void cfgfile_parse_line (struct uae_prefs *p, char *line)
1.1 root 769: {
770: int i;
771: char *orig_line = my_strdup (line);
772: char *line1, *line2;
773:
774: line1 = line;
775: line2 = strchr (line, '=');
776: if (! line2) {
777: write_log ("CFGFILE: line was incomplete with only %s\n", line1);
778: return;
779: }
780:
781: *line2++ = '\0';
782:
783: /* Get rid of whitespace. */
1.1.1.2 root 784: i = strlen (line2);
785: while (i > 0 && (line2[i - 1] == '\t' || line2[i - 1] == ' '
786: || line2[i - 1] == '\r' || line2[i - 1] == '\n'))
787: line2[--i] = '\0';
1.1 root 788: line2 += strspn (line2, "\t \r\n");
1.1.1.2 root 789: i = strlen (line);
790: while (i > 0 && (line[i - 1] == '\t' || line[i - 1] == ' '
791: || line[i - 1] == '\r' || line[i - 1] == '\n'))
792: line[--i] = '\0';
1.1 root 793: line += strspn (line, "\t \r\n");
794:
1.1.1.2 root 795: if (! cfgfile_parse_option (p, line, line2)) {
1.1 root 796: struct strlist *u = xmalloc (sizeof (struct strlist));
797: u->str = orig_line;
798: u->next = p->unknown_lines;
799: p->unknown_lines = u;
800: } else
801: free (orig_line);
802: }
803:
804: static void subst (char *p, char *f, int n)
805: {
806: char *str = cfgfile_subst_path (UNEXPANDED, p, f);
807: strncpy (f, str, n - 1);
808: f[n - 1] = '\0';
809: free (str);
810: }
811:
812: int cfgfile_load (struct uae_prefs *p, const char *filename)
813: {
814: int i;
815:
816: FILE *fh;
817: char line[256];
818:
1.1.1.4 root 819: fh = fopen (filename, "r");
1.1 root 820: if (! fh)
821: return 0;
822:
823: while (fgets (line, 256, fh) != 0) {
1.1.1.13 root 824: int len = strlen (line);
825: /* Delete trailing whitespace. */
1.1.1.18! root 826: while (len > 0 && strcspn (line + len - 1, "\t \r\n") == 0)
1.1.1.13 root 827: line[--len] = '\0';
1.1.1.18! root 828: if (strlen (line) > 0) {
! 829: if (line[0] == '#' || line[0] == ';')
! 830: continue;
1.1.1.2 root 831: cfgfile_parse_line (p, line);
1.1.1.18! root 832: }
1.1 root 833: }
834: fclose (fh);
835:
836: for (i = 0; i < 4; i++)
837: subst (p->path_floppy, p->df[i], sizeof p->df[i]);
838: subst (p->path_rom, p->romfile, sizeof p->romfile);
1.1.1.12 root 839: subst (p->path_rom, p->romextfile, sizeof p->romextfile);
1.1 root 840: subst (p->path_rom, p->keyfile, sizeof p->keyfile);
841:
842: return 1;
843: }
844:
845: int cfgfile_save (struct uae_prefs *p, const char *filename)
846: {
847: FILE *fh = fopen (filename, "w");
848: if (! fh)
849: return 0;
850:
851: save_options (fh, p);
852: fclose (fh);
853: return 1;
854: }
855:
856: int cfgfile_get_description (const char *filename, char *description)
857: {
858: int result = 0;
859: struct uae_prefs p;
860: default_prefs (&p);
861: strcpy (p.description, "");
1.1.1.12 root 862: if (cfgfile_load (&p, filename)) {
1.1 root 863: result = 1;
864: strcpy (description, p.description);
865: }
866: discard_prefs (&p);
867: return result;
868: }
869:
870: void cfgfile_show_usage (void)
871: {
872: int i;
873: fprintf (stderr, "UAE Configuration Help:\n" \
874: "=======================\n");
875: for (i = 0; i < sizeof opttable / sizeof *opttable; i++)
876: fprintf (stderr, "%s: %s\n", opttable[i].config_label, opttable[i].config_help);
877: }
1.1.1.4 root 878:
879: /* This implements the old commandline option parsing. I've re-added this
880: because the new way of doing things is painful for me (it requires me
881: to type a couple hundred characters when invoking UAE). The following
882: is far less annoying to use. */
1.1.1.16 root 883: static void parse_gfx_specs (struct uae_prefs *p, char *spec)
1.1.1.4 root 884: {
885: char *x0 = my_strdup (spec);
886: char *x1, *x2;
887:
888: x1 = strchr (x0, ':');
889: if (x1 == 0)
890: goto argh;
891: x2 = strchr (x1+1, ':');
892: if (x2 == 0)
893: goto argh;
894: *x1++ = 0; *x2++ = 0;
895:
1.1.1.17 root 896: p->gfx_w.width = atoi (x0);
897: p->gfx_w.height = atoi (x1);
898: p->gfx_w.lores = strchr (x2, 'l') != 0;
899: p->gfx_w.xcenter = strchr (x2, 'x') != 0 ? 1 : strchr (x2, 'X') != 0 ? 2 : 0;
900: p->gfx_w.ycenter = strchr (x2, 'y') != 0 ? 1 : strchr (x2, 'Y') != 0 ? 2 : 0;
901: p->gfx_w.linedbl = strchr (x2, 'd') != 0;
902: p->gfx_w.linedbl += 2 * (strchr (x2, 'D') != 0);
903: p->gfx_w.correct_aspect = strchr (x2, 'c') != 0;
904:
905: p->gfx_f = p->gfx_w;
906:
1.1.1.16 root 907: p->gfx_afullscreen = strchr (x2, 'a') != 0;
908: p->gfx_pfullscreen = strchr (x2, 'p') != 0;
1.1.1.4 root 909:
1.1.1.17 root 910: if (p->gfx_w.linedbl == 3) {
1.1.1.4 root 911: fprintf (stderr, "You can't use both 'd' and 'D' modifiers in the display mode specification.\n");
912: }
1.1.1.16 root 913:
1.1.1.4 root 914: free (x0);
915: return;
916:
917: argh:
918: fprintf (stderr, "Bad display mode specification.\n");
919: fprintf (stderr, "The format to use is: \"width:height:modifiers\"\n");
920: fprintf (stderr, "Type \"uae -h\" for detailed help.\n");
921: free (x0);
922: }
923:
1.1.1.16 root 924: static void parse_sound_spec (struct uae_prefs *p, char *spec)
1.1.1.4 root 925: {
926: char *x0 = my_strdup (spec);
1.1.1.18! root 927: char *x1, *x2 = NULL, *x3 = NULL, *x4 = NULL;
1.1.1.4 root 928:
929: x1 = strchr (x0, ':');
930: if (x1 != NULL) {
931: *x1++ = '\0';
932: x2 = strchr (x1 + 1, ':');
933: if (x2 != NULL) {
934: *x2++ = '\0';
935: x3 = strchr (x2 + 1, ':');
936: if (x3 != NULL) {
937: *x3++ = '\0';
938: x4 = strchr (x3 + 1, ':');
939: }
940: }
941: }
1.1.1.16 root 942: p->produce_sound = atoi (x0);
1.1.1.4 root 943: if (x1) {
1.1.1.18! root 944: p->sound_mixed_stereo_delay = 0;
! 945: if (*x1 == 'S') {
! 946: p->sound_stereo = SND_STEREO;
! 947: p->sound_stereo_separation = 7;
! 948: } else if (*x1 == 's')
! 949: p->sound_stereo = SND_STEREO;
1.1.1.4 root 950: else
1.1.1.18! root 951: p->sound_stereo = SND_MONO;
1.1.1.4 root 952: }
1.1.1.18! root 953: /* x2 used to be bits, now fixed at 16 bit. */
1.1.1.4 root 954: if (x3)
1.1.1.16 root 955: p->sound_freq = atoi (x3);
1.1.1.4 root 956: if (x4)
1.1.1.18! root 957: p->sound_maxbsiz = atoi (x4);
1.1.1.4 root 958: free (x0);
959: }
960:
961:
1.1.1.16 root 962: static void parse_joy_spec (struct uae_prefs *p, char *spec)
1.1.1.4 root 963: {
964: int v0 = 2, v1 = 0;
965: if (strlen(spec) != 2)
966: goto bad;
967:
968: switch (spec[0]) {
1.1.1.16 root 969: case '0': v0 = JSEM_JOYS; break;
970: case '1': v0 = JSEM_JOYS + 1; break;
971: case 'M': case 'm': v0 = JSEM_MICE; break;
972: case 'A': case 'a': v0 = JSEM_KBDLAYOUT; break;
973: case 'B': case 'b': v0 = JSEM_KBDLAYOUT + 1; break;
974: case 'C': case 'c': v0 = JSEM_KBDLAYOUT + 2; break;
1.1.1.4 root 975: default: goto bad;
976: }
977:
978: switch (spec[1]) {
1.1.1.16 root 979: case '0': v1 = JSEM_JOYS; break;
980: case '1': v1 = JSEM_JOYS + 1; break;
981: case 'M': case 'm': v1 = JSEM_MICE; break;
982: case 'A': case 'a': v1 = JSEM_KBDLAYOUT; break;
983: case 'B': case 'b': v1 = JSEM_KBDLAYOUT + 1; break;
984: case 'C': case 'c': v1 = JSEM_KBDLAYOUT + 2; break;
1.1.1.4 root 985: default: goto bad;
986: }
987: if (v0 == v1)
988: goto bad;
989: /* Let's scare Pascal programmers */
990: if (0)
991: bad:
1.1.1.16 root 992: write_log ("Bad joystick mode specification. Use -J xy, where x and y\n"
1.1.1.4 root 993: "can be 0 for joystick 0, 1 for joystick 1, M for mouse, and\n"
994: "a, b or c for different keyboard settings.\n");
995:
1.1.1.16 root 996: p->jport0 = v0;
997: p->jport1 = v1;
1.1.1.4 root 998: }
999:
1.1.1.18! root 1000: static void parse_filesys_spec (struct uae_prefs *p, int readonly, char *spec)
1.1.1.4 root 1001: {
1002: char buf[256];
1003: char *s2;
1004:
1005: strncpy (buf, spec, 255); buf[255] = 0;
1006: s2 = strchr (buf, ':');
1007: if (s2) {
1008: *s2++ = '\0';
1009: #ifdef __DOS__
1010: {
1011: char *tmp;
1.1.1.16 root 1012:
1.1.1.4 root 1013: while ((tmp = strchr (s2, '\\')))
1014: *tmp = '/';
1015: }
1016: #endif
1.1.1.18! root 1017: s2 = add_filesys_unit (p->mountinfo, NULL, buf, s2, readonly, 0, 0, 0, 0, -1);
1.1.1.4 root 1018: if (s2)
1019: fprintf (stderr, "%s\n", s2);
1020: } else {
1021: fprintf (stderr, "Usage: [-m | -M] VOLNAME:mount_point\n");
1022: }
1023: }
1.1.1.16 root 1024:
1.1.1.18! root 1025: static void parse_hardfile_spec (struct uae_prefs *p, char *spec)
1.1.1.4 root 1026: {
1027: char *x0 = my_strdup (spec);
1028: char *x1, *x2, *x3, *x4;
1029:
1030: x1 = strchr (x0, ':');
1031: if (x1 == NULL)
1032: goto argh;
1033: *x1++ = '\0';
1034: x2 = strchr (x1 + 1, ':');
1035: if (x2 == NULL)
1036: goto argh;
1037: *x2++ = '\0';
1038: x3 = strchr (x2 + 1, ':');
1039: if (x3 == NULL)
1040: goto argh;
1041: *x3++ = '\0';
1042: x4 = strchr (x3 + 1, ':');
1043: if (x4 == NULL)
1044: goto argh;
1045: *x4++ = '\0';
1.1.1.18! root 1046: x4 = add_filesys_unit (p->mountinfo, NULL, 0, x4, 0, atoi (x0), atoi (x1), atoi (x2), atoi (x3), -1);
1.1.1.4 root 1047: if (x4)
1048: fprintf (stderr, "%s\n", x4);
1049:
1050: free (x0);
1051: return;
1052:
1053: argh:
1054: free (x0);
1055: fprintf (stderr, "Bad hardfile parameter specified - type \"uae -h\" for help.\n");
1056: return;
1057: }
1058:
1.1.1.18! root 1059: static void parse_cpu_specs (struct uae_prefs *p, char *spec)
1.1.1.4 root 1060: {
1.1.1.18! root 1061: int lvl;
1.1.1.7 root 1062: if (*spec < '0' || *spec > '4') {
1063: fprintf (stderr, "CPU parameter string must begin with '0', '1', '2', '3' or '4'.\n");
1.1.1.4 root 1064: return;
1065: }
1.1.1.16 root 1066:
1.1.1.18! root 1067: lvl = *spec++ - '0';
! 1068: p->fpu_model = 0;
! 1069: p->cpu_model = lvl * 10 + 68000;
! 1070: if (p->cpu_model >= 68040)
! 1071: p->fpu_model = p->cpu_model;
! 1072: p->address_space_24 = p->cpu_model < 68020;
1.1.1.4 root 1073: while (*spec != '\0') {
1074: switch (*spec) {
1.1.1.18! root 1075: case 'a':
! 1076: if (p->cpu_model < 68020)
1.1.1.4 root 1077: fprintf (stderr, "In 68000/68010 emulation, the address space is always 24 bit.\n");
1.1.1.18! root 1078: else if (p->cpu_model >= 68040)
1.1.1.7 root 1079: fprintf (stderr, "In 68040 emulation, the address space is always 32 bit.\n");
1.1.1.4 root 1080: else
1.1.1.18! root 1081: p->address_space_24 = 1;
1.1.1.4 root 1082: break;
1.1.1.18! root 1083: case 'c':
! 1084: fprintf (stderr, "Obsolete CPU type modifier 'c'.\n");
1.1.1.4 root 1085: break;
1.1.1.18! root 1086: default:
1.1.1.4 root 1087: fprintf (stderr, "Bad CPU parameter specified - type \"uae -h\" for help.\n");
1088: break;
1089: }
1090: spec++;
1091: }
1092: }
1093:
1094: /* Returns the number of args used up (0 or 1). */
1.1.1.18! root 1095: int parse_cmdline_option (struct uae_prefs *p, char c, char *arg)
1.1.1.4 root 1096: {
1.1.1.5 root 1097: const char arg_required[] = "0123rKpImWSAJwNCZUFcblOdHRv";
1.1.1.4 root 1098:
1099: if (strchr (arg_required, c) && ! arg) {
1100: fprintf (stderr, "Missing argument for option `-%c'!\n", c);
1101: return 0;
1102: }
1103:
1104: switch (c) {
1.1.1.5 root 1105: case 'h': usage (); exit (0);
1.1.1.4 root 1106:
1.1.1.18! root 1107: case '0': strncpy (p->df[0], arg, 255); p->df[0][255] = 0; break;
! 1108: case '1': strncpy (p->df[1], arg, 255); p->df[1][255] = 0; break;
! 1109: case '2': strncpy (p->df[2], arg, 255); p->df[2][255] = 0; break;
! 1110: case '3': strncpy (p->df[3], arg, 255); p->df[3][255] = 0; break;
! 1111: case 'r': strncpy (p->romfile, arg, 255); p->romfile[255] = 0; break;
! 1112: case 'K': strncpy (p->keyfile, arg, 255); p->keyfile[255] = 0; break;
! 1113: case 'p': strncpy (p->prtname, arg, 255); p->prtname[255] = 0; break;
! 1114: /* case 'I': strncpy (p->sername, arg, 255); p->sername[255] = 0; p->use_serial = 1; break; */
! 1115: case 'm': case 'M': parse_filesys_spec (p, c == 'M', arg); break;
! 1116: case 'W': parse_hardfile_spec (p, arg); break;
! 1117: case 'S': parse_sound_spec (p, arg); break;
! 1118: case 'R': p->gfx_framerate = atoi (arg); break;
! 1119: case 'i': p->illegal_mem = 1; break;
! 1120: case 'J': parse_joy_spec (p, arg); break;
! 1121:
! 1122: case 't': p->test_drawing_speed = 1; break;
! 1123: case 'L': p->x11_use_low_bandwidth = 1; break;
! 1124: case 'T': p->x11_use_mitshm = 1; break;
! 1125: case 'w': p->m68k_speed = atoi (arg); break;
! 1126:
! 1127: case 'G': p->start_gui = 0; break;
! 1128: case 'D': p->start_debugger = 1; break;
1.1.1.4 root 1129:
1.1.1.5 root 1130: case 'n':
1.1.1.4 root 1131: if (strchr (arg, '3') != 0)
1.1.1.18! root 1132: p->blits_32bit_enabled = 1;
1.1.1.4 root 1133: if (strchr (arg, 'i') != 0)
1.1.1.18! root 1134: p->immediate_blits = 1;
1.1.1.4 root 1135: break;
1136:
1.1.1.5 root 1137: case 'v':
1.1.1.18! root 1138: set_chipset_mask (p, atoi (arg));
1.1.1.5 root 1139: break;
1140:
1141: case 'C':
1.1.1.18! root 1142: parse_cpu_specs (p, arg);
1.1.1.4 root 1143: break;
1144:
1.1.1.5 root 1145: case 'Z':
1.1.1.18! root 1146: p->z3fastmem_size = atoi (arg) * 0x100000;
1.1.1.4 root 1147: break;
1148:
1.1.1.5 root 1149: case 'U':
1.1.1.18! root 1150: p->gfxmem_size = atoi (arg) * 0x100000;
1.1.1.4 root 1151: break;
1152:
1.1.1.5 root 1153: case 'F':
1.1.1.18! root 1154: p->fastmem_size = atoi (arg) * 0x100000;
1.1.1.4 root 1155: break;
1156:
1.1.1.5 root 1157: case 'b':
1.1.1.18! root 1158: p->bogomem_size = atoi (arg) * 0x40000;
1.1.1.4 root 1159: break;
1160:
1.1.1.5 root 1161: case 'c':
1.1.1.18! root 1162: p->chipmem_size = atoi (arg) * 0x80000;
1.1.1.4 root 1163: break;
1164:
1.1.1.5 root 1165: case 'l':
1.1.1.18! root 1166: if (0 == strcasecmp (arg, "de"))
! 1167: p->keyboard_lang = KBD_LANG_DE;
! 1168: else if (0 == strcasecmp (arg, "dk"))
! 1169: p->keyboard_lang = KBD_LANG_DK;
! 1170: else if (0 == strcasecmp (arg, "us"))
! 1171: p->keyboard_lang = KBD_LANG_US;
! 1172: else if (0 == strcasecmp (arg, "se"))
! 1173: p->keyboard_lang = KBD_LANG_SE;
! 1174: else if (0 == strcasecmp (arg, "fr"))
! 1175: p->keyboard_lang = KBD_LANG_FR;
! 1176: else if (0 == strcasecmp (arg, "it"))
! 1177: p->keyboard_lang = KBD_LANG_IT;
! 1178: else if (0 == strcasecmp (arg, "es"))
! 1179: p->keyboard_lang = KBD_LANG_ES;
1.1.1.4 root 1180: break;
1181:
1.1.1.18! root 1182: case 'O': parse_gfx_specs (p, arg); break;
1.1.1.5 root 1183: case 'd':
1.1.1.4 root 1184: if (strchr (arg, 'S') != NULL || strchr (arg, 's')) {
1185: write_log (" Serial on demand.\n");
1.1.1.18! root 1186: p->serial_demand = 1;
1.1.1.4 root 1187: }
1188: if (strchr (arg, 'P') != NULL || strchr (arg, 'p')) {
1189: write_log (" Parallel on demand.\n");
1.1.1.18! root 1190: p->parallel_demand = 1;
1.1.1.4 root 1191: }
1192:
1193: break;
1194:
1.1.1.5 root 1195: case 'H':
1.1.1.18! root 1196: p->color_mode = atoi (arg);
! 1197: if (p->color_mode < 0) {
1.1.1.4 root 1198: fprintf (stderr, "Bad color mode selected. Using default.\n");
1.1.1.18! root 1199: p->color_mode = 0;
1.1.1.4 root 1200: }
1201: break;
1.1.1.5 root 1202: default:
1.1.1.4 root 1203: fprintf (stderr, "Unknown option `-%c'!\n", c);
1204: break;
1205: }
1206: return !! strchr (arg_required, c);
1207: }
1.1.1.18! root 1208:
! 1209: int cstype_from_prefs (struct uae_prefs *p)
! 1210: {
! 1211: if ((p->chipset_mask & CSMASK_AGA) == 0) {
! 1212: if (p->cs_ramseyrev == -1 && p->cs_fatgaryrev == -1) {
! 1213: if (p->cs_ide == 0) {
! 1214: if (p->cs_a1000ram && p->chipset_mask == CSMASK_OCS)
! 1215: return CP_A1000;
! 1216: if (p->chipset_mask == CSMASK_FULL_ECS)
! 1217: return CP_A500P;
! 1218: return CP_A500;
! 1219: }
! 1220: if (p->chipset_mask == CSMASK_FULL_ECS)
! 1221: return CP_A600;
! 1222: return CP_GENERIC;
! 1223: }
! 1224: if (p->cs_ide == 0 && p->cs_fatgaryrev == 0 && p->cs_ramseyrev == 0xd)
! 1225: return CP_A3000;
! 1226: return CP_GENERIC;
! 1227: }
! 1228: if (p->cs_ide == 1 && p->cs_ramseyrev == -1 && p->cs_fatgaryrev == -1)
! 1229: return CP_A1200;
! 1230: if (p->cs_ide == 2 && p->cs_ramseyrev == 0xf && p->cs_fatgaryrev == 0)
! 1231: return CP_A4000;
! 1232: return CP_GENERIC;
! 1233: }
! 1234:
! 1235: void built_in_chipset_prefs (struct uae_prefs *p, int cstype)
! 1236: {
! 1237: p->cs_a1000ram = 0;
! 1238: p->cs_fatgaryrev = -1;
! 1239: p->cs_ide = 0;
! 1240: p->cs_ramseyrev = -1;
! 1241:
! 1242: switch (cstype)
! 1243: {
! 1244: case CP_GENERIC: // generic
! 1245: p->cs_fatgaryrev = 0;
! 1246: p->cs_ide = -1;
! 1247: p->cs_ramseyrev = 0x0f;
! 1248: break;
! 1249: case CP_CDTV: // CDTV
! 1250: break;
! 1251: case CP_CD32: // CD32
! 1252: break;
! 1253: case CP_A500: // A500
! 1254: if (p->chipset_mask & CSMASK_AGA)
! 1255: p->chipset_mask = CSMASK_ECS_AGNUS;
! 1256: break;
! 1257: case CP_A500P: // A500+
! 1258: p->chipset_mask = CSMASK_FULL_ECS;
! 1259: break;
! 1260: case CP_A600: // A600
! 1261: p->cs_ide = 1;
! 1262: p->chipset_mask = CSMASK_FULL_ECS;
! 1263: break;
! 1264: case CP_A1000: // A1000
! 1265: p->cs_a1000ram = 1;
! 1266: p->chipset_mask = CSMASK_OCS;
! 1267: break;
! 1268: case CP_A1200: // A1200
! 1269: p->cs_ide = 1;
! 1270: p->chipset_mask = CSMASK_AGA;
! 1271: break;
! 1272: case CP_A2000: // A2000
! 1273: if (p->chipset_mask & CSMASK_AGA)
! 1274: p->chipset_mask = CSMASK_ECS_AGNUS;
! 1275: p->cs_rtc = 1;
! 1276: break;
! 1277: case CP_A3000: // A3000
! 1278: p->cs_rtc = 2;
! 1279: p->cs_fatgaryrev = 0;
! 1280: p->cs_ramseyrev = 0x0d;
! 1281: p->chipset_mask = CSMASK_FULL_ECS;
! 1282: break;
! 1283: case CP_A3000T: // A3000T
! 1284: p->cs_rtc = 2;
! 1285: p->cs_fatgaryrev = 0;
! 1286: p->cs_ramseyrev = 0x0d;
! 1287: p->chipset_mask = CSMASK_FULL_ECS;
! 1288: break;
! 1289: case CP_A4000: // A4000
! 1290: p->cs_rtc = 2;
! 1291: p->cs_fatgaryrev = 0;
! 1292: p->cs_ramseyrev = 0x0f;
! 1293: p->cs_ide = 2;
! 1294: p->chipset_mask = CSMASK_AGA;
! 1295: break;
! 1296: case CP_A4000T: // A4000T
! 1297: p->cs_rtc = 2;
! 1298: p->cs_fatgaryrev = 0;
! 1299: p->cs_ramseyrev = 0x0f;
! 1300: p->cs_ide = 2;
! 1301: p->chipset_mask = CSMASK_AGA;
! 1302: break;
! 1303: }
! 1304: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.