/cfgfile.cpp
C++ | 9417 lines | 8976 code | 382 blank | 59 comment | 2086 complexity | 1b238f847b3d1b80686f2250433573d4 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- /*
- * UAE - The Un*x Amiga Emulator
- *
- * Config file handling
- * This still needs some thought before it's complete...
- *
- * Copyright 1998 Brian King, Bernd Schmidt
- */
- #include "sysconfig.h"
- #include "sysdeps.h"
- #include <ctype.h>
- #include "options.h"
- #include "uae.h"
- #include "audio.h"
- #include "events.h"
- #include "custom.h"
- #include "inputdevice.h"
- #include "gfxfilter.h"
- #include "savestate.h"
- #include "memory.h"
- #include "autoconf.h"
- #include "rommgr.h"
- #include "gui.h"
- #include "newcpu.h"
- #include "zfile.h"
- #include "filesys.h"
- #include "fsdb.h"
- #include "disk.h"
- #include "blkdev.h"
- #include "statusline.h"
- #include "debug.h"
- #include "calc.h"
- #include "gfxboard.h"
- #include "cpuboard.h"
- #include "luascript.h"
- #include "ethernet.h"
- #include "native2amiga_api.h"
- #include "ini.h"
- #include "specialmonitors.h"
- #define cfgfile_warning write_log
- #define cfgfile_warning_obsolete write_log
- #if SIZEOF_TCHAR != 1
- /* FIXME: replace strcasecmp with _tcsicmp in source code instead */
- #undef strcasecmp
- #define strcasecmp _tcsicmp
- #endif
- static int config_newfilesystem;
- static struct strlist *temp_lines;
- static struct strlist *error_lines;
- static struct zfile *default_file, *configstore;
- static int uaeconfig;
- static int unicode_config = 0;
- /* @@@ need to get rid of this... just cut part of the manual and print that
- * as a help text. */
- struct cfg_lines
- {
- const TCHAR *config_label, *config_help;
- };
- static const struct cfg_lines opttable[] =
- {
- {_T("help"), _T("Prints this help") },
- {_T("config_description"), _T("") },
- {_T("config_info"), _T("") },
- {_T("use_gui"), _T("Enable the GUI? If no, then goes straight to emulator") },
- {_T("use_debugger"), _T("Enable the debugger?") },
- {_T("cpu_speed"), _T("can be max, real, or a number between 1 and 20") },
- {_T("cpu_model"), _T("Can be 68000, 68010, 68020, 68030, 68040, 68060") },
- {_T("fpu_model"), _T("Can be 68881, 68882, 68040, 68060") },
- {_T("cpu_compatible"), _T("yes enables compatibility-mode") },
- {_T("cpu_24bit_addressing"), _T("must be set to 'no' in order for Z3mem or P96mem to work") },
- {_T("autoconfig"), _T("yes = add filesystems and extra ram") },
- {_T("log_illegal_mem"), _T("print illegal memory access by Amiga software?") },
- {_T("fastmem_size"), _T("Size in megabytes of fast-memory") },
- {_T("chipmem_size"), _T("Size in megabytes of chip-memory") },
- {_T("bogomem_size"), _T("Size in megabytes of bogo-memory at 0xC00000") },
- {_T("a3000mem_size"), _T("Size in megabytes of A3000 memory") },
- {_T("gfxcard_size"), _T("Size in megabytes of Picasso96 graphics-card memory") },
- {_T("z3mem_size"), _T("Size in megabytes of Zorro-III expansion memory") },
- {_T("gfx_test_speed"), _T("Test graphics speed?") },
- {_T("gfx_framerate"), _T("Print every nth frame") },
- {_T("gfx_width"), _T("Screen width") },
- {_T("gfx_height"), _T("Screen height") },
- {_T("gfx_refreshrate"), _T("Fullscreen refresh rate") },
- {_T("gfx_vsync"), _T("Sync screen refresh to refresh rate") },
- {_T("gfx_lores"), _T("Treat display as lo-res?") },
- {_T("gfx_linemode"), _T("Can be none, double, or scanlines") },
- {_T("gfx_fullscreen_amiga"), _T("Amiga screens are fullscreen?") },
- {_T("gfx_fullscreen_picasso"), _T("Picasso screens are fullscreen?") },
- {_T("gfx_center_horizontal"), _T("Center display horizontally?") },
- {_T("gfx_center_vertical"), _T("Center display vertically?") },
- {_T("gfx_colour_mode"), _T("") },
- {_T("32bit_blits"), _T("Enable 32 bit blitter emulation") },
- {_T("immediate_blits"), _T("Perform blits immediately") },
- {_T("show_leds"), _T("LED display") },
- {_T("keyboard_leds"), _T("Keyboard LEDs") },
- {_T("gfxlib_replacement"), _T("Use graphics.library replacement?") },
- {_T("sound_output"), _T("") },
- {_T("sound_frequency"), _T("") },
- {_T("sound_bits"), _T("") },
- {_T("sound_channels"), _T("") },
- {_T("sound_max_buff"), _T("") },
- {_T("comp_trustbyte"), _T("How to access bytes in compiler (direct/indirect/indirectKS/afterPic") },
- {_T("comp_trustword"), _T("How to access words in compiler (direct/indirect/indirectKS/afterPic") },
- {_T("comp_trustlong"), _T("How to access longs in compiler (direct/indirect/indirectKS/afterPic") },
- {_T("comp_nf"), _T("Whether to optimize away flag generation where possible") },
- {_T("comp_fpu"), _T("Whether to provide JIT FPU emulation") },
- {_T("cachesize"), _T("How many MB to use to buffer translated instructions")},
- {_T("override_dga_address"),_T("Address from which to map the frame buffer (upper 16 bits) (DANGEROUS!)")},
- {_T("avoid_dga"), _T("Set to yes if the use of DGA extension creates problems") },
- {_T("avoid_vid"), _T("Set to yes if the use of the Vidmode extension creates problems") },
- {_T("parallel_on_demand"), _T("") },
- {_T("serial_on_demand"), _T("") },
- {_T("scsi"), _T("scsi.device emulation") },
- {_T("joyport0"), _T("") },
- {_T("joyport1"), _T("") },
- {_T("pci_devices"), _T("List of PCI devices to make visible to the emulated Amiga") },
- {_T("kickstart_rom_file"), _T("Kickstart ROM image, (C) Copyright Amiga, Inc.") },
- {_T("kickstart_ext_rom_file"), _T("Extended Kickstart ROM image, (C) Copyright Amiga, Inc.") },
- {_T("kickstart_key_file"), _T("Key-file for encrypted ROM images (from Cloanto's Amiga Forever)") },
- {_T("flash_ram_file"), _T("Flash/battery backed RAM image file.") },
- {_T("cart_file"), _T("Freezer cartridge ROM image file.") },
- {_T("floppy0"), _T("Diskfile for drive 0") },
- {_T("floppy1"), _T("Diskfile for drive 1") },
- {_T("floppy2"), _T("Diskfile for drive 2") },
- {_T("floppy3"), _T("Diskfile for drive 3") },
- {_T("hardfile"), _T("access,sectors, surfaces, reserved, blocksize, path format") },
- {_T("filesystem"), _T("access,'Amiga volume-name':'host directory path' - where 'access' can be 'read-only' or 'read-write'") },
- {_T("catweasel"), _T("Catweasel board io base address") }
- };
- static const TCHAR *guimode1[] = { _T("no"), _T("yes"), _T("nowait"), 0 };
- static const TCHAR *guimode2[] = { _T("false"), _T("true"), _T("nowait"), 0 };
- static const TCHAR *guimode3[] = { _T("0"), _T("1"), _T("nowait"), 0 };
- static const TCHAR *csmode[] = { _T("ocs"), _T("ecs_agnus"), _T("ecs_denise"), _T("ecs"), _T("aga"), 0 };
- static const TCHAR *linemode[] = {
- _T("none"),
- _T("double"), _T("scanlines"), _T("scanlines2p"), _T("scanlines3p"),
- _T("double2"), _T("scanlines2"), _T("scanlines2p2"), _T("scanlines2p3"),
- _T("double3"), _T("scanlines3"), _T("scanlines3p2"), _T("scanlines3p3"),
- 0 };
- static const TCHAR *speedmode[] = { _T("max"), _T("real"), 0 };
- static const TCHAR *colormode1[] = { _T("8bit"), _T("15bit"), _T("16bit"), _T("8bit_dither"), _T("4bit_dither"), _T("32bit"), 0 };
- static const TCHAR *colormode2[] = { _T("8"), _T("15"), _T("16"), _T("8d"), _T("4d"), _T("32"), 0 };
- static const TCHAR *soundmode1[] = { _T("none"), _T("interrupts"), _T("normal"), _T("exact"), 0 };
- static const TCHAR *soundmode2[] = { _T("none"), _T("interrupts"), _T("good"), _T("best"), 0 };
- static const TCHAR *centermode1[] = { _T("none"), _T("simple"), _T("smart"), 0 };
- static const TCHAR *centermode2[] = { _T("false"), _T("true"), _T("smart"), 0 };
- static const TCHAR *stereomode[] = { _T("mono"), _T("stereo"), _T("clonedstereo"), _T("4ch"), _T("clonedstereo6ch"), _T("6ch"), _T("mixed"), 0 };
- static const TCHAR *interpolmode[] = { _T("none"), _T("anti"), _T("sinc"), _T("rh"), _T("crux"), 0 };
- static const TCHAR *collmode[] = { _T("none"), _T("sprites"), _T("playfields"), _T("full"), 0 };
- static const TCHAR *compmode[] = { _T("direct"), _T("indirect"), _T("indirectKS"), _T("afterPic"), 0 };
- static const TCHAR *flushmode[] = { _T("soft"), _T("hard"), 0 };
- static const TCHAR *kbleds[] = { _T("none"), _T("POWER"), _T("DF0"), _T("DF1"), _T("DF2"), _T("DF3"), _T("HD"), _T("CD"), _T("DFx"), 0 };
- static const TCHAR *onscreenleds[] = { _T("false"), _T("true"), _T("rtg"), _T("both"), 0 };
- static const TCHAR *soundfiltermode1[] = { _T("off"), _T("emulated"), _T("on"), 0 };
- static const TCHAR *soundfiltermode2[] = { _T("standard"), _T("enhanced"), 0 };
- static const TCHAR *lorestype1[] = { _T("lores"), _T("hires"), _T("superhires"), 0 };
- static const TCHAR *lorestype2[] = { _T("true"), _T("false"), 0 };
- static const TCHAR *loresmode[] = { _T("normal"), _T("filtered"), 0 };
- static const TCHAR *horizmode[] = { _T("vertical"), _T("lores"), _T("hires"), _T("superhires"), 0 };
- static const TCHAR *vertmode[] = { _T("horizontal"), _T("single"), _T("double"), _T("quadruple"), 0 };
- #ifdef GFXFILTER
- static const TCHAR *filtermode2[] = { _T("1x"), _T("2x"), _T("3x"), _T("4x"), 0 };
- static const TCHAR *filtermode2v[] = { _T("-"), _T("1x"), _T("2x"), _T("3x"), _T("4x"), 0 };
- #endif
- static const TCHAR *cartsmode[] = { _T("none"), _T("hrtmon"), 0 };
- static const TCHAR *idemode[] = { _T("none"), _T("a600/a1200"), _T("a4000"), 0 };
- static const TCHAR *rtctype[] = { _T("none"), _T("MSM6242B"), _T("RP5C01A"), _T("MSM6242B_A2000"), 0 };
- static const TCHAR *ciaatodmode[] = { _T("vblank"), _T("50hz"), _T("60hz"), 0 };
- static const TCHAR *ksmirrortype[] = { _T("none"), _T("e0"), _T("a8+e0"), 0 };
- static const TCHAR *cscompa[] = {
- _T("-"), _T("Generic"), _T("CDTV"), _T("CDTV-CR"), _T("CD32"), _T("A500"), _T("A500+"), _T("A600"),
- _T("A1000"), _T("A1200"), _T("A2000"), _T("A3000"), _T("A3000T"), _T("A4000"), _T("A4000T"),
- _T("Velvet"), _T("Casablanca"), _T("DraCo"),
- NULL
- };
- static const TCHAR *qsmodes[] = {
- _T("A500"), _T("A500+"), _T("A600"), _T("A1000"), _T("A1200"), _T("A3000"), _T("A4000"), _T(""), _T("CD32"), _T("CDTV"), _T("CDTV-CR"), _T("ARCADIA"), NULL };
- /* 3-state boolean! */
- static const TCHAR *fullmodes[] = { _T("false"), _T("true"), /* "FILE_NOT_FOUND", */ _T("fullwindow"), 0 };
- /* bleh for compatibility */
- static const TCHAR *scsimode[] = { _T("false"), _T("true"), _T("scsi"), 0 };
- static const TCHAR *maxhoriz[] = { _T("lores"), _T("hires"), _T("superhires"), 0 };
- static const TCHAR *maxvert[] = { _T("nointerlace"), _T("interlace"), 0 };
- static const TCHAR *abspointers[] = { _T("none"), _T("mousehack"), _T("tablet"), 0 };
- static const TCHAR *magiccursors[] = { _T("both"), _T("native"), _T("host"), 0 };
- static const TCHAR *autoscale[] = { _T("none"), _T("auto"), _T("standard"), _T("max"), _T("scale"), _T("resize"), _T("center"), _T("manual"),
- _T("integer"), _T("integer_auto"), _T("separator"), _T("overscan_blanking"), 0 };
- static const TCHAR *autoscale_rtg[] = { _T("resize"), _T("scale"), _T("center"), _T("integer"), 0 };
- static const TCHAR *autoscalelimit[] = { _T("1/1"), _T("1/2"), _T("1/4"), _T("1/8"), 0 };
- static const TCHAR *joyportmodes[] = { _T(""), _T("mouse"), _T("mousenowheel"), _T("djoy"), _T("gamepad"), _T("ajoy"), _T("cdtvjoy"), _T("cd32joy"), _T("lightpen"), 0 };
- static const TCHAR *joyportsubmodes_lightpen[] = { _T(""), _T("trojan"), 0 };
- static const TCHAR *joyaf[] = { _T("none"), _T("normal"), _T("toggle"), _T("always"), 0 };
- static const TCHAR *epsonprinter[] = { _T("none"), _T("ascii"), _T("epson_matrix_9pin"), _T("epson_matrix_24pin"), _T("epson_matrix_48pin"), 0 };
- static const TCHAR *aspects[] = { _T("none"), _T("vga"), _T("tv"), 0 };
- static const TCHAR *vsyncmodes[] = { _T("false"), _T("true"), _T("autoswitch"), 0 };
- static const TCHAR *vsyncmodes2[] = { _T("normal"), _T("busywait"), 0 };
- static const TCHAR *filterapi[] = { _T("directdraw"), _T("direct3d"), _T("direct3d11"), _T("direct3d11"), 0};
- static const TCHAR *filterapiopts[] = { _T("hardware"), _T("software"), 0 };
- static const TCHAR *overscanmodes[] = { _T("tv_narrow"), _T("tv_standard"), _T("tv_wide"), _T("overscan"), _T("broadcast"), _T("extreme"), NULL };
- static const TCHAR *dongles[] =
- {
- _T("none"),
- _T("robocop 3"), _T("leaderboard"), _T("b.a.t. ii"), _T("italy'90 soccer"), _T("dames grand maitre"),
- _T("rugby coach"), _T("cricket captain"), _T("leviathan"), _T("musicmaster"),
- _T("logistics"), _T("scala red"), _T("scala green"),
- NULL
- };
- static const TCHAR *cdmodes[] = { _T("disabled"), _T(""), _T("image"), _T("ioctl"), _T("spti"), _T("aspi"), 0 };
- static const TCHAR *cdconmodes[] = { _T(""), _T("uae"), _T("ide"), _T("scsi"), _T("cdtv"), _T("cd32"), 0 };
- static const TCHAR *genlockmodes[] = { _T("none"), _T("noise"), _T("testcard"), _T("image"), _T("video"), _T("stream"), _T("ld"), _T("sony_ld"), _T("pioneer_ld"), NULL };
- static const TCHAR *ppc_implementations[] = {
- _T("auto"),
- _T("dummy"),
- _T("pearpc"),
- _T("qemu"),
- NULL
- };
- static const TCHAR *ppc_cpu_idle[] = {
- _T("disabled"),
- _T("1"),
- _T("2"),
- _T("3"),
- _T("4"),
- _T("5"),
- _T("6"),
- _T("7"),
- _T("8"),
- _T("9"),
- _T("max"),
- NULL
- };
- static const TCHAR *waitblits[] = { _T("disabled"), _T("automatic"), _T("noidleonly"), _T("always"), 0 };
- static const TCHAR *autoext2[] = { _T("disabled"), _T("copy"), _T("replace"), 0 };
- static const TCHAR *leds[] = { _T("power"), _T("df0"), _T("df1"), _T("df2"), _T("df3"), _T("hd"), _T("cd"), _T("fps"), _T("cpu"), _T("snd"), _T("md"), _T("net"), 0 };
- static const int leds_order[] = { 3, 6, 7, 8, 9, 4, 5, 2, 1, 0, 9, 10 };
- static const TCHAR *lacer[] = { _T("off"), _T("i"), _T("p"), 0 };
- /* another boolean to choice update.. */
- static const TCHAR *cycleexact[] = { _T("false"), _T("memory"), _T("true"), 0 };
- static const TCHAR *unmapped[] = { _T("floating"), _T("zero"), _T("one"), 0 };
- static const TCHAR *ciatype[] = { _T("default"), _T("391078-01"), 0 };
- static const TCHAR *debugfeatures[] = { _T("segtracker"), _T("fsdebug"), 0 };
- struct hdcontrollerconfig
- {
- const TCHAR *label;
- int romtype;
- };
- static const struct hdcontrollerconfig hdcontrollers[] = {
- { _T("uae"), 0 },
- { _T("ide%d"), 0 },
- { _T("ide%d_mainboard"), ROMTYPE_MB_IDE },
- { _T("scsi%d"), 0 },
- { _T("scsi%d_a3000"), ROMTYPE_SCSI_A3000 },
- { _T("scsi%d_a4000t"), ROMTYPE_SCSI_A4000T },
- { _T("scsi%d_cdtv"), ROMTYPE_CDTVSCSI },
- { NULL }
- };
- static const TCHAR *z3mapping[] = {
- _T("auto"),
- _T("uae"),
- _T("real"),
- NULL
- };
- static const TCHAR *uaescsidevmodes[] = {
- _T("original"),
- _T("rename_scsi"),
- NULL
- };
- static const TCHAR *uaebootrom[] = {
- _T("automatic"),
- _T("disabled"),
- _T("min"),
- _T("full"),
- NULL
- };
- static const TCHAR *uaeboard[] = {
- _T("disabled"),
- _T("min"),
- _T("full"),
- _T("full+indirect"),
- NULL
- };
- static const TCHAR *uaeboard_off[] = {
- _T("disabled_off"),
- _T("min_off"),
- _T("full_off"),
- _T("full+indirect_off"),
- NULL
- };
- static const TCHAR *serialcrlf[] = {
- _T("disabled"),
- _T("crlf_cr"),
- NULL
- };
- static const TCHAR *threebitcolors[] = {
- _T("disabled"),
- _T("3to4to8bit"),
- _T("3to4bit"),
- _T("3to8bit"),
- NULL
- };
- static const TCHAR *obsolete[] = {
- _T("accuracy"), _T("gfx_opengl"), _T("gfx_32bit_blits"), _T("32bit_blits"),
- _T("gfx_immediate_blits"), _T("gfx_ntsc"), _T("win32"), _T("gfx_filter_bits"),
- _T("sound_pri_cutoff"), _T("sound_pri_time"), _T("sound_min_buff"), _T("sound_bits"),
- _T("gfx_test_speed"), _T("gfxlib_replacement"), _T("enforcer"), _T("catweasel_io"),
- _T("kickstart_key_file"), _T("fast_copper"), _T("sound_adjust"), _T("sound_latency"),
- _T("serial_hardware_dtrdsr"), _T("gfx_filter_upscale"),
- _T("gfx_correct_aspect"), _T("gfx_autoscale"), _T("parallel_sampler"), _T("parallel_ascii_emulation"),
- _T("avoid_vid"), _T("avoid_dga"), _T("z3chipmem_size"), _T("state_replay_buffer"), _T("state_replay"),
- _T("z3realmapping"), _T("force_0x10000000_z3"),
- _T("fpu_arithmetic_exceptions"),
-
- _T("gfx_filter_vert_zoom"),_T("gfx_filter_horiz_zoom"),
- _T("gfx_filter_vert_zoom_mult"), _T("gfx_filter_horiz_zoom_mult"),
- _T("gfx_filter_vert_offset"), _T("gfx_filter_horiz_offset"),
- _T("gfx_tearing"), _T("gfx_tearing_rtg"),
-
- // created by some buggy beta
- _T("uaehf0%s,%s"),
- _T("uaehf1%s,%s"),
- _T("uaehf2%s,%s"),
- _T("uaehf3%s,%s"),
- _T("uaehf4%s,%s"),
- _T("uaehf5%s,%s"),
- _T("uaehf6%s,%s"),
- _T("uaehf7%s,%s"),
- _T("pcibridge_rom_file"),
- _T("pcibridge_rom_options"),
- _T("cpuboard_ext_rom_file"),
- _T("uaeboard_mode"),
- _T("comp_oldsegv"),
- _T("comp_midopt"),
- _T("comp_lowopt"),
- _T("avoid_cmov"),
- _T("compforcesettings"),
- _T("comp_catchdetect"),
- _T("hblank_glitch"),
- _T("gfx_hdr"),
- NULL
- };
- #define UNEXPANDED _T("$(FILE_PATH)")
- static TCHAR *cfgfile_unescape(const TCHAR *s, const TCHAR **endpos, TCHAR separator, bool min)
- {
- bool quoted = false;
- TCHAR *s2 = xmalloc(TCHAR, _tcslen(s) + 1);
- TCHAR *p = s2;
- if (s[0] == '\"') {
- s++;
- quoted = true;
- }
- int i;
- for (i = 0; s[i]; i++) {
- TCHAR c = s[i];
- if (quoted && c == '\"') {
- i++;
- break;
- }
- if (c == separator) {
- i++;
- break;
- }
- if (c == '\\' && !min) {
- char v = 0;
- TCHAR c2;
- c = s[i + 1];
- switch (c)
- {
- case 'X':
- case 'x':
- c2 = _totupper(s[i + 2]);
- v = ((c2 >= 'A') ? c2 - 'A' : c2 - '0') << 4;
- c2 = _totupper(s[i + 3]);
- v |= (c2 >= 'A') ? c2 - 'A' : c2 - '0';
- *p++ = c2;
- i += 2;
- break;
- case 'r':
- *p++ = '\r';
- break;
- case '\n':
- *p++ = '\n';
- break;
- default:
- *p++ = c;
- break;
- }
- i++;
- }
- else {
- *p++ = c;
- }
- }
- *p = 0;
- if (endpos)
- *endpos = &s[i];
- return s2;
- }
- static TCHAR *cfgfile_unescape(const TCHAR *s, const TCHAR **endpos)
- {
- return cfgfile_unescape(s, endpos, 0, false);
- }
- static TCHAR *cfgfile_unescape_min(const TCHAR *s)
- {
- return cfgfile_unescape(s, NULL, 0, true);
- }
- static TCHAR *cfgfile_option_find_it(const TCHAR *s, const TCHAR *option, bool checkequals)
- {
- TCHAR buf[MAX_DPATH];
- if (!s)
- return NULL;
- _tcscpy(buf, s);
- _tcscat(buf, _T(","));
- TCHAR *p = buf;
- for (;;) {
- TCHAR *tmpp = _tcschr(p, ',');
- TCHAR *tmpp2 = NULL;
- if (tmpp == NULL)
- return NULL;
- *tmpp++ = 0;
- if (checkequals) {
- tmpp2 = _tcschr(p, '=');
- if (tmpp2)
- *tmpp2++ = 0;
- }
- if (!strcasecmp(p, option)) {
- if (checkequals && tmpp2) {
- if (tmpp2[0] == '"') {
- TCHAR *n = cfgfile_unescape_min(tmpp2);
- return n;
- }
- return my_strdup(tmpp2);
- }
- return my_strdup(p);
- }
- p = tmpp;
- }
- }
- bool cfgfile_option_find(const TCHAR *s, const TCHAR *option)
- {
- TCHAR *ss = cfgfile_option_find_it(s, option, false);
- xfree(ss);
- return ss != NULL;
- }
- TCHAR *cfgfile_option_get(const TCHAR *s, const TCHAR *option)
- {
- return cfgfile_option_find_it(s, option, true);
- }
- bool cfgfile_option_get_bool(const TCHAR* s, const TCHAR* option)
- {
- TCHAR *d = cfgfile_option_find_it(s, option, true);
- bool ret = d && (!_tcsicmp(d, _T("true")) || !_tcsicmp(d, _T("1")));
- xfree(d);
- return ret;
- }
- static void trimwsa (char *s)
- {
- /* Delete trailing whitespace. */
- int len = strlen (s);
- while (len > 0 && strcspn (s + len - 1, "\t \r\n") == 0)
- s[--len] = '\0';
- }
- static int match_string (const TCHAR *table[], const TCHAR *str)
- {
- int i;
- for (i = 0; table[i] != 0; i++)
- if (strcasecmp (table[i], str) == 0)
- return i;
- return -1;
- }
- // escape config file separators and control characters
- static TCHAR *cfgfile_escape (const TCHAR *s, const TCHAR *escstr, bool quote)
- {
- bool doquote = false;
- int cnt = 0;
- for (int i = 0; s[i]; i++) {
- TCHAR c = s[i];
- if (c == 0)
- break;
- if (c < 32 || c == '\\' || c == '\"' || c == '\'') {
- cnt++;
- }
- for (int j = 0; escstr && escstr[j]; j++) {
- if (c == escstr[j]) {
- cnt++;
- if (quote) {
- doquote = true;
- cnt++;
- }
- }
- }
- // always quote if starts or ends with space
- if (c == ' ' && (s[i + 1] == 0 || i == 0)) {
- doquote = true;
- }
- }
- if (escstr == NULL && quote)
- doquote = true;
- TCHAR *s2 = xmalloc (TCHAR, _tcslen (s) + cnt * 4 + 2 + 1);
- TCHAR *p = s2;
- if (doquote)
- *p++ = '\"';
- for (int i = 0; s[i]; i++) {
- TCHAR c = s[i];
- if (c == 0)
- break;
- if (c == '\\' || c == '\"' || c == '\'') {
- *p++ = '\\';
- *p++ = c;
- } else if (c >= 32 && !quote) {
- bool escaped = false;
- for (int j = 0; escstr && escstr[j]; j++) {
- if (c == escstr[j]) {
- *p++ = '\\';
- *p++ = c;
- escaped = true;
- break;
- }
- }
- if (!escaped)
- *p++ = c;
- } else if (c < 32) {
- *p++ = '\\';
- switch (c)
- {
- case '\t':
- *p++ = 't';
- break;
- case '\n':
- *p++ = 'n';
- break;
- case '\r':
- *p++ = 'r';
- break;
- default:
- *p++ = 'x';
- *p++ = (c >> 4) >= 10 ? (c >> 4) + 'a' : (c >> 4) + '0';
- *p++ = (c & 15) >= 10 ? (c & 15) + 'a' : (c & 15) + '0';
- break;
- }
- } else {
- *p++ = c;
- }
- }
- if (doquote)
- *p++ = '\"';
- *p = 0;
- return s2;
- }
- // escapy only , and " or if starts or ends with a space
- static TCHAR *cfgfile_escape_min(const TCHAR *s)
- {
- for (int i = 0; s[i]; i++) {
- TCHAR c = s[i];
- if (c == ',' || c == '\"' || (c == ' ' && (i == 0 || s[i + 1] == 0))) {
- return cfgfile_escape(s, _T(","), true);
- }
- }
- return my_strdup(s);
- }
- static TCHAR *getnextentry (const TCHAR **valuep, const TCHAR separator)
- {
- TCHAR *s;
- const TCHAR *value = *valuep;
- if (value[0] == '\"') {
- s = cfgfile_unescape (value, valuep);
- value = *valuep;
- if (*value != 0 && *value != separator) {
- xfree (s);
- return NULL;
- }
- value++;
- *valuep = value;
- } else {
- s = cfgfile_unescape (value, valuep, separator, false);
- }
- return s;
- }
- static TCHAR *cfgfile_subst_path2 (const TCHAR *path, const TCHAR *subst, const TCHAR *file)
- {
- /* @@@ use strcasecmp for some targets. */
- if (path != NULL && subst != NULL && _tcslen (path) > 0 && _tcsncmp (file, path, _tcslen (path)) == 0) {
- int l;
- TCHAR *p2, *p = xmalloc (TCHAR, _tcslen (file) + _tcslen (subst) + 2);
- _tcscpy (p, subst);
- l = _tcslen (p);
- while (l > 0 && p[l - 1] == '/')
- p[--l] = '\0';
- l = _tcslen (path);
- while (file[l] == '/')
- l++;
- _tcscat (p, _T("/"));
- _tcscat (p, file + l);
- p2 = target_expand_environment (p, NULL, 0);
- xfree (p);
- if (p2 && p2[0] == '$') {
- xfree(p2);
- return NULL;
- }
- return p2;
- }
- return NULL;
- }
- TCHAR *cfgfile_subst_path (const TCHAR *path, const TCHAR *subst, const TCHAR *file)
- {
- TCHAR *s = cfgfile_subst_path2 (path, subst, file);
- if (s)
- return s;
- s = target_expand_environment (file, NULL, 0);
- if (s) {
- TCHAR tmp[MAX_DPATH];
- _tcscpy (tmp, s);
- xfree (s);
- fullpath (tmp, sizeof tmp / sizeof (TCHAR));
- s = my_strdup (tmp);
- }
- return s;
- }
- static TCHAR *cfgfile_get_multipath2 (struct multipath *mp, const TCHAR *path, const TCHAR *file, bool dir)
- {
- for (int i = 0; i < MAX_PATHS; i++) {
- if (mp->path[i][0] && _tcscmp (mp->path[i], _T(".\\")) != 0 && _tcscmp (mp->path[i], _T("./")) != 0 && (file[0] != '/' && file[0] != '\\' && !_tcschr(file, ':'))) {
- TCHAR *s = NULL;
- if (path)
- s = cfgfile_subst_path2 (path, mp->path[i], file);
- if (!s) {
- TCHAR np[MAX_DPATH];
- _tcscpy (np, mp->path[i]);
- fixtrailing (np);
- _tcscat (np, file);
- fullpath (np, sizeof np / sizeof (TCHAR));
- s = my_strdup (np);
- }
- if (dir) {
- if (my_existsdir (s))
- return s;
- } else {
- if (zfile_exists (s))
- return s;
- }
- xfree (s);
- }
- }
- return NULL;
- }
- static TCHAR *cfgfile_get_multipath (struct multipath *mp, const TCHAR *path, const TCHAR *file, bool dir)
- {
- TCHAR *s = cfgfile_get_multipath2 (mp, path, file, dir);
- if (s)
- return s;
- return my_strdup (file);
- }
- static TCHAR *cfgfile_put_multipath (struct multipath *mp, const TCHAR *s)
- {
- for (int i = 0; i < MAX_PATHS; i++) {
- if (mp->path[i][0] && _tcscmp (mp->path[i], _T(".\\")) != 0 && _tcscmp (mp->path[i], _T("./")) != 0) {
- if (_tcsnicmp (mp->path[i], s, _tcslen (mp->path[i])) == 0) {
- return my_strdup (s + _tcslen (mp->path[i]));
- }
- }
- }
- return my_strdup (s);
- }
- static TCHAR *cfgfile_subst_path_load (const TCHAR *path, struct multipath *mp, const TCHAR *file, bool dir)
- {
- TCHAR *s = cfgfile_get_multipath2 (mp, path, file, dir);
- if (s)
- return s;
- return cfgfile_subst_path (path, mp->path[0], file);
- }
- static bool isdefault (const TCHAR *s)
- {
- TCHAR tmp[MAX_DPATH];
- if (!default_file || uaeconfig)
- return false;
- zfile_fseek (default_file, 0, SEEK_SET);
- while (zfile_fgets (tmp, sizeof tmp / sizeof (TCHAR), default_file)) {
- if (tmp[0] && tmp[_tcslen (tmp) - 1] == '\n')
- tmp[_tcslen (tmp) - 1] = 0;
- if (!_tcscmp (tmp, s))
- return true;
- }
- return false;
- }
- static size_t cfg_write (const void *b, struct zfile *z)
- {
- size_t v;
- if (unicode_config) {
- TCHAR lf = 10;
- v = zfile_fwrite (b, _tcslen ((TCHAR*)b), sizeof (TCHAR), z);
- zfile_fwrite (&lf, 1, 1, z);
- } else {
- char lf = 10;
- char *s = ua ((TCHAR*)b);
- v = zfile_fwrite (s, strlen (s), 1, z);
- zfile_fwrite (&lf, 1, 1, z);
- xfree (s);
- }
- return v;
- }
- #define UTF8NAME _T(".utf8")
- static void cfg_dowrite(struct zfile *f, const TCHAR *option, const TCHAR *optionext, const TCHAR *value, int d, int target, int escape)
- {
- char lf = 10;
- TCHAR tmp[CONFIG_BLEN], tmpext[CONFIG_BLEN];
- const TCHAR *optionp;
- const TCHAR *new_value = NULL;
- bool free_value = false;
- char tmpa[CONFIG_BLEN];
- char *tmp1, *tmp2;
- int utf8;
- if (value == NULL)
- return;
- if (optionext) {
- _tcscpy(tmpext, option);
- _tcscat(tmpext, optionext);
- optionp = tmpext;
- } else {
- optionp = option;
- }
- utf8 = 0;
- tmp1 = ua(value);
- tmp2 = uutf8(value);
- if (strcmp(tmp1, tmp2) && tmp2[0] != 0)
- utf8 = 1;
- if (escape) {
- new_value = cfgfile_escape_min(value);
- free_value = true;
- } else {
- new_value = value;
- }
- if (target)
- _stprintf(tmp, _T("%s.%s=%s"), TARGET_NAME, optionp, new_value);
- else
- _stprintf(tmp, _T("%s=%s"), optionp, new_value);
- if (d && isdefault (tmp))
- goto end;
- cfg_write(tmp, f);
- if (utf8 && !unicode_config) {
- char *opt = ua(optionp);
- if (target) {
- char *tna = ua(TARGET_NAME);
- sprintf(tmpa, "%s.%s.utf8=%s", tna, opt, tmp2);
- xfree(tna);
- } else {
- sprintf(tmpa, "%s.utf8=%s", opt, tmp2);
- }
- xfree(opt);
- zfile_fwrite(tmpa, strlen (tmpa), 1, f);
- zfile_fwrite(&lf, 1, 1, f);
- }
- end:
- if (free_value) {
- xfree((void*)new_value);
- }
- xfree(tmp2);
- xfree(tmp1);
- }
- static void cfgfile_dwrite_coords(struct zfile *f, const TCHAR *option, int x, int y)
- {
- if (x || y)
- cfgfile_dwrite(f, option, _T("%d,%d"), x, y);
- }
- static void cfg_dowrite(struct zfile *f, const TCHAR *option, const TCHAR *value, int d, int target, int escape)
- {
- cfg_dowrite(f, option, NULL, value, d, target, escape);
- }
- void cfgfile_write_bool(struct zfile *f, const TCHAR *option, bool b)
- {
- cfg_dowrite(f, option, b ? _T("true") : _T("false"), 0, 0, 0);
- }
- void cfgfile_dwrite_bool(struct zfile *f, const TCHAR *option, bool b)
- {
- cfg_dowrite(f, option, b ? _T("true") : _T("false"), 1, 0, 0);
- }
- static void cfgfile_dwrite_bool(struct zfile *f, const TCHAR *option, const TCHAR *optionext, bool b)
- {
- cfg_dowrite(f, option, optionext, b ? _T("true") : _T("false"), 1, 0, 0);
- }
- static void cfgfile_dwrite_bool(struct zfile *f, const TCHAR *option, int b)
- {
- cfgfile_dwrite_bool (f, option, b != 0);
- }
- void cfgfile_write_str(struct zfile *f, const TCHAR *option, const TCHAR *value)
- {
- cfg_dowrite(f, option, value, 0, 0, 0);
- }
- static void cfgfile_write_str(struct zfile *f, const TCHAR *option, const TCHAR *optionext, const TCHAR *value)
- {
- cfg_dowrite(f, option, optionext, value, 0, 0, 0);
- }
- static void cfgfile_write_str_escape(struct zfile *f, const TCHAR *option, const TCHAR *value)
- {
- cfg_dowrite(f, option, value, 0, 0, 1);
- }
- void cfgfile_dwrite_str(struct zfile *f, const TCHAR *option, const TCHAR *value)
- {
- cfg_dowrite(f, option, value, 1, 0, 0);
- }
- static void cfgfile_dwrite_str(struct zfile *f, const TCHAR *option, const TCHAR *optionext, const TCHAR *value)
- {
- cfg_dowrite(f, option, optionext, value, 1, 0, 0);
- }
- void cfgfile_target_write_bool(struct zfile *f, const TCHAR *option, bool b)
- {
- cfg_dowrite(f, option, b ? _T("true") : _T("false"), 0, 1, 0);
- }
- void cfgfile_target_dwrite_bool(struct zfile *f, const TCHAR *option, bool b)
- {
- cfg_dowrite(f, option, b ? _T("true") : _T("false"), 1, 1, 0);
- }
- void cfgfile_target_write_str(struct zfile *f, const TCHAR *option, const TCHAR *value)
- {
- cfg_dowrite(f, option, value, 0, 1, 0);
- }
- void cfgfile_target_dwrite_str(struct zfile *f, const TCHAR *option, const TCHAR *value)
- {
- cfg_dowrite(f, option, value, 1, 1, 0);
- }
- void cfgfile_target_dwrite_str_escape(struct zfile *f, const TCHAR *option, const TCHAR *value)
- {
- cfg_dowrite(f, option, value, 1, 1, 1);
- }
- static void cfgfile_write_ext(struct zfile *f, const TCHAR *option, const TCHAR *optionext, const TCHAR *format,...)
- {
- va_list parms;
- TCHAR tmp[CONFIG_BLEN], tmp2[CONFIG_BLEN];
- if (optionext) {
- _tcscpy(tmp2, option);
- _tcscat(tmp2, optionext);
- }
- va_start(parms, format);
- _vsntprintf(tmp, CONFIG_BLEN, format, parms);
- cfg_dowrite(f, optionext ? tmp2 : option, tmp, 0, 0, 0);
- va_end(parms);
- }
- void cfgfile_write(struct zfile *f, const TCHAR *option, const TCHAR *format,...)
- {
- va_list parms;
- TCHAR tmp[CONFIG_BLEN];
- va_start(parms, format);
- _vsntprintf(tmp, CONFIG_BLEN, format, parms);
- cfg_dowrite(f, option, tmp, 0, 0, 0);
- va_end(parms);
- }
- void cfgfile_write_escape(struct zfile *f, const TCHAR *option, const TCHAR *format,...)
- {
- va_list parms;
- TCHAR tmp[CONFIG_BLEN];
- va_start(parms, format);
- _vsntprintf(tmp, CONFIG_BLEN, format, parms);
- cfg_dowrite(f, option, tmp, 0, 0, 1);
- va_end(parms);
- }
- static void cfgfile_dwrite_ext(struct zfile *f, const TCHAR *option, const TCHAR *optionext, const TCHAR *format,...)
- {
- va_list parms;
- TCHAR tmp[CONFIG_BLEN], tmp2[CONFIG_BLEN];
- if (optionext) {
- _tcscpy(tmp2, option);
- _tcscat(tmp2, optionext);
- }
- va_start(parms, format);
- _vsntprintf(tmp, CONFIG_BLEN, format, parms);
- cfg_dowrite(f, optionext ? tmp2 : option, tmp, 1, 0, 0);
- va_end(parms);
- }
- void cfgfile_dwrite(struct zfile *f, const TCHAR *option, const TCHAR *format,...)
- {
- va_list parms;
- TCHAR tmp[CONFIG_BLEN];
- va_start(parms, format);
- _vsntprintf(tmp, CONFIG_BLEN, format, parms);
- cfg_dowrite(f, option, tmp, 1, 0, 0);
- va_end(parms);
- }
- void cfgfile_dwrite_escape(struct zfile *f, const TCHAR *option, const TCHAR *format,...)
- {
- va_list parms;
- TCHAR tmp[CONFIG_BLEN];
- va_start(parms, format);
- _vsntprintf(tmp, CONFIG_BLEN, format, parms);
- cfg_dowrite(f, option, tmp, 1, 0, 1);
- va_end(parms);
- }
- void cfgfile_target_write(struct zfile *f, const TCHAR *option, const TCHAR *format,...)
- {
- va_list parms;
- TCHAR tmp[CONFIG_BLEN];
- va_start(parms, format);
- _vsntprintf(tmp, CONFIG_BLEN, format, parms);
- cfg_dowrite(f, option, tmp, 0, 1, 0);
- va_end(parms);
- }
- void cfgfile_target_write_escape(struct zfile *f, const TCHAR *option, const TCHAR *format,...)
- {
- va_list parms;
- TCHAR tmp[CONFIG_BLEN];
- va_start(parms, format);
- _vsntprintf(tmp, CONFIG_BLEN, format, parms);
- cfg_dowrite(f, option, tmp, 0, 1, 1);
- va_end(parms);
- }
- void cfgfile_target_dwrite(struct zfile *f, const TCHAR *option, const TCHAR *format,...)
- {
- va_list parms;
- TCHAR tmp[CONFIG_BLEN];
- va_start(parms, format);
- _vsntprintf(tmp, CONFIG_BLEN, format, parms);
- cfg_dowrite(f, option, tmp, 1, 1, 0);
- va_end(parms);
- }
- void cfgfile_target_dwrite_escape(struct zfile *f, const TCHAR *option, const TCHAR *format,...)
- {
- va_list parms;
- TCHAR tmp[CONFIG_BLEN];
- va_start(parms, format);
- _vsntprintf(tmp, CONFIG_BLEN, format, parms);
- cfg_dowrite(f, option, tmp, 1, 1, 1);
- va_end(parms);
- }
- static void cfgfile_write_rom (struct zfile *f, struct multipath *mp, const TCHAR *romfile, const TCHAR *name)
- {
- TCHAR *str = cfgfile_subst_path (mp->path[0], UNEXPANDED, romfile);
- str = cfgfile_put_multipath (mp, str);
- cfgfile_write_str (f, name, str);
- struct zfile *zf = zfile_fopen (str, _T("rb"), ZFD_ALL);
- if (zf) {
- struct romdata *rd = getromdatabyzfile (zf);
- if (rd) {
- TCHAR name2[MAX_DPATH], str2[MAX_DPATH];
- _tcscpy (name2, name);
- _tcscat (name2, _T("_id"));
- _stprintf (str2, _T("%08X,%s"), rd->crc32, rd->name);
- cfgfile_write_str (f, name2, str2);
- }
- zfile_fclose (zf);
- }
- xfree (str);
- }
- static void cfgfile_to_path_save(const TCHAR *in, TCHAR *out, int type)
- {
- if (_tcschr(in, '%')) {
- _tcscpy(out, in);
- } else {
- cfgfile_resolve_path_out_save(in, out, MAX_DPATH, type);
- }
- }
- static void cfgfile_write_path2(struct zfile *f, const TCHAR *option, const TCHAR *value, int type)
- {
- if (_tcschr(value, '%')) {
- cfgfile_write_str(f, option, value);
- } else {
- TCHAR path[MAX_DPATH];
- cfgfile_resolve_path_out_save(value, path, MAX_DPATH, type);
- cfgfile_write_str(f, option, path);
- }
- }
- static void cfgfile_dwrite_path2(struct zfile *f, const TCHAR *option, const TCHAR *value, int type)
- {
- if (_tcschr(value, '%')) {
- cfgfile_dwrite_str(f, option, value);
- } else {
- TCHAR path[MAX_DPATH];
- cfgfile_resolve_path_out_save(value, path, MAX_DPATH, type);
- cfgfile_dwrite_str(f, option, path);
- }
- }
- static void cfgfile_write_path (struct zfile *f, struct multipath *mp, const TCHAR *option, const TCHAR *value)
- {
- TCHAR *s = cfgfile_put_multipath (mp, value);
- cfgfile_write_str (f, option, s);
- xfree (s);
- }
- static void cfgfile_dwrite_path (struct zfile *f, struct multipath *mp, const TCHAR *option, const TCHAR *value)
- {
- TCHAR *s = cfgfile_put_multipath (mp, value);
- cfgfile_dwrite_str (f, option, s);
- xfree (s);
- }
- static void cfgfile_write_multichoice(struct zfile *f, const TCHAR *option, const TCHAR *table[], int value)
- {
- TCHAR tmp[MAX_DPATH];
- if (!value)
- return;
- tmp[0] = 0;
- int i = 0;
- while (value && table[i]) {
- if (value & (1 << i) && table[i][0] && table[i][0] != '|') {
- if (tmp[0])
- _tcscat(tmp, _T(","));
- _tcscat(tmp, table[i]);
- }
- i++;
- }
- if (tmp[0])
- cfgfile_write(f, option, tmp);
- }
- static void cfgfile_adjust_path(TCHAR *path, int maxsz, struct multipath *mp)
- {
- if (path[0] == 0)
- return;
- TCHAR *s = target_expand_environment(path, NULL, 0);
- _tcsncpy(path, s, maxsz - 1);
- path[maxsz - 1] = 0;
- if (mp) {
- for (int i = 0; i < MAX_PATHS; i++) {
- if (mp->path[i][0] && _tcscmp(mp->path[i], _T(".\\")) != 0 && _tcscmp(mp->path[i], _T("./")) != 0 && (path[0] != '/' && path[0] != '\\' && !_tcschr(path, ':'))) {
- TCHAR np[MAX_DPATH];
- _tcscpy(np, mp->path[i]);
- fixtrailing(np);
- _tcscat(np, s);
- fullpath(np, sizeof np / sizeof(TCHAR));
- if (zfile_exists(np)) {
- _tcsncpy(path, np, maxsz - 1);
- path[maxsz - 1] = 0;
- xfree(s);
- return;
- }
- }
- }
- }
- fullpath(path, maxsz);
- xfree(s);
- }
- static void cfgfile_resolve_path_out_all(const TCHAR *path, TCHAR *out, int size, int type, bool save)
- {
- struct uae_prefs *p = &currprefs;
- TCHAR *s = NULL;
- switch (type)
- {
- case PATH_DIR:
- s = cfgfile_subst_path_load(UNEXPANDED, &p->path_hardfile, path, true);
- break;
- case PATH_HDF:
- s = cfgfile_subst_path_load(UNEXPANDED, &p->path_hardfile, path, false);
- break;
- case PATH_CD:
- s = cfgfile_subst_path_load(UNEXPANDED, &p->path_cd, path, false);
- break;
- case PATH_ROM:
- s = cfgfile_subst_path_load(UNEXPANDED, &p->path_rom, path, false);
- break;
- case PATH_FLOPPY:
- _tcscpy(out, path);
- cfgfile_adjust_path(out, MAX_DPATH, &p->path_floppy);
- break;
- default:
- s = cfgfile_subst_path(NULL, NULL, path);
- break;
- }
- if (s) {
- _tcscpy(out, s);
- xfree(s);
- }
- if (!save) {
- my_resolvesoftlink(out, size, true);
- }
- }
- void cfgfile_resolve_path_out_load(const TCHAR *path, TCHAR *out, int size, int type)
- {
- cfgfile_resolve_path_out_all(path, out, size, type, false);
- }
- void cfgfile_resolve_path_load(TCHAR *path, int size, int type)
- {
- cfgfile_resolve_path_out_all(path, path, size, type, false);
- }
- void cfgfile_resolve_path_out_save(const TCHAR *path, TCHAR *out, int size, int type)
- {
- cfgfile_resolve_path_out_all(path, out, size, type, true);
- }
- void cfgfile_resolve_path_save(TCHAR *path, int size, int type)
- {
- cfgfile_resolve_path_out_all(path, path, size, type, true);
- }
- static void write_filesys_config (struct uae_prefs *p, struct zfile *f)
- {
- TCHAR tmp[MAX_DPATH], tmp2[MAX_DPATH], tmp3[MAX_DPATH], str1[MAX_DPATH], hdcs[MAX_DPATH];
- for (int i = 0; i < p->mountitems; i++) {
- struct uaedev_config_data *uci = &p->mountconfig[i];
- struct uaedev_config_info *ci = &uci->ci;
- TCHAR *str1b, *str1c, *str2b;
- const TCHAR *str2;
- int bp = ci->bootpri;
- str2 = _T("");
- if (ci->rootdir[0] == ':') {
- TCHAR *ptr;
- // separate harddrive names
- _tcscpy(str1, ci->rootdir);
- ptr = _tcschr (str1 + 1, ':');
- if (ptr) {
- *ptr++ = 0;
- str2 = ptr;
- ptr = (TCHAR *) _tcschr (str2, ',');
- if (ptr)
- *ptr = 0;
- }
- } else {
- cfgfile_to_path_save(ci->rootdir, str1, ci->type == UAEDEV_DIR ? PATH_DIR : (ci->type == UAEDEV_CD ? PATH_CD : (ci->type == UAEDEV_HDF ? PATH_HDF : PATH_TAPE)));
- }
- int ct = ci->controller_type;
- int romtype = 0;
- if (ct >= HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST && ct <= HD_CONTROLLER_TYPE_SCSI_LAST) {
- _stprintf(hdcs, _T("scsi%d_%s"), ci->controller_unit, expansionroms[ct - HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST].name);
- romtype = expansionroms[ct - HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST].romtype;
- } else if (ct >= HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST && ct <= HD_CONTROLLER_TYPE_IDE_LAST) {
- _stprintf(hdcs, _T("ide%d_%s"), ci->controller_unit, expansionroms[ct - HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST].name);
- romtype = expansionroms[ct - HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST].romtype;
- } else if (ct >= HD_CONTROLLER_TYPE_CUSTOM_FIRST && ct <= HD_CONTROLLER_TYPE_CUSTOM_LAST) {
- _stprintf(hdcs, _T("custom%d_%s"), ci->controller_unit, expansionroms[ct - HD_CONTROLLER_TYPE_CUSTOM_FIRST].name);
- romtype = expansionroms[ct - HD_CONTROLLER_TYPE_CUSTOM_FIRST].romtype;
- } else if (ct == HD_CONTROLLER_TYPE_SCSI_AUTO) {
- _stprintf(hdcs, _T("scsi%d"), ci->controller_unit);
- } else if (ct == HD_CONTROLLER_TYPE_IDE_AUTO) {
- _stprintf(hdcs, _T("ide%d"), ci->controller_unit);
- } else if (ct == HD_CONTROLLER_TYPE_UAE) {
- _stprintf(hdcs, _T("uae%d"), ci->controller_unit);
- }
- if (romtype) {
- for (int j = 0; hdcontrollers[j].label; j++) {
- if (hdcontrollers[j].romtype == (romtype & ROMTYPE_MASK)) {
- _stprintf(hdcs, hdcontrollers[j].label, ci->controller_unit);
- break;
- }
- }
- }
- if (ci->controller_type_unit > 0)
- _stprintf(hdcs + _tcslen(hdcs), _T("-%d"), ci->controller_type_unit + 1);
- str1b = cfgfile_escape (str1, _T(":,"), true);
- str1c = cfgfile_escape_min(str1);
- str2b = cfgfile_escape (str2, _T(":,"), true);
- if (ci->type == UAEDEV_DIR) {
- _stprintf (tmp, _T("%s,%s:%s:%s,%d"), ci->readonly ? _T("ro") : _T("rw"),
- ci->devname ? ci->devname : _T(""), ci->volname, str1c, bp);
- cfgfile_write_str (f, _T("filesystem2"), tmp);
- _tcscpy (tmp3, tmp);
- #if 0
- _stprintf (tmp2, _T("filesystem=%s,%s:%s"), uci->readonly ? _T("ro") : _T("rw"),
- uci->volname, str);
- zfile_fputs (f, tmp2);
- #endif
- } else if (ci->type == UAEDEV_HDF || ci->type == UAEDEV_CD || ci->type == UAEDEV_TAPE) {
- TCHAR filesyspath[MAX_DPATH];
- cfgfile_to_path_save(ci->filesys, filesyspath, PATH_HDF);
- TCHAR *sfilesys = cfgfile_escape_min(filesyspath);
- TCHAR *sgeometry = cfgfile_escape(ci->geometry, NULL, true);
- _stprintf (tmp, _T("%s,%s:%s,%d,%d,%d,%d,%d,%s,%s"),
- ci->readonly ? _T("ro") : _T("rw"),
- ci->devname ? ci->devname : _T(""), str1c,
- ci->sectors, ci->surfaces, ci->reserved, ci->blocksize,
- bp, ci->filesys[0] ? sfilesys : _T(""), hdcs);
- _stprintf (tmp3, _T("%s,%s:%s%s%s,%d,%d,%d,%d,%d,%s,%s"),
- ci->readonly ? _T("ro") : _T("rw"),
- ci->devname ? ci->devname : _T(""), str1b, str2b[0] ? _T(":") : _T(""), str2b,
- ci->sectors, ci->surfaces, ci->reserved, ci->blocksize,
- bp, ci->filesys[0] ? sfilesys : _T(""), hdcs);
- if (ci->highcyl || ci->physical_geometry || ci->geometry[0]) {
- TCHAR *s = tmp + _tcslen (tmp);
- TCHAR *s2 = s;
- _stprintf (s2, _T(",%d"), ci->highcyl);
- if ((ci->physical_geometry && ci->pheads && ci->psecs) || ci->geometry[0]) {
- s = tmp + _tcslen (tmp);
- _stprintf (s, _T(",%d/%d/%d"), ci->pcyls, ci->pheads, ci->psecs);
- if (ci->geometry[0]) {
- s = tmp + _tcslen (tmp);
- _stprintf (s, _T(",%s"), sgeometry);
- }
- }
- _tcscat (tmp3, s2);
- xfree(sfilesys);
- xfree(sgeometry);
- }
- if (ci->controller_media_type) {
- _tcscat(tmp, _T(",CF"));
- _tcscat(tmp3, _T(",CF"));
- }
- const TCHAR *extras = NULL;
- if (ct >= HD_CONTROLLER_TYPE_SCSI_FIRST && ct <= HD_CONTROLLER_TYPE_SCSI_LAST) {
- if (ci->unit_feature_level == HD_LEVEL_SCSI_1){
- extras = _T("SCSI1");
- } else if (ci->unit_feature_level == HD_LEVEL_SASI) {
- extras = _T("SASI");
- } else if (ci->unit_feature_level == HD_LEVEL_SASI_ENHANCED) {
- extras = _T("SASIE");
- } else if (ci->unit_feature_level == HD_LEVEL_SASI_CHS) {
- extras = _T("SASI_CHS");
- }
- } else if (ct >= HD_CONTROLLER_TYPE_IDE_FIRST && ct <= HD_CONTROLLER_TYPE_IDE_LAST) {
- if (ci->unit_feature_level == HD_LEVEL_ATA_1) {
- extras = _T("ATA1");
- } else if (ci->unit_feature_level == HD_LEVEL_ATA_2S) {
- extras = _T("ATA2+S");
- }
- }
- if (extras) {
- _tcscat(tmp, _T(","));
- _tcscat(tmp3, _T(","));
- _tcscat(tmp, extras);
- _tcscat(tmp3, extras);
- }
- if (ci->unit_special_flags) {
- TCHAR tmpx[32];
- _stprintf(tmpx, _T(",flags=0x%x"), ci->unit_special_flags);
- _tcscat(tmp, tmpx);
- _tcscat(tmp3, tmpx);
- }
- if (ci->lock) {
- _tcscat(tmp, _T(",lock"));
- _tcscat(tmp3, _T(",lock"));
- }
- if (ci->loadidentity) {
- _tcscat(tmp, _T(",identity"));
- _tcscat(tmp3, _T(",identity"));
- }
- if (ci->type == UAEDEV_HDF)
- cfgfile_write_str (f, _T("hardfile2"), tmp);
- #if 0
- _stprintf (tmp2, _T("hardfile=%s,%d,%d,%d,%d,%s"),
- uci->readonly ? "ro" : "rw", uci->sectors,
- uci->surfaces, uci->reserved, uci->blocksize, str);
- zfile_fputs (f, tmp2);
- #endif
- }
- _stprintf (tmp2, _T("uaehf%d"), i);
- if (ci->type == UAEDEV_CD) {
- cfgfile_write (f, tmp2, _T("cd%d,%s"), ci->device_emu_unit, tmp);
- } else if (ci->type == UAEDEV_TAPE) {
- cfgfile_write (f, tmp2, _T("tape%d,%s"), ci->device_emu_unit, tmp);
- } else {
- cfgfile_write (f, tmp2, _T("%s,%s"), ci->type == UAEDEV_HDF ? _T("hdf") : _T("dir"), tmp3);
- }
- if (ci->type == UAEDEV_DIR) {
- bool add_extra = false;
- if (ci->inject_icons) {
- add_extra = true;
- }
- if (add_extra) {
- _stprintf(tmp2, _T("%s,inject_icons=%s"), ci->devname, ci->inject_icons ? _T("true") : _T("false"));
- cfgfile_write(f, _T("filesystem_extra"), tmp2);
- }
- }
- xfree (str1b);
- xfree (str1c);
- xfree (str2b);
- }
- }
- static void write_compatibility_cpu (struct zfile *f, struct uae_prefs *p)
- {
- TCHAR tmp[100];
- int model;
- model = p->cpu_model;
- if (model == 68030)
- model = 68020;
- if (model == 68060)
- model = 68040;
- if (p->address_space_24 && model == 68020)
- _tcscpy (tmp, _T("68ec020"));
- else
- _stprintf (tmp, _T("%d"), model);
- if (model == 68020 && (p->fpu_model == 68881 || p->fpu_model == 68882))
- _tcscat (tmp, _T("/68881"));
- cfgfile_write (f, _T("cpu_type"), tmp);
- }
- static void write_leds (struct zfile *f, const TCHAR *name, int mask)
- {
- TCHAR tmp[MAX_DPATH];
- tmp[0] = 0;
- for (int i = 0; leds[i]; i++) {
- bool got = false;
- for (int j = 0; leds[j]; j++) {
- if (leds_order[j] == i) {
- if (mask & (1 << j)) {
- if (got)
- _tcscat (tmp, _T(":"));
- _tcscat (tmp, leds[j]);
- got = true;
- }
- }
- }
- if (leds[i + 1] && got)
- _tcscat (tmp, _T(","));
- }
- while (tmp[0] && tmp[_tcslen (tmp) - 1] == ',')
- tmp[_tcslen (tmp) - 1] = 0;
- cfgfile_dwrite_str (f, name, tmp);
- }
- static void write_resolution (struct zfile *f, const TCHAR *ws, const TCHAR *hs, struct wh *wh)
- {
- if (wh->width <= 0 || wh->height <= 0 || wh->special == WH_NATIVE) {
- cfgfile_write_str (f, ws, _T("native"));
- cfgfile_write_str (f, hs, _T("native"));
- } else {
- cfgfile_write (f, ws, _T("%d"), wh->width);
- cfgfile_write (f, hs, _T("%d"), wh->height);
- }
- }
- static int cfgfile_read_rom_settings(const struct expansionboardsettings *ebs, const TCHAR *buf, TCHAR *configtext)
- {
- int settings = 0;
- int bitcnt = 0;
- int sstr = 0;
- if (configtext)
- configtext[0] = 0;
- TCHAR *ct = configtext;
- for (int i = 0; ebs[i].name; i++) {
- const struct expansionboardsettings *eb = &ebs[i];
- bitcnt += eb->bitshift;
- if (eb->type == EXPANSIONBOARD_STRING) {
- TCHAR *p = cfgfile_option_get(buf, eb->configname);
- if (p) {
- _tcscpy(ct, p);
- ct += _tcslen(ct);
- xfree(p);
- }
- *ct++ = 0;
- } else if (eb->type == EXPANSIONBOARD_MULTI) {
- int itemcnt = -1;
- int itemfound = 0;
- const TCHAR *p = eb->configname;
- while (p[0]) {
- if (itemcnt >= 0) {
- if (cfgfile_option_find(buf, p)) {
- itemfound = itemcnt;
- }
- }
- itemcnt++;
- p += _tcslen(p) + 1;
- }
- int cnt = 1;
- int bits = 1;
- for (int i = 0; i < 8; i++) {
- if ((1 << i) >= itemcnt) {
- cnt = 1 << i;
- bits = i;
- break;
- }
- }
- int multimask = cnt - 1;
- if (eb->invert)
- itemfound ^= 0x7fffffff;
- itemfound &= multimask;
- settings |= itemfound << bitcnt;
- bitcnt += bits;
- } else {
- int mask = 1 << bitcnt;
- if (cfgfile_option_find(buf, eb->configname)) {
- settings |= mask;
- }
- if (eb->invert)
- settings ^= mask;
- bitcnt++;
- }
- }
- return settings;
- }
- static void cfgfile_write_rom_settings(const struct expansionboardsettings *ebs, TCHAR *buf, int settings, const TCHAR *settingstring)
- {
- int bitcnt = 0;
- int sstr = 0;
- for (int j = 0; ebs[j].name; j++) {
- const struct expansionboardsettings *eb = &ebs[j];
- bitcnt += eb->bitshift;
- if (eb->type == EXPANSIONBOARD_STRING) {
- if (settingstring) {
- TCHAR tmp[MAX_DPATH];
- const TCHAR *p = settingstring;
- for (int i = 0; i < sstr; i++) {
- p += _tcslen(p) + 1;
- }
- if (buf[0])
- _tcscat(buf, _T(","));
- TCHAR *cs = cfgfile_escape_min(p);
- _stprintf(tmp, _T("%s=%s"), eb->configname, cs);
- _tcscat(buf, tmp);
- xfree(cs);
- sstr++;
- }
- } else if (eb->type == EXPANSIONBOARD_MULTI) {
- int itemcnt = -1;
- const TCHAR *p = eb->configname;
- while (p[0]) {
- itemcnt++;
- p += _tcslen(p) + 1;
- }
- int cnt = 1;
- int bits = 1;
- for (int i = 0; i < 8; i++) {
- if ((1 << i) >= itemcnt) {
- cnt = 1 << i;
- bits = i;
- break;
- }
- }
- int multimask = cnt - 1;
- int multivalue = settings;
- if (eb->invert)
- multivalue ^= 0x7fffffff;
- multivalue = (multivalue >> bitcnt) & multimask;
- p = eb->configname;
- while (multivalue >= 0) {
- multivalue--;
- p += _tcslen(p) + 1;
- }
- if (buf[0])
- _tcscat(buf, _T(","));
- _tcscat(buf, p);
- bitcnt += bits;
- } else {
- int value = settings;
- if (eb->invert)
- value ^= 0x7fffffff;
- if (value & (1 << bitcnt)) {
- if (buf[0])
- _tcscat(buf, _T(","));
- _tcscat(buf, eb->configname);
- }
- bitcnt++;
- }
- }
- }
- static bool is_custom_romboard(struct boardromconfig *br)
- {
- return ((br->device_type & ROMTYPE_MASK) == ROMTYPE_UAEBOARDZ2 || (br->device_type & ROMTYPE_MASK) == ROMTYPE_UAEBOARDZ3);
- }
- static void cfgfile_write_board_rom(struct uae_prefs *prefs, struct zfile *f, struct multipath *mp, struct boardromconfig *br)
- {
- TCHAR buf[MAX_DPATH];
- TCHAR name[256];
- const struct expansionromtype *ert;
-
- if (br->device_type == 0)
- return;
- ert = get_device_expansion_rom(br->device_type);
- if (!ert)
- return;
- for (int i = 0; i < MAX_BOARD_ROMS; i++) {
- struct romconfig *rc = &br->roms[i];
- if (br->device_num == 0)
- _tcscpy(name, ert->name);
- else
- _stprintf(name, _T("%s-%d"), ert->name, br->device_num + 1);
- if (i == 0 || _tcslen(br->roms[i].romfile)) {
- _stprintf(buf, _T("%s%s_rom_file"), name, i ? _T("_ext") : _T(""));
- cfgfile_write_rom (f, mp, br->roms[i].romfile, buf);
- if (rc->romident[0]) {
- _stprintf(buf, _T("%s%s_rom"), name, i ? _T("_ext") : _T(""));
- cfgfile_dwrite_str (f, buf, rc->romident);
- }
- if (rc->autoboot_disabled || rc->dma24bit || rc->inserted || ert->subtypes || ert->settings || ert->id_jumper || br->device_order > 0 || is_custom_romboard(br)) {
- TCHAR buf2[256], *p;
- buf2[0] = 0;
- p = buf2;
- _stprintf(buf, _T("%s%s_rom_options"), name, i ? _T("_ext") : _T(""));
- if (ert->subtypes) {
- const struct expansionsubromtype *srt = ert->subtypes;
- int k = rc->subtype;
- while (k && srt[1].name) {
- srt++;
- k--;
- }
- _stprintf(p, _T("subtype=%s"), srt->configname);
- }
- if (br->device_order > 0 && prefs->autoconfig_custom_sort) {
- if (buf2[0])
- _tcscat(buf2, _T(","));
- TCHAR *p2 = buf2 + _tcslen(buf2);
- _stprintf(p2, _T("order=%d"), br->device_order);
- }
- if (rc->autoboot_disabled) {
- if (buf2[0])
- _tcscat(buf2, _T(","));
- _tcscat(buf2, _T("autoboot_disabled=true"));
- }
- if (rc->dma24bit) {
- if (buf2[0])
- _tcscat(buf2, _T(","));
- _tcscat(buf2, _T("dma24bit=true"));
- }
- if (rc->inserted) {
- if (buf2[0])
- _tcscat(buf2, _T(","));
- _tcscat(buf2, _T("inserted=true"));
- }
- if (ert->id_jumper) {
- TCHAR tmp[256];
- _stprintf(tmp, _T("id=%d"), rc->device_id);
- if (buf2[0])
- _tcscat(buf2, _T(","));
- _tcscat(buf2, tmp);
- }
- if ((rc->device_settings || rc->configtext[0]) && ert->settings) {
- cfgfile_write_rom_settings(ert->settings, buf2, rc->device_settings, rc->configtext);
- }
- if (is_custom_romboard(br)) {
- if (rc->manufacturer) {
- if (buf2[0])
- _tcscat(buf2, _T(","));
- TCHAR *p2 = buf2 + _tcslen(buf2);
- _stprintf(p2, _T("mid=%u,pid=%u"), rc->manufacturer, rc->product);
- }
- if (rc->autoconfig[0]) {
- uae_u8 *ac = rc->autoconfig;
- if (buf2[0])
- _tcscat(buf2, _T(","));
- TCHAR *p2 = buf2 + _tcslen(buf2);
- _stprintf(p2, _T("data=%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x"),
- ac[0], ac[1], ac[2], ac[3], ac[4], ac[5], ac[6], ac[7],
- ac[8], ac[9], ac[10], ac[11], ac[12], ac[13], ac[14], ac[15]);
- }
- }
- if (buf2[0])
- cfgfile_dwrite_str (f, buf, buf2);
- }
- if (rc->board_ram_size) {
- _stprintf(buf, _T("%s%s_mem_size"), name, i ? _T("_ext") : _T(""));
- cfgfile_write(f, buf, _T("%d"), rc->board_ram_size / 0x40000);
- }
- }
- }
- }
- static bool cfgfile_readromboard(const TCHAR *option, const TCHAR *value, struct romboard *rbp)
- {
- TCHAR tmp1[MAX_DPATH];
- for (int i = 0; i < MAX_ROM_BOARDS; i++) {
- struct romboard *rb = &rbp[i];
- if (i > 0)
- _stprintf(tmp1, _T("romboard%d_options"), i + 1);
- else
- _tcscpy(tmp1, _T("romboard_options"));
- if (!_tcsicmp(option, tmp1)) {
- TCHAR *endptr;
- TCHAR *s1, *s2;
- s1 = cfgfile_option_get(value, _T("start"));
- s2 = cfgfile_option_get(value, _T("…
Large files files are truncated, but you can click here to view the full file