PageRenderTime 136ms CodeModel.GetById 40ms RepoModel.GetById 1ms app.codeStats 1ms

/cfgfile.cpp

https://github.com/tonioni/WinUAE
C++ | 9417 lines | 8976 code | 382 blank | 59 comment | 2086 complexity | 1b238f847b3d1b80686f2250433573d4 MD5 | raw file
  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. #include "sysconfig.h"
  10. #include "sysdeps.h"
  11. #include <ctype.h>
  12. #include "options.h"
  13. #include "uae.h"
  14. #include "audio.h"
  15. #include "events.h"
  16. #include "custom.h"
  17. #include "inputdevice.h"
  18. #include "gfxfilter.h"
  19. #include "savestate.h"
  20. #include "memory.h"
  21. #include "autoconf.h"
  22. #include "rommgr.h"
  23. #include "gui.h"
  24. #include "newcpu.h"
  25. #include "zfile.h"
  26. #include "filesys.h"
  27. #include "fsdb.h"
  28. #include "disk.h"
  29. #include "blkdev.h"
  30. #include "statusline.h"
  31. #include "debug.h"
  32. #include "calc.h"
  33. #include "gfxboard.h"
  34. #include "cpuboard.h"
  35. #include "luascript.h"
  36. #include "ethernet.h"
  37. #include "native2amiga_api.h"
  38. #include "ini.h"
  39. #include "specialmonitors.h"
  40. #define cfgfile_warning write_log
  41. #define cfgfile_warning_obsolete write_log
  42. #if SIZEOF_TCHAR != 1
  43. /* FIXME: replace strcasecmp with _tcsicmp in source code instead */
  44. #undef strcasecmp
  45. #define strcasecmp _tcsicmp
  46. #endif
  47. static int config_newfilesystem;
  48. static struct strlist *temp_lines;
  49. static struct strlist *error_lines;
  50. static struct zfile *default_file, *configstore;
  51. static int uaeconfig;
  52. static int unicode_config = 0;
  53. /* @@@ need to get rid of this... just cut part of the manual and print that
  54. * as a help text. */
  55. struct cfg_lines
  56. {
  57. const TCHAR *config_label, *config_help;
  58. };
  59. static const struct cfg_lines opttable[] =
  60. {
  61. {_T("help"), _T("Prints this help") },
  62. {_T("config_description"), _T("") },
  63. {_T("config_info"), _T("") },
  64. {_T("use_gui"), _T("Enable the GUI? If no, then goes straight to emulator") },
  65. {_T("use_debugger"), _T("Enable the debugger?") },
  66. {_T("cpu_speed"), _T("can be max, real, or a number between 1 and 20") },
  67. {_T("cpu_model"), _T("Can be 68000, 68010, 68020, 68030, 68040, 68060") },
  68. {_T("fpu_model"), _T("Can be 68881, 68882, 68040, 68060") },
  69. {_T("cpu_compatible"), _T("yes enables compatibility-mode") },
  70. {_T("cpu_24bit_addressing"), _T("must be set to 'no' in order for Z3mem or P96mem to work") },
  71. {_T("autoconfig"), _T("yes = add filesystems and extra ram") },
  72. {_T("log_illegal_mem"), _T("print illegal memory access by Amiga software?") },
  73. {_T("fastmem_size"), _T("Size in megabytes of fast-memory") },
  74. {_T("chipmem_size"), _T("Size in megabytes of chip-memory") },
  75. {_T("bogomem_size"), _T("Size in megabytes of bogo-memory at 0xC00000") },
  76. {_T("a3000mem_size"), _T("Size in megabytes of A3000 memory") },
  77. {_T("gfxcard_size"), _T("Size in megabytes of Picasso96 graphics-card memory") },
  78. {_T("z3mem_size"), _T("Size in megabytes of Zorro-III expansion memory") },
  79. {_T("gfx_test_speed"), _T("Test graphics speed?") },
  80. {_T("gfx_framerate"), _T("Print every nth frame") },
  81. {_T("gfx_width"), _T("Screen width") },
  82. {_T("gfx_height"), _T("Screen height") },
  83. {_T("gfx_refreshrate"), _T("Fullscreen refresh rate") },
  84. {_T("gfx_vsync"), _T("Sync screen refresh to refresh rate") },
  85. {_T("gfx_lores"), _T("Treat display as lo-res?") },
  86. {_T("gfx_linemode"), _T("Can be none, double, or scanlines") },
  87. {_T("gfx_fullscreen_amiga"), _T("Amiga screens are fullscreen?") },
  88. {_T("gfx_fullscreen_picasso"), _T("Picasso screens are fullscreen?") },
  89. {_T("gfx_center_horizontal"), _T("Center display horizontally?") },
  90. {_T("gfx_center_vertical"), _T("Center display vertically?") },
  91. {_T("gfx_colour_mode"), _T("") },
  92. {_T("32bit_blits"), _T("Enable 32 bit blitter emulation") },
  93. {_T("immediate_blits"), _T("Perform blits immediately") },
  94. {_T("show_leds"), _T("LED display") },
  95. {_T("keyboard_leds"), _T("Keyboard LEDs") },
  96. {_T("gfxlib_replacement"), _T("Use graphics.library replacement?") },
  97. {_T("sound_output"), _T("") },
  98. {_T("sound_frequency"), _T("") },
  99. {_T("sound_bits"), _T("") },
  100. {_T("sound_channels"), _T("") },
  101. {_T("sound_max_buff"), _T("") },
  102. {_T("comp_trustbyte"), _T("How to access bytes in compiler (direct/indirect/indirectKS/afterPic") },
  103. {_T("comp_trustword"), _T("How to access words in compiler (direct/indirect/indirectKS/afterPic") },
  104. {_T("comp_trustlong"), _T("How to access longs in compiler (direct/indirect/indirectKS/afterPic") },
  105. {_T("comp_nf"), _T("Whether to optimize away flag generation where possible") },
  106. {_T("comp_fpu"), _T("Whether to provide JIT FPU emulation") },
  107. {_T("cachesize"), _T("How many MB to use to buffer translated instructions")},
  108. {_T("override_dga_address"),_T("Address from which to map the frame buffer (upper 16 bits) (DANGEROUS!)")},
  109. {_T("avoid_dga"), _T("Set to yes if the use of DGA extension creates problems") },
  110. {_T("avoid_vid"), _T("Set to yes if the use of the Vidmode extension creates problems") },
  111. {_T("parallel_on_demand"), _T("") },
  112. {_T("serial_on_demand"), _T("") },
  113. {_T("scsi"), _T("scsi.device emulation") },
  114. {_T("joyport0"), _T("") },
  115. {_T("joyport1"), _T("") },
  116. {_T("pci_devices"), _T("List of PCI devices to make visible to the emulated Amiga") },
  117. {_T("kickstart_rom_file"), _T("Kickstart ROM image, (C) Copyright Amiga, Inc.") },
  118. {_T("kickstart_ext_rom_file"), _T("Extended Kickstart ROM image, (C) Copyright Amiga, Inc.") },
  119. {_T("kickstart_key_file"), _T("Key-file for encrypted ROM images (from Cloanto's Amiga Forever)") },
  120. {_T("flash_ram_file"), _T("Flash/battery backed RAM image file.") },
  121. {_T("cart_file"), _T("Freezer cartridge ROM image file.") },
  122. {_T("floppy0"), _T("Diskfile for drive 0") },
  123. {_T("floppy1"), _T("Diskfile for drive 1") },
  124. {_T("floppy2"), _T("Diskfile for drive 2") },
  125. {_T("floppy3"), _T("Diskfile for drive 3") },
  126. {_T("hardfile"), _T("access,sectors, surfaces, reserved, blocksize, path format") },
  127. {_T("filesystem"), _T("access,'Amiga volume-name':'host directory path' - where 'access' can be 'read-only' or 'read-write'") },
  128. {_T("catweasel"), _T("Catweasel board io base address") }
  129. };
  130. static const TCHAR *guimode1[] = { _T("no"), _T("yes"), _T("nowait"), 0 };
  131. static const TCHAR *guimode2[] = { _T("false"), _T("true"), _T("nowait"), 0 };
  132. static const TCHAR *guimode3[] = { _T("0"), _T("1"), _T("nowait"), 0 };
  133. static const TCHAR *csmode[] = { _T("ocs"), _T("ecs_agnus"), _T("ecs_denise"), _T("ecs"), _T("aga"), 0 };
  134. static const TCHAR *linemode[] = {
  135. _T("none"),
  136. _T("double"), _T("scanlines"), _T("scanlines2p"), _T("scanlines3p"),
  137. _T("double2"), _T("scanlines2"), _T("scanlines2p2"), _T("scanlines2p3"),
  138. _T("double3"), _T("scanlines3"), _T("scanlines3p2"), _T("scanlines3p3"),
  139. 0 };
  140. static const TCHAR *speedmode[] = { _T("max"), _T("real"), 0 };
  141. static const TCHAR *colormode1[] = { _T("8bit"), _T("15bit"), _T("16bit"), _T("8bit_dither"), _T("4bit_dither"), _T("32bit"), 0 };
  142. static const TCHAR *colormode2[] = { _T("8"), _T("15"), _T("16"), _T("8d"), _T("4d"), _T("32"), 0 };
  143. static const TCHAR *soundmode1[] = { _T("none"), _T("interrupts"), _T("normal"), _T("exact"), 0 };
  144. static const TCHAR *soundmode2[] = { _T("none"), _T("interrupts"), _T("good"), _T("best"), 0 };
  145. static const TCHAR *centermode1[] = { _T("none"), _T("simple"), _T("smart"), 0 };
  146. static const TCHAR *centermode2[] = { _T("false"), _T("true"), _T("smart"), 0 };
  147. static const TCHAR *stereomode[] = { _T("mono"), _T("stereo"), _T("clonedstereo"), _T("4ch"), _T("clonedstereo6ch"), _T("6ch"), _T("mixed"), 0 };
  148. static const TCHAR *interpolmode[] = { _T("none"), _T("anti"), _T("sinc"), _T("rh"), _T("crux"), 0 };
  149. static const TCHAR *collmode[] = { _T("none"), _T("sprites"), _T("playfields"), _T("full"), 0 };
  150. static const TCHAR *compmode[] = { _T("direct"), _T("indirect"), _T("indirectKS"), _T("afterPic"), 0 };
  151. static const TCHAR *flushmode[] = { _T("soft"), _T("hard"), 0 };
  152. static const TCHAR *kbleds[] = { _T("none"), _T("POWER"), _T("DF0"), _T("DF1"), _T("DF2"), _T("DF3"), _T("HD"), _T("CD"), _T("DFx"), 0 };
  153. static const TCHAR *onscreenleds[] = { _T("false"), _T("true"), _T("rtg"), _T("both"), 0 };
  154. static const TCHAR *soundfiltermode1[] = { _T("off"), _T("emulated"), _T("on"), 0 };
  155. static const TCHAR *soundfiltermode2[] = { _T("standard"), _T("enhanced"), 0 };
  156. static const TCHAR *lorestype1[] = { _T("lores"), _T("hires"), _T("superhires"), 0 };
  157. static const TCHAR *lorestype2[] = { _T("true"), _T("false"), 0 };
  158. static const TCHAR *loresmode[] = { _T("normal"), _T("filtered"), 0 };
  159. static const TCHAR *horizmode[] = { _T("vertical"), _T("lores"), _T("hires"), _T("superhires"), 0 };
  160. static const TCHAR *vertmode[] = { _T("horizontal"), _T("single"), _T("double"), _T("quadruple"), 0 };
  161. #ifdef GFXFILTER
  162. static const TCHAR *filtermode2[] = { _T("1x"), _T("2x"), _T("3x"), _T("4x"), 0 };
  163. static const TCHAR *filtermode2v[] = { _T("-"), _T("1x"), _T("2x"), _T("3x"), _T("4x"), 0 };
  164. #endif
  165. static const TCHAR *cartsmode[] = { _T("none"), _T("hrtmon"), 0 };
  166. static const TCHAR *idemode[] = { _T("none"), _T("a600/a1200"), _T("a4000"), 0 };
  167. static const TCHAR *rtctype[] = { _T("none"), _T("MSM6242B"), _T("RP5C01A"), _T("MSM6242B_A2000"), 0 };
  168. static const TCHAR *ciaatodmode[] = { _T("vblank"), _T("50hz"), _T("60hz"), 0 };
  169. static const TCHAR *ksmirrortype[] = { _T("none"), _T("e0"), _T("a8+e0"), 0 };
  170. static const TCHAR *cscompa[] = {
  171. _T("-"), _T("Generic"), _T("CDTV"), _T("CDTV-CR"), _T("CD32"), _T("A500"), _T("A500+"), _T("A600"),
  172. _T("A1000"), _T("A1200"), _T("A2000"), _T("A3000"), _T("A3000T"), _T("A4000"), _T("A4000T"),
  173. _T("Velvet"), _T("Casablanca"), _T("DraCo"),
  174. NULL
  175. };
  176. static const TCHAR *qsmodes[] = {
  177. _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 };
  178. /* 3-state boolean! */
  179. static const TCHAR *fullmodes[] = { _T("false"), _T("true"), /* "FILE_NOT_FOUND", */ _T("fullwindow"), 0 };
  180. /* bleh for compatibility */
  181. static const TCHAR *scsimode[] = { _T("false"), _T("true"), _T("scsi"), 0 };
  182. static const TCHAR *maxhoriz[] = { _T("lores"), _T("hires"), _T("superhires"), 0 };
  183. static const TCHAR *maxvert[] = { _T("nointerlace"), _T("interlace"), 0 };
  184. static const TCHAR *abspointers[] = { _T("none"), _T("mousehack"), _T("tablet"), 0 };
  185. static const TCHAR *magiccursors[] = { _T("both"), _T("native"), _T("host"), 0 };
  186. static const TCHAR *autoscale[] = { _T("none"), _T("auto"), _T("standard"), _T("max"), _T("scale"), _T("resize"), _T("center"), _T("manual"),
  187. _T("integer"), _T("integer_auto"), _T("separator"), _T("overscan_blanking"), 0 };
  188. static const TCHAR *autoscale_rtg[] = { _T("resize"), _T("scale"), _T("center"), _T("integer"), 0 };
  189. static const TCHAR *autoscalelimit[] = { _T("1/1"), _T("1/2"), _T("1/4"), _T("1/8"), 0 };
  190. static const TCHAR *joyportmodes[] = { _T(""), _T("mouse"), _T("mousenowheel"), _T("djoy"), _T("gamepad"), _T("ajoy"), _T("cdtvjoy"), _T("cd32joy"), _T("lightpen"), 0 };
  191. static const TCHAR *joyportsubmodes_lightpen[] = { _T(""), _T("trojan"), 0 };
  192. static const TCHAR *joyaf[] = { _T("none"), _T("normal"), _T("toggle"), _T("always"), 0 };
  193. static const TCHAR *epsonprinter[] = { _T("none"), _T("ascii"), _T("epson_matrix_9pin"), _T("epson_matrix_24pin"), _T("epson_matrix_48pin"), 0 };
  194. static const TCHAR *aspects[] = { _T("none"), _T("vga"), _T("tv"), 0 };
  195. static const TCHAR *vsyncmodes[] = { _T("false"), _T("true"), _T("autoswitch"), 0 };
  196. static const TCHAR *vsyncmodes2[] = { _T("normal"), _T("busywait"), 0 };
  197. static const TCHAR *filterapi[] = { _T("directdraw"), _T("direct3d"), _T("direct3d11"), _T("direct3d11"), 0};
  198. static const TCHAR *filterapiopts[] = { _T("hardware"), _T("software"), 0 };
  199. static const TCHAR *overscanmodes[] = { _T("tv_narrow"), _T("tv_standard"), _T("tv_wide"), _T("overscan"), _T("broadcast"), _T("extreme"), NULL };
  200. static const TCHAR *dongles[] =
  201. {
  202. _T("none"),
  203. _T("robocop 3"), _T("leaderboard"), _T("b.a.t. ii"), _T("italy'90 soccer"), _T("dames grand maitre"),
  204. _T("rugby coach"), _T("cricket captain"), _T("leviathan"), _T("musicmaster"),
  205. _T("logistics"), _T("scala red"), _T("scala green"),
  206. NULL
  207. };
  208. static const TCHAR *cdmodes[] = { _T("disabled"), _T(""), _T("image"), _T("ioctl"), _T("spti"), _T("aspi"), 0 };
  209. static const TCHAR *cdconmodes[] = { _T(""), _T("uae"), _T("ide"), _T("scsi"), _T("cdtv"), _T("cd32"), 0 };
  210. 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 };
  211. static const TCHAR *ppc_implementations[] = {
  212. _T("auto"),
  213. _T("dummy"),
  214. _T("pearpc"),
  215. _T("qemu"),
  216. NULL
  217. };
  218. static const TCHAR *ppc_cpu_idle[] = {
  219. _T("disabled"),
  220. _T("1"),
  221. _T("2"),
  222. _T("3"),
  223. _T("4"),
  224. _T("5"),
  225. _T("6"),
  226. _T("7"),
  227. _T("8"),
  228. _T("9"),
  229. _T("max"),
  230. NULL
  231. };
  232. static const TCHAR *waitblits[] = { _T("disabled"), _T("automatic"), _T("noidleonly"), _T("always"), 0 };
  233. static const TCHAR *autoext2[] = { _T("disabled"), _T("copy"), _T("replace"), 0 };
  234. 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 };
  235. static const int leds_order[] = { 3, 6, 7, 8, 9, 4, 5, 2, 1, 0, 9, 10 };
  236. static const TCHAR *lacer[] = { _T("off"), _T("i"), _T("p"), 0 };
  237. /* another boolean to choice update.. */
  238. static const TCHAR *cycleexact[] = { _T("false"), _T("memory"), _T("true"), 0 };
  239. static const TCHAR *unmapped[] = { _T("floating"), _T("zero"), _T("one"), 0 };
  240. static const TCHAR *ciatype[] = { _T("default"), _T("391078-01"), 0 };
  241. static const TCHAR *debugfeatures[] = { _T("segtracker"), _T("fsdebug"), 0 };
  242. struct hdcontrollerconfig
  243. {
  244. const TCHAR *label;
  245. int romtype;
  246. };
  247. static const struct hdcontrollerconfig hdcontrollers[] = {
  248. { _T("uae"), 0 },
  249. { _T("ide%d"), 0 },
  250. { _T("ide%d_mainboard"), ROMTYPE_MB_IDE },
  251. { _T("scsi%d"), 0 },
  252. { _T("scsi%d_a3000"), ROMTYPE_SCSI_A3000 },
  253. { _T("scsi%d_a4000t"), ROMTYPE_SCSI_A4000T },
  254. { _T("scsi%d_cdtv"), ROMTYPE_CDTVSCSI },
  255. { NULL }
  256. };
  257. static const TCHAR *z3mapping[] = {
  258. _T("auto"),
  259. _T("uae"),
  260. _T("real"),
  261. NULL
  262. };
  263. static const TCHAR *uaescsidevmodes[] = {
  264. _T("original"),
  265. _T("rename_scsi"),
  266. NULL
  267. };
  268. static const TCHAR *uaebootrom[] = {
  269. _T("automatic"),
  270. _T("disabled"),
  271. _T("min"),
  272. _T("full"),
  273. NULL
  274. };
  275. static const TCHAR *uaeboard[] = {
  276. _T("disabled"),
  277. _T("min"),
  278. _T("full"),
  279. _T("full+indirect"),
  280. NULL
  281. };
  282. static const TCHAR *uaeboard_off[] = {
  283. _T("disabled_off"),
  284. _T("min_off"),
  285. _T("full_off"),
  286. _T("full+indirect_off"),
  287. NULL
  288. };
  289. static const TCHAR *serialcrlf[] = {
  290. _T("disabled"),
  291. _T("crlf_cr"),
  292. NULL
  293. };
  294. static const TCHAR *threebitcolors[] = {
  295. _T("disabled"),
  296. _T("3to4to8bit"),
  297. _T("3to4bit"),
  298. _T("3to8bit"),
  299. NULL
  300. };
  301. static const TCHAR *obsolete[] = {
  302. _T("accuracy"), _T("gfx_opengl"), _T("gfx_32bit_blits"), _T("32bit_blits"),
  303. _T("gfx_immediate_blits"), _T("gfx_ntsc"), _T("win32"), _T("gfx_filter_bits"),
  304. _T("sound_pri_cutoff"), _T("sound_pri_time"), _T("sound_min_buff"), _T("sound_bits"),
  305. _T("gfx_test_speed"), _T("gfxlib_replacement"), _T("enforcer"), _T("catweasel_io"),
  306. _T("kickstart_key_file"), _T("fast_copper"), _T("sound_adjust"), _T("sound_latency"),
  307. _T("serial_hardware_dtrdsr"), _T("gfx_filter_upscale"),
  308. _T("gfx_correct_aspect"), _T("gfx_autoscale"), _T("parallel_sampler"), _T("parallel_ascii_emulation"),
  309. _T("avoid_vid"), _T("avoid_dga"), _T("z3chipmem_size"), _T("state_replay_buffer"), _T("state_replay"),
  310. _T("z3realmapping"), _T("force_0x10000000_z3"),
  311. _T("fpu_arithmetic_exceptions"),
  312. _T("gfx_filter_vert_zoom"),_T("gfx_filter_horiz_zoom"),
  313. _T("gfx_filter_vert_zoom_mult"), _T("gfx_filter_horiz_zoom_mult"),
  314. _T("gfx_filter_vert_offset"), _T("gfx_filter_horiz_offset"),
  315. _T("gfx_tearing"), _T("gfx_tearing_rtg"),
  316. // created by some buggy beta
  317. _T("uaehf0%s,%s"),
  318. _T("uaehf1%s,%s"),
  319. _T("uaehf2%s,%s"),
  320. _T("uaehf3%s,%s"),
  321. _T("uaehf4%s,%s"),
  322. _T("uaehf5%s,%s"),
  323. _T("uaehf6%s,%s"),
  324. _T("uaehf7%s,%s"),
  325. _T("pcibridge_rom_file"),
  326. _T("pcibridge_rom_options"),
  327. _T("cpuboard_ext_rom_file"),
  328. _T("uaeboard_mode"),
  329. _T("comp_oldsegv"),
  330. _T("comp_midopt"),
  331. _T("comp_lowopt"),
  332. _T("avoid_cmov"),
  333. _T("compforcesettings"),
  334. _T("comp_catchdetect"),
  335. _T("hblank_glitch"),
  336. _T("gfx_hdr"),
  337. NULL
  338. };
  339. #define UNEXPANDED _T("$(FILE_PATH)")
  340. static TCHAR *cfgfile_unescape(const TCHAR *s, const TCHAR **endpos, TCHAR separator, bool min)
  341. {
  342. bool quoted = false;
  343. TCHAR *s2 = xmalloc(TCHAR, _tcslen(s) + 1);
  344. TCHAR *p = s2;
  345. if (s[0] == '\"') {
  346. s++;
  347. quoted = true;
  348. }
  349. int i;
  350. for (i = 0; s[i]; i++) {
  351. TCHAR c = s[i];
  352. if (quoted && c == '\"') {
  353. i++;
  354. break;
  355. }
  356. if (c == separator) {
  357. i++;
  358. break;
  359. }
  360. if (c == '\\' && !min) {
  361. char v = 0;
  362. TCHAR c2;
  363. c = s[i + 1];
  364. switch (c)
  365. {
  366. case 'X':
  367. case 'x':
  368. c2 = _totupper(s[i + 2]);
  369. v = ((c2 >= 'A') ? c2 - 'A' : c2 - '0') << 4;
  370. c2 = _totupper(s[i + 3]);
  371. v |= (c2 >= 'A') ? c2 - 'A' : c2 - '0';
  372. *p++ = c2;
  373. i += 2;
  374. break;
  375. case 'r':
  376. *p++ = '\r';
  377. break;
  378. case '\n':
  379. *p++ = '\n';
  380. break;
  381. default:
  382. *p++ = c;
  383. break;
  384. }
  385. i++;
  386. }
  387. else {
  388. *p++ = c;
  389. }
  390. }
  391. *p = 0;
  392. if (endpos)
  393. *endpos = &s[i];
  394. return s2;
  395. }
  396. static TCHAR *cfgfile_unescape(const TCHAR *s, const TCHAR **endpos)
  397. {
  398. return cfgfile_unescape(s, endpos, 0, false);
  399. }
  400. static TCHAR *cfgfile_unescape_min(const TCHAR *s)
  401. {
  402. return cfgfile_unescape(s, NULL, 0, true);
  403. }
  404. static TCHAR *cfgfile_option_find_it(const TCHAR *s, const TCHAR *option, bool checkequals)
  405. {
  406. TCHAR buf[MAX_DPATH];
  407. if (!s)
  408. return NULL;
  409. _tcscpy(buf, s);
  410. _tcscat(buf, _T(","));
  411. TCHAR *p = buf;
  412. for (;;) {
  413. TCHAR *tmpp = _tcschr(p, ',');
  414. TCHAR *tmpp2 = NULL;
  415. if (tmpp == NULL)
  416. return NULL;
  417. *tmpp++ = 0;
  418. if (checkequals) {
  419. tmpp2 = _tcschr(p, '=');
  420. if (tmpp2)
  421. *tmpp2++ = 0;
  422. }
  423. if (!strcasecmp(p, option)) {
  424. if (checkequals && tmpp2) {
  425. if (tmpp2[0] == '"') {
  426. TCHAR *n = cfgfile_unescape_min(tmpp2);
  427. return n;
  428. }
  429. return my_strdup(tmpp2);
  430. }
  431. return my_strdup(p);
  432. }
  433. p = tmpp;
  434. }
  435. }
  436. bool cfgfile_option_find(const TCHAR *s, const TCHAR *option)
  437. {
  438. TCHAR *ss = cfgfile_option_find_it(s, option, false);
  439. xfree(ss);
  440. return ss != NULL;
  441. }
  442. TCHAR *cfgfile_option_get(const TCHAR *s, const TCHAR *option)
  443. {
  444. return cfgfile_option_find_it(s, option, true);
  445. }
  446. bool cfgfile_option_get_bool(const TCHAR* s, const TCHAR* option)
  447. {
  448. TCHAR *d = cfgfile_option_find_it(s, option, true);
  449. bool ret = d && (!_tcsicmp(d, _T("true")) || !_tcsicmp(d, _T("1")));
  450. xfree(d);
  451. return ret;
  452. }
  453. static void trimwsa (char *s)
  454. {
  455. /* Delete trailing whitespace. */
  456. int len = strlen (s);
  457. while (len > 0 && strcspn (s + len - 1, "\t \r\n") == 0)
  458. s[--len] = '\0';
  459. }
  460. static int match_string (const TCHAR *table[], const TCHAR *str)
  461. {
  462. int i;
  463. for (i = 0; table[i] != 0; i++)
  464. if (strcasecmp (table[i], str) == 0)
  465. return i;
  466. return -1;
  467. }
  468. // escape config file separators and control characters
  469. static TCHAR *cfgfile_escape (const TCHAR *s, const TCHAR *escstr, bool quote)
  470. {
  471. bool doquote = false;
  472. int cnt = 0;
  473. for (int i = 0; s[i]; i++) {
  474. TCHAR c = s[i];
  475. if (c == 0)
  476. break;
  477. if (c < 32 || c == '\\' || c == '\"' || c == '\'') {
  478. cnt++;
  479. }
  480. for (int j = 0; escstr && escstr[j]; j++) {
  481. if (c == escstr[j]) {
  482. cnt++;
  483. if (quote) {
  484. doquote = true;
  485. cnt++;
  486. }
  487. }
  488. }
  489. // always quote if starts or ends with space
  490. if (c == ' ' && (s[i + 1] == 0 || i == 0)) {
  491. doquote = true;
  492. }
  493. }
  494. if (escstr == NULL && quote)
  495. doquote = true;
  496. TCHAR *s2 = xmalloc (TCHAR, _tcslen (s) + cnt * 4 + 2 + 1);
  497. TCHAR *p = s2;
  498. if (doquote)
  499. *p++ = '\"';
  500. for (int i = 0; s[i]; i++) {
  501. TCHAR c = s[i];
  502. if (c == 0)
  503. break;
  504. if (c == '\\' || c == '\"' || c == '\'') {
  505. *p++ = '\\';
  506. *p++ = c;
  507. } else if (c >= 32 && !quote) {
  508. bool escaped = false;
  509. for (int j = 0; escstr && escstr[j]; j++) {
  510. if (c == escstr[j]) {
  511. *p++ = '\\';
  512. *p++ = c;
  513. escaped = true;
  514. break;
  515. }
  516. }
  517. if (!escaped)
  518. *p++ = c;
  519. } else if (c < 32) {
  520. *p++ = '\\';
  521. switch (c)
  522. {
  523. case '\t':
  524. *p++ = 't';
  525. break;
  526. case '\n':
  527. *p++ = 'n';
  528. break;
  529. case '\r':
  530. *p++ = 'r';
  531. break;
  532. default:
  533. *p++ = 'x';
  534. *p++ = (c >> 4) >= 10 ? (c >> 4) + 'a' : (c >> 4) + '0';
  535. *p++ = (c & 15) >= 10 ? (c & 15) + 'a' : (c & 15) + '0';
  536. break;
  537. }
  538. } else {
  539. *p++ = c;
  540. }
  541. }
  542. if (doquote)
  543. *p++ = '\"';
  544. *p = 0;
  545. return s2;
  546. }
  547. // escapy only , and " or if starts or ends with a space
  548. static TCHAR *cfgfile_escape_min(const TCHAR *s)
  549. {
  550. for (int i = 0; s[i]; i++) {
  551. TCHAR c = s[i];
  552. if (c == ',' || c == '\"' || (c == ' ' && (i == 0 || s[i + 1] == 0))) {
  553. return cfgfile_escape(s, _T(","), true);
  554. }
  555. }
  556. return my_strdup(s);
  557. }
  558. static TCHAR *getnextentry (const TCHAR **valuep, const TCHAR separator)
  559. {
  560. TCHAR *s;
  561. const TCHAR *value = *valuep;
  562. if (value[0] == '\"') {
  563. s = cfgfile_unescape (value, valuep);
  564. value = *valuep;
  565. if (*value != 0 && *value != separator) {
  566. xfree (s);
  567. return NULL;
  568. }
  569. value++;
  570. *valuep = value;
  571. } else {
  572. s = cfgfile_unescape (value, valuep, separator, false);
  573. }
  574. return s;
  575. }
  576. static TCHAR *cfgfile_subst_path2 (const TCHAR *path, const TCHAR *subst, const TCHAR *file)
  577. {
  578. /* @@@ use strcasecmp for some targets. */
  579. if (path != NULL && subst != NULL && _tcslen (path) > 0 && _tcsncmp (file, path, _tcslen (path)) == 0) {
  580. int l;
  581. TCHAR *p2, *p = xmalloc (TCHAR, _tcslen (file) + _tcslen (subst) + 2);
  582. _tcscpy (p, subst);
  583. l = _tcslen (p);
  584. while (l > 0 && p[l - 1] == '/')
  585. p[--l] = '\0';
  586. l = _tcslen (path);
  587. while (file[l] == '/')
  588. l++;
  589. _tcscat (p, _T("/"));
  590. _tcscat (p, file + l);
  591. p2 = target_expand_environment (p, NULL, 0);
  592. xfree (p);
  593. if (p2 && p2[0] == '$') {
  594. xfree(p2);
  595. return NULL;
  596. }
  597. return p2;
  598. }
  599. return NULL;
  600. }
  601. TCHAR *cfgfile_subst_path (const TCHAR *path, const TCHAR *subst, const TCHAR *file)
  602. {
  603. TCHAR *s = cfgfile_subst_path2 (path, subst, file);
  604. if (s)
  605. return s;
  606. s = target_expand_environment (file, NULL, 0);
  607. if (s) {
  608. TCHAR tmp[MAX_DPATH];
  609. _tcscpy (tmp, s);
  610. xfree (s);
  611. fullpath (tmp, sizeof tmp / sizeof (TCHAR));
  612. s = my_strdup (tmp);
  613. }
  614. return s;
  615. }
  616. static TCHAR *cfgfile_get_multipath2 (struct multipath *mp, const TCHAR *path, const TCHAR *file, bool dir)
  617. {
  618. for (int i = 0; i < MAX_PATHS; i++) {
  619. if (mp->path[i][0] && _tcscmp (mp->path[i], _T(".\\")) != 0 && _tcscmp (mp->path[i], _T("./")) != 0 && (file[0] != '/' && file[0] != '\\' && !_tcschr(file, ':'))) {
  620. TCHAR *s = NULL;
  621. if (path)
  622. s = cfgfile_subst_path2 (path, mp->path[i], file);
  623. if (!s) {
  624. TCHAR np[MAX_DPATH];
  625. _tcscpy (np, mp->path[i]);
  626. fixtrailing (np);
  627. _tcscat (np, file);
  628. fullpath (np, sizeof np / sizeof (TCHAR));
  629. s = my_strdup (np);
  630. }
  631. if (dir) {
  632. if (my_existsdir (s))
  633. return s;
  634. } else {
  635. if (zfile_exists (s))
  636. return s;
  637. }
  638. xfree (s);
  639. }
  640. }
  641. return NULL;
  642. }
  643. static TCHAR *cfgfile_get_multipath (struct multipath *mp, const TCHAR *path, const TCHAR *file, bool dir)
  644. {
  645. TCHAR *s = cfgfile_get_multipath2 (mp, path, file, dir);
  646. if (s)
  647. return s;
  648. return my_strdup (file);
  649. }
  650. static TCHAR *cfgfile_put_multipath (struct multipath *mp, const TCHAR *s)
  651. {
  652. for (int i = 0; i < MAX_PATHS; i++) {
  653. if (mp->path[i][0] && _tcscmp (mp->path[i], _T(".\\")) != 0 && _tcscmp (mp->path[i], _T("./")) != 0) {
  654. if (_tcsnicmp (mp->path[i], s, _tcslen (mp->path[i])) == 0) {
  655. return my_strdup (s + _tcslen (mp->path[i]));
  656. }
  657. }
  658. }
  659. return my_strdup (s);
  660. }
  661. static TCHAR *cfgfile_subst_path_load (const TCHAR *path, struct multipath *mp, const TCHAR *file, bool dir)
  662. {
  663. TCHAR *s = cfgfile_get_multipath2 (mp, path, file, dir);
  664. if (s)
  665. return s;
  666. return cfgfile_subst_path (path, mp->path[0], file);
  667. }
  668. static bool isdefault (const TCHAR *s)
  669. {
  670. TCHAR tmp[MAX_DPATH];
  671. if (!default_file || uaeconfig)
  672. return false;
  673. zfile_fseek (default_file, 0, SEEK_SET);
  674. while (zfile_fgets (tmp, sizeof tmp / sizeof (TCHAR), default_file)) {
  675. if (tmp[0] && tmp[_tcslen (tmp) - 1] == '\n')
  676. tmp[_tcslen (tmp) - 1] = 0;
  677. if (!_tcscmp (tmp, s))
  678. return true;
  679. }
  680. return false;
  681. }
  682. static size_t cfg_write (const void *b, struct zfile *z)
  683. {
  684. size_t v;
  685. if (unicode_config) {
  686. TCHAR lf = 10;
  687. v = zfile_fwrite (b, _tcslen ((TCHAR*)b), sizeof (TCHAR), z);
  688. zfile_fwrite (&lf, 1, 1, z);
  689. } else {
  690. char lf = 10;
  691. char *s = ua ((TCHAR*)b);
  692. v = zfile_fwrite (s, strlen (s), 1, z);
  693. zfile_fwrite (&lf, 1, 1, z);
  694. xfree (s);
  695. }
  696. return v;
  697. }
  698. #define UTF8NAME _T(".utf8")
  699. static void cfg_dowrite(struct zfile *f, const TCHAR *option, const TCHAR *optionext, const TCHAR *value, int d, int target, int escape)
  700. {
  701. char lf = 10;
  702. TCHAR tmp[CONFIG_BLEN], tmpext[CONFIG_BLEN];
  703. const TCHAR *optionp;
  704. const TCHAR *new_value = NULL;
  705. bool free_value = false;
  706. char tmpa[CONFIG_BLEN];
  707. char *tmp1, *tmp2;
  708. int utf8;
  709. if (value == NULL)
  710. return;
  711. if (optionext) {
  712. _tcscpy(tmpext, option);
  713. _tcscat(tmpext, optionext);
  714. optionp = tmpext;
  715. } else {
  716. optionp = option;
  717. }
  718. utf8 = 0;
  719. tmp1 = ua(value);
  720. tmp2 = uutf8(value);
  721. if (strcmp(tmp1, tmp2) && tmp2[0] != 0)
  722. utf8 = 1;
  723. if (escape) {
  724. new_value = cfgfile_escape_min(value);
  725. free_value = true;
  726. } else {
  727. new_value = value;
  728. }
  729. if (target)
  730. _stprintf(tmp, _T("%s.%s=%s"), TARGET_NAME, optionp, new_value);
  731. else
  732. _stprintf(tmp, _T("%s=%s"), optionp, new_value);
  733. if (d && isdefault (tmp))
  734. goto end;
  735. cfg_write(tmp, f);
  736. if (utf8 && !unicode_config) {
  737. char *opt = ua(optionp);
  738. if (target) {
  739. char *tna = ua(TARGET_NAME);
  740. sprintf(tmpa, "%s.%s.utf8=%s", tna, opt, tmp2);
  741. xfree(tna);
  742. } else {
  743. sprintf(tmpa, "%s.utf8=%s", opt, tmp2);
  744. }
  745. xfree(opt);
  746. zfile_fwrite(tmpa, strlen (tmpa), 1, f);
  747. zfile_fwrite(&lf, 1, 1, f);
  748. }
  749. end:
  750. if (free_value) {
  751. xfree((void*)new_value);
  752. }
  753. xfree(tmp2);
  754. xfree(tmp1);
  755. }
  756. static void cfgfile_dwrite_coords(struct zfile *f, const TCHAR *option, int x, int y)
  757. {
  758. if (x || y)
  759. cfgfile_dwrite(f, option, _T("%d,%d"), x, y);
  760. }
  761. static void cfg_dowrite(struct zfile *f, const TCHAR *option, const TCHAR *value, int d, int target, int escape)
  762. {
  763. cfg_dowrite(f, option, NULL, value, d, target, escape);
  764. }
  765. void cfgfile_write_bool(struct zfile *f, const TCHAR *option, bool b)
  766. {
  767. cfg_dowrite(f, option, b ? _T("true") : _T("false"), 0, 0, 0);
  768. }
  769. void cfgfile_dwrite_bool(struct zfile *f, const TCHAR *option, bool b)
  770. {
  771. cfg_dowrite(f, option, b ? _T("true") : _T("false"), 1, 0, 0);
  772. }
  773. static void cfgfile_dwrite_bool(struct zfile *f, const TCHAR *option, const TCHAR *optionext, bool b)
  774. {
  775. cfg_dowrite(f, option, optionext, b ? _T("true") : _T("false"), 1, 0, 0);
  776. }
  777. static void cfgfile_dwrite_bool(struct zfile *f, const TCHAR *option, int b)
  778. {
  779. cfgfile_dwrite_bool (f, option, b != 0);
  780. }
  781. void cfgfile_write_str(struct zfile *f, const TCHAR *option, const TCHAR *value)
  782. {
  783. cfg_dowrite(f, option, value, 0, 0, 0);
  784. }
  785. static void cfgfile_write_str(struct zfile *f, const TCHAR *option, const TCHAR *optionext, const TCHAR *value)
  786. {
  787. cfg_dowrite(f, option, optionext, value, 0, 0, 0);
  788. }
  789. static void cfgfile_write_str_escape(struct zfile *f, const TCHAR *option, const TCHAR *value)
  790. {
  791. cfg_dowrite(f, option, value, 0, 0, 1);
  792. }
  793. void cfgfile_dwrite_str(struct zfile *f, const TCHAR *option, const TCHAR *value)
  794. {
  795. cfg_dowrite(f, option, value, 1, 0, 0);
  796. }
  797. static void cfgfile_dwrite_str(struct zfile *f, const TCHAR *option, const TCHAR *optionext, const TCHAR *value)
  798. {
  799. cfg_dowrite(f, option, optionext, value, 1, 0, 0);
  800. }
  801. void cfgfile_target_write_bool(struct zfile *f, const TCHAR *option, bool b)
  802. {
  803. cfg_dowrite(f, option, b ? _T("true") : _T("false"), 0, 1, 0);
  804. }
  805. void cfgfile_target_dwrite_bool(struct zfile *f, const TCHAR *option, bool b)
  806. {
  807. cfg_dowrite(f, option, b ? _T("true") : _T("false"), 1, 1, 0);
  808. }
  809. void cfgfile_target_write_str(struct zfile *f, const TCHAR *option, const TCHAR *value)
  810. {
  811. cfg_dowrite(f, option, value, 0, 1, 0);
  812. }
  813. void cfgfile_target_dwrite_str(struct zfile *f, const TCHAR *option, const TCHAR *value)
  814. {
  815. cfg_dowrite(f, option, value, 1, 1, 0);
  816. }
  817. void cfgfile_target_dwrite_str_escape(struct zfile *f, const TCHAR *option, const TCHAR *value)
  818. {
  819. cfg_dowrite(f, option, value, 1, 1, 1);
  820. }
  821. static void cfgfile_write_ext(struct zfile *f, const TCHAR *option, const TCHAR *optionext, const TCHAR *format,...)
  822. {
  823. va_list parms;
  824. TCHAR tmp[CONFIG_BLEN], tmp2[CONFIG_BLEN];
  825. if (optionext) {
  826. _tcscpy(tmp2, option);
  827. _tcscat(tmp2, optionext);
  828. }
  829. va_start(parms, format);
  830. _vsntprintf(tmp, CONFIG_BLEN, format, parms);
  831. cfg_dowrite(f, optionext ? tmp2 : option, tmp, 0, 0, 0);
  832. va_end(parms);
  833. }
  834. void cfgfile_write(struct zfile *f, const TCHAR *option, const TCHAR *format,...)
  835. {
  836. va_list parms;
  837. TCHAR tmp[CONFIG_BLEN];
  838. va_start(parms, format);
  839. _vsntprintf(tmp, CONFIG_BLEN, format, parms);
  840. cfg_dowrite(f, option, tmp, 0, 0, 0);
  841. va_end(parms);
  842. }
  843. void cfgfile_write_escape(struct zfile *f, const TCHAR *option, const TCHAR *format,...)
  844. {
  845. va_list parms;
  846. TCHAR tmp[CONFIG_BLEN];
  847. va_start(parms, format);
  848. _vsntprintf(tmp, CONFIG_BLEN, format, parms);
  849. cfg_dowrite(f, option, tmp, 0, 0, 1);
  850. va_end(parms);
  851. }
  852. static void cfgfile_dwrite_ext(struct zfile *f, const TCHAR *option, const TCHAR *optionext, const TCHAR *format,...)
  853. {
  854. va_list parms;
  855. TCHAR tmp[CONFIG_BLEN], tmp2[CONFIG_BLEN];
  856. if (optionext) {
  857. _tcscpy(tmp2, option);
  858. _tcscat(tmp2, optionext);
  859. }
  860. va_start(parms, format);
  861. _vsntprintf(tmp, CONFIG_BLEN, format, parms);
  862. cfg_dowrite(f, optionext ? tmp2 : option, tmp, 1, 0, 0);
  863. va_end(parms);
  864. }
  865. void cfgfile_dwrite(struct zfile *f, const TCHAR *option, const TCHAR *format,...)
  866. {
  867. va_list parms;
  868. TCHAR tmp[CONFIG_BLEN];
  869. va_start(parms, format);
  870. _vsntprintf(tmp, CONFIG_BLEN, format, parms);
  871. cfg_dowrite(f, option, tmp, 1, 0, 0);
  872. va_end(parms);
  873. }
  874. void cfgfile_dwrite_escape(struct zfile *f, const TCHAR *option, const TCHAR *format,...)
  875. {
  876. va_list parms;
  877. TCHAR tmp[CONFIG_BLEN];
  878. va_start(parms, format);
  879. _vsntprintf(tmp, CONFIG_BLEN, format, parms);
  880. cfg_dowrite(f, option, tmp, 1, 0, 1);
  881. va_end(parms);
  882. }
  883. void cfgfile_target_write(struct zfile *f, const TCHAR *option, const TCHAR *format,...)
  884. {
  885. va_list parms;
  886. TCHAR tmp[CONFIG_BLEN];
  887. va_start(parms, format);
  888. _vsntprintf(tmp, CONFIG_BLEN, format, parms);
  889. cfg_dowrite(f, option, tmp, 0, 1, 0);
  890. va_end(parms);
  891. }
  892. void cfgfile_target_write_escape(struct zfile *f, const TCHAR *option, const TCHAR *format,...)
  893. {
  894. va_list parms;
  895. TCHAR tmp[CONFIG_BLEN];
  896. va_start(parms, format);
  897. _vsntprintf(tmp, CONFIG_BLEN, format, parms);
  898. cfg_dowrite(f, option, tmp, 0, 1, 1);
  899. va_end(parms);
  900. }
  901. void cfgfile_target_dwrite(struct zfile *f, const TCHAR *option, const TCHAR *format,...)
  902. {
  903. va_list parms;
  904. TCHAR tmp[CONFIG_BLEN];
  905. va_start(parms, format);
  906. _vsntprintf(tmp, CONFIG_BLEN, format, parms);
  907. cfg_dowrite(f, option, tmp, 1, 1, 0);
  908. va_end(parms);
  909. }
  910. void cfgfile_target_dwrite_escape(struct zfile *f, const TCHAR *option, const TCHAR *format,...)
  911. {
  912. va_list parms;
  913. TCHAR tmp[CONFIG_BLEN];
  914. va_start(parms, format);
  915. _vsntprintf(tmp, CONFIG_BLEN, format, parms);
  916. cfg_dowrite(f, option, tmp, 1, 1, 1);
  917. va_end(parms);
  918. }
  919. static void cfgfile_write_rom (struct zfile *f, struct multipath *mp, const TCHAR *romfile, const TCHAR *name)
  920. {
  921. TCHAR *str = cfgfile_subst_path (mp->path[0], UNEXPANDED, romfile);
  922. str = cfgfile_put_multipath (mp, str);
  923. cfgfile_write_str (f, name, str);
  924. struct zfile *zf = zfile_fopen (str, _T("rb"), ZFD_ALL);
  925. if (zf) {
  926. struct romdata *rd = getromdatabyzfile (zf);
  927. if (rd) {
  928. TCHAR name2[MAX_DPATH], str2[MAX_DPATH];
  929. _tcscpy (name2, name);
  930. _tcscat (name2, _T("_id"));
  931. _stprintf (str2, _T("%08X,%s"), rd->crc32, rd->name);
  932. cfgfile_write_str (f, name2, str2);
  933. }
  934. zfile_fclose (zf);
  935. }
  936. xfree (str);
  937. }
  938. static void cfgfile_to_path_save(const TCHAR *in, TCHAR *out, int type)
  939. {
  940. if (_tcschr(in, '%')) {
  941. _tcscpy(out, in);
  942. } else {
  943. cfgfile_resolve_path_out_save(in, out, MAX_DPATH, type);
  944. }
  945. }
  946. static void cfgfile_write_path2(struct zfile *f, const TCHAR *option, const TCHAR *value, int type)
  947. {
  948. if (_tcschr(value, '%')) {
  949. cfgfile_write_str(f, option, value);
  950. } else {
  951. TCHAR path[MAX_DPATH];
  952. cfgfile_resolve_path_out_save(value, path, MAX_DPATH, type);
  953. cfgfile_write_str(f, option, path);
  954. }
  955. }
  956. static void cfgfile_dwrite_path2(struct zfile *f, const TCHAR *option, const TCHAR *value, int type)
  957. {
  958. if (_tcschr(value, '%')) {
  959. cfgfile_dwrite_str(f, option, value);
  960. } else {
  961. TCHAR path[MAX_DPATH];
  962. cfgfile_resolve_path_out_save(value, path, MAX_DPATH, type);
  963. cfgfile_dwrite_str(f, option, path);
  964. }
  965. }
  966. static void cfgfile_write_path (struct zfile *f, struct multipath *mp, const TCHAR *option, const TCHAR *value)
  967. {
  968. TCHAR *s = cfgfile_put_multipath (mp, value);
  969. cfgfile_write_str (f, option, s);
  970. xfree (s);
  971. }
  972. static void cfgfile_dwrite_path (struct zfile *f, struct multipath *mp, const TCHAR *option, const TCHAR *value)
  973. {
  974. TCHAR *s = cfgfile_put_multipath (mp, value);
  975. cfgfile_dwrite_str (f, option, s);
  976. xfree (s);
  977. }
  978. static void cfgfile_write_multichoice(struct zfile *f, const TCHAR *option, const TCHAR *table[], int value)
  979. {
  980. TCHAR tmp[MAX_DPATH];
  981. if (!value)
  982. return;
  983. tmp[0] = 0;
  984. int i = 0;
  985. while (value && table[i]) {
  986. if (value & (1 << i) && table[i][0] && table[i][0] != '|') {
  987. if (tmp[0])
  988. _tcscat(tmp, _T(","));
  989. _tcscat(tmp, table[i]);
  990. }
  991. i++;
  992. }
  993. if (tmp[0])
  994. cfgfile_write(f, option, tmp);
  995. }
  996. static void cfgfile_adjust_path(TCHAR *path, int maxsz, struct multipath *mp)
  997. {
  998. if (path[0] == 0)
  999. return;
  1000. TCHAR *s = target_expand_environment(path, NULL, 0);
  1001. _tcsncpy(path, s, maxsz - 1);
  1002. path[maxsz - 1] = 0;
  1003. if (mp) {
  1004. for (int i = 0; i < MAX_PATHS; i++) {
  1005. if (mp->path[i][0] && _tcscmp(mp->path[i], _T(".\\")) != 0 && _tcscmp(mp->path[i], _T("./")) != 0 && (path[0] != '/' && path[0] != '\\' && !_tcschr(path, ':'))) {
  1006. TCHAR np[MAX_DPATH];
  1007. _tcscpy(np, mp->path[i]);
  1008. fixtrailing(np);
  1009. _tcscat(np, s);
  1010. fullpath(np, sizeof np / sizeof(TCHAR));
  1011. if (zfile_exists(np)) {
  1012. _tcsncpy(path, np, maxsz - 1);
  1013. path[maxsz - 1] = 0;
  1014. xfree(s);
  1015. return;
  1016. }
  1017. }
  1018. }
  1019. }
  1020. fullpath(path, maxsz);
  1021. xfree(s);
  1022. }
  1023. static void cfgfile_resolve_path_out_all(const TCHAR *path, TCHAR *out, int size, int type, bool save)
  1024. {
  1025. struct uae_prefs *p = &currprefs;
  1026. TCHAR *s = NULL;
  1027. switch (type)
  1028. {
  1029. case PATH_DIR:
  1030. s = cfgfile_subst_path_load(UNEXPANDED, &p->path_hardfile, path, true);
  1031. break;
  1032. case PATH_HDF:
  1033. s = cfgfile_subst_path_load(UNEXPANDED, &p->path_hardfile, path, false);
  1034. break;
  1035. case PATH_CD:
  1036. s = cfgfile_subst_path_load(UNEXPANDED, &p->path_cd, path, false);
  1037. break;
  1038. case PATH_ROM:
  1039. s = cfgfile_subst_path_load(UNEXPANDED, &p->path_rom, path, false);
  1040. break;
  1041. case PATH_FLOPPY:
  1042. _tcscpy(out, path);
  1043. cfgfile_adjust_path(out, MAX_DPATH, &p->path_floppy);
  1044. break;
  1045. default:
  1046. s = cfgfile_subst_path(NULL, NULL, path);
  1047. break;
  1048. }
  1049. if (s) {
  1050. _tcscpy(out, s);
  1051. xfree(s);
  1052. }
  1053. if (!save) {
  1054. my_resolvesoftlink(out, size, true);
  1055. }
  1056. }
  1057. void cfgfile_resolve_path_out_load(const TCHAR *path, TCHAR *out, int size, int type)
  1058. {
  1059. cfgfile_resolve_path_out_all(path, out, size, type, false);
  1060. }
  1061. void cfgfile_resolve_path_load(TCHAR *path, int size, int type)
  1062. {
  1063. cfgfile_resolve_path_out_all(path, path, size, type, false);
  1064. }
  1065. void cfgfile_resolve_path_out_save(const TCHAR *path, TCHAR *out, int size, int type)
  1066. {
  1067. cfgfile_resolve_path_out_all(path, out, size, type, true);
  1068. }
  1069. void cfgfile_resolve_path_save(TCHAR *path, int size, int type)
  1070. {
  1071. cfgfile_resolve_path_out_all(path, path, size, type, true);
  1072. }
  1073. static void write_filesys_config (struct uae_prefs *p, struct zfile *f)
  1074. {
  1075. TCHAR tmp[MAX_DPATH], tmp2[MAX_DPATH], tmp3[MAX_DPATH], str1[MAX_DPATH], hdcs[MAX_DPATH];
  1076. for (int i = 0; i < p->mountitems; i++) {
  1077. struct uaedev_config_data *uci = &p->mountconfig[i];
  1078. struct uaedev_config_info *ci = &uci->ci;
  1079. TCHAR *str1b, *str1c, *str2b;
  1080. const TCHAR *str2;
  1081. int bp = ci->bootpri;
  1082. str2 = _T("");
  1083. if (ci->rootdir[0] == ':') {
  1084. TCHAR *ptr;
  1085. // separate harddrive names
  1086. _tcscpy(str1, ci->rootdir);
  1087. ptr = _tcschr (str1 + 1, ':');
  1088. if (ptr) {
  1089. *ptr++ = 0;
  1090. str2 = ptr;
  1091. ptr = (TCHAR *) _tcschr (str2, ',');
  1092. if (ptr)
  1093. *ptr = 0;
  1094. }
  1095. } else {
  1096. 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)));
  1097. }
  1098. int ct = ci->controller_type;
  1099. int romtype = 0;
  1100. if (ct >= HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST && ct <= HD_CONTROLLER_TYPE_SCSI_LAST) {
  1101. _stprintf(hdcs, _T("scsi%d_%s"), ci->controller_unit, expansionroms[ct - HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST].name);
  1102. romtype = expansionroms[ct - HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST].romtype;
  1103. } else if (ct >= HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST && ct <= HD_CONTROLLER_TYPE_IDE_LAST) {
  1104. _stprintf(hdcs, _T("ide%d_%s"), ci->controller_unit, expansionroms[ct - HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST].name);
  1105. romtype = expansionroms[ct - HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST].romtype;
  1106. } else if (ct >= HD_CONTROLLER_TYPE_CUSTOM_FIRST && ct <= HD_CONTROLLER_TYPE_CUSTOM_LAST) {
  1107. _stprintf(hdcs, _T("custom%d_%s"), ci->controller_unit, expansionroms[ct - HD_CONTROLLER_TYPE_CUSTOM_FIRST].name);
  1108. romtype = expansionroms[ct - HD_CONTROLLER_TYPE_CUSTOM_FIRST].romtype;
  1109. } else if (ct == HD_CONTROLLER_TYPE_SCSI_AUTO) {
  1110. _stprintf(hdcs, _T("scsi%d"), ci->controller_unit);
  1111. } else if (ct == HD_CONTROLLER_TYPE_IDE_AUTO) {
  1112. _stprintf(hdcs, _T("ide%d"), ci->controller_unit);
  1113. } else if (ct == HD_CONTROLLER_TYPE_UAE) {
  1114. _stprintf(hdcs, _T("uae%d"), ci->controller_unit);
  1115. }
  1116. if (romtype) {
  1117. for (int j = 0; hdcontrollers[j].label; j++) {
  1118. if (hdcontrollers[j].romtype == (romtype & ROMTYPE_MASK)) {
  1119. _stprintf(hdcs, hdcontrollers[j].label, ci->controller_unit);
  1120. break;
  1121. }
  1122. }
  1123. }
  1124. if (ci->controller_type_unit > 0)
  1125. _stprintf(hdcs + _tcslen(hdcs), _T("-%d"), ci->controller_type_unit + 1);
  1126. str1b = cfgfile_escape (str1, _T(":,"), true);
  1127. str1c = cfgfile_escape_min(str1);
  1128. str2b = cfgfile_escape (str2, _T(":,"), true);
  1129. if (ci->type == UAEDEV_DIR) {
  1130. _stprintf (tmp, _T("%s,%s:%s:%s,%d"), ci->readonly ? _T("ro") : _T("rw"),
  1131. ci->devname ? ci->devname : _T(""), ci->volname, str1c, bp);
  1132. cfgfile_write_str (f, _T("filesystem2"), tmp);
  1133. _tcscpy (tmp3, tmp);
  1134. #if 0
  1135. _stprintf (tmp2, _T("filesystem=%s,%s:%s"), uci->readonly ? _T("ro") : _T("rw"),
  1136. uci->volname, str);
  1137. zfile_fputs (f, tmp2);
  1138. #endif
  1139. } else if (ci->type == UAEDEV_HDF || ci->type == UAEDEV_CD || ci->type == UAEDEV_TAPE) {
  1140. TCHAR filesyspath[MAX_DPATH];
  1141. cfgfile_to_path_save(ci->filesys, filesyspath, PATH_HDF);
  1142. TCHAR *sfilesys = cfgfile_escape_min(filesyspath);
  1143. TCHAR *sgeometry = cfgfile_escape(ci->geometry, NULL, true);
  1144. _stprintf (tmp, _T("%s,%s:%s,%d,%d,%d,%d,%d,%s,%s"),
  1145. ci->readonly ? _T("ro") : _T("rw"),
  1146. ci->devname ? ci->devname : _T(""), str1c,
  1147. ci->sectors, ci->surfaces, ci->reserved, ci->blocksize,
  1148. bp, ci->filesys[0] ? sfilesys : _T(""), hdcs);
  1149. _stprintf (tmp3, _T("%s,%s:%s%s%s,%d,%d,%d,%d,%d,%s,%s"),
  1150. ci->readonly ? _T("ro") : _T("rw"),
  1151. ci->devname ? ci->devname : _T(""), str1b, str2b[0] ? _T(":") : _T(""), str2b,
  1152. ci->sectors, ci->surfaces, ci->reserved, ci->blocksize,
  1153. bp, ci->filesys[0] ? sfilesys : _T(""), hdcs);
  1154. if (ci->highcyl || ci->physical_geometry || ci->geometry[0]) {
  1155. TCHAR *s = tmp + _tcslen (tmp);
  1156. TCHAR *s2 = s;
  1157. _stprintf (s2, _T(",%d"), ci->highcyl);
  1158. if ((ci->physical_geometry && ci->pheads && ci->psecs) || ci->geometry[0]) {
  1159. s = tmp + _tcslen (tmp);
  1160. _stprintf (s, _T(",%d/%d/%d"), ci->pcyls, ci->pheads, ci->psecs);
  1161. if (ci->geometry[0]) {
  1162. s = tmp + _tcslen (tmp);
  1163. _stprintf (s, _T(",%s"), sgeometry);
  1164. }
  1165. }
  1166. _tcscat (tmp3, s2);
  1167. xfree(sfilesys);
  1168. xfree(sgeometry);
  1169. }
  1170. if (ci->controller_media_type) {
  1171. _tcscat(tmp, _T(",CF"));
  1172. _tcscat(tmp3, _T(",CF"));
  1173. }
  1174. const TCHAR *extras = NULL;
  1175. if (ct >= HD_CONTROLLER_TYPE_SCSI_FIRST && ct <= HD_CONTROLLER_TYPE_SCSI_LAST) {
  1176. if (ci->unit_feature_level == HD_LEVEL_SCSI_1){
  1177. extras = _T("SCSI1");
  1178. } else if (ci->unit_feature_level == HD_LEVEL_SASI) {
  1179. extras = _T("SASI");
  1180. } else if (ci->unit_feature_level == HD_LEVEL_SASI_ENHANCED) {
  1181. extras = _T("SASIE");
  1182. } else if (ci->unit_feature_level == HD_LEVEL_SASI_CHS) {
  1183. extras = _T("SASI_CHS");
  1184. }
  1185. } else if (ct >= HD_CONTROLLER_TYPE_IDE_FIRST && ct <= HD_CONTROLLER_TYPE_IDE_LAST) {
  1186. if (ci->unit_feature_level == HD_LEVEL_ATA_1) {
  1187. extras = _T("ATA1");
  1188. } else if (ci->unit_feature_level == HD_LEVEL_ATA_2S) {
  1189. extras = _T("ATA2+S");
  1190. }
  1191. }
  1192. if (extras) {
  1193. _tcscat(tmp, _T(","));
  1194. _tcscat(tmp3, _T(","));
  1195. _tcscat(tmp, extras);
  1196. _tcscat(tmp3, extras);
  1197. }
  1198. if (ci->unit_special_flags) {
  1199. TCHAR tmpx[32];
  1200. _stprintf(tmpx, _T(",flags=0x%x"), ci->unit_special_flags);
  1201. _tcscat(tmp, tmpx);
  1202. _tcscat(tmp3, tmpx);
  1203. }
  1204. if (ci->lock) {
  1205. _tcscat(tmp, _T(",lock"));
  1206. _tcscat(tmp3, _T(",lock"));
  1207. }
  1208. if (ci->loadidentity) {
  1209. _tcscat(tmp, _T(",identity"));
  1210. _tcscat(tmp3, _T(",identity"));
  1211. }
  1212. if (ci->type == UAEDEV_HDF)
  1213. cfgfile_write_str (f, _T("hardfile2"), tmp);
  1214. #if 0
  1215. _stprintf (tmp2, _T("hardfile=%s,%d,%d,%d,%d,%s"),
  1216. uci->readonly ? "ro" : "rw", uci->sectors,
  1217. uci->surfaces, uci->reserved, uci->blocksize, str);
  1218. zfile_fputs (f, tmp2);
  1219. #endif
  1220. }
  1221. _stprintf (tmp2, _T("uaehf%d"), i);
  1222. if (ci->type == UAEDEV_CD) {
  1223. cfgfile_write (f, tmp2, _T("cd%d,%s"), ci->device_emu_unit, tmp);
  1224. } else if (ci->type == UAEDEV_TAPE) {
  1225. cfgfile_write (f, tmp2, _T("tape%d,%s"), ci->device_emu_unit, tmp);
  1226. } else {
  1227. cfgfile_write (f, tmp2, _T("%s,%s"), ci->type == UAEDEV_HDF ? _T("hdf") : _T("dir"), tmp3);
  1228. }
  1229. if (ci->type == UAEDEV_DIR) {
  1230. bool add_extra = false;
  1231. if (ci->inject_icons) {
  1232. add_extra = true;
  1233. }
  1234. if (add_extra) {
  1235. _stprintf(tmp2, _T("%s,inject_icons=%s"), ci->devname, ci->inject_icons ? _T("true") : _T("false"));
  1236. cfgfile_write(f, _T("filesystem_extra"), tmp2);
  1237. }
  1238. }
  1239. xfree (str1b);
  1240. xfree (str1c);
  1241. xfree (str2b);
  1242. }
  1243. }
  1244. static void write_compatibility_cpu (struct zfile *f, struct uae_prefs *p)
  1245. {
  1246. TCHAR tmp[100];
  1247. int model;
  1248. model = p->cpu_model;
  1249. if (model == 68030)
  1250. model = 68020;
  1251. if (model == 68060)
  1252. model = 68040;
  1253. if (p->address_space_24 && model == 68020)
  1254. _tcscpy (tmp, _T("68ec020"));
  1255. else
  1256. _stprintf (tmp, _T("%d"), model);
  1257. if (model == 68020 && (p->fpu_model == 68881 || p->fpu_model == 68882))
  1258. _tcscat (tmp, _T("/68881"));
  1259. cfgfile_write (f, _T("cpu_type"), tmp);
  1260. }
  1261. static void write_leds (struct zfile *f, const TCHAR *name, int mask)
  1262. {
  1263. TCHAR tmp[MAX_DPATH];
  1264. tmp[0] = 0;
  1265. for (int i = 0; leds[i]; i++) {
  1266. bool got = false;
  1267. for (int j = 0; leds[j]; j++) {
  1268. if (leds_order[j] == i) {
  1269. if (mask & (1 << j)) {
  1270. if (got)
  1271. _tcscat (tmp, _T(":"));
  1272. _tcscat (tmp, leds[j]);
  1273. got = true;
  1274. }
  1275. }
  1276. }
  1277. if (leds[i + 1] && got)
  1278. _tcscat (tmp, _T(","));
  1279. }
  1280. while (tmp[0] && tmp[_tcslen (tmp) - 1] == ',')
  1281. tmp[_tcslen (tmp) - 1] = 0;
  1282. cfgfile_dwrite_str (f, name, tmp);
  1283. }
  1284. static void write_resolution (struct zfile *f, const TCHAR *ws, const TCHAR *hs, struct wh *wh)
  1285. {
  1286. if (wh->width <= 0 || wh->height <= 0 || wh->special == WH_NATIVE) {
  1287. cfgfile_write_str (f, ws, _T("native"));
  1288. cfgfile_write_str (f, hs, _T("native"));
  1289. } else {
  1290. cfgfile_write (f, ws, _T("%d"), wh->width);
  1291. cfgfile_write (f, hs, _T("%d"), wh->height);
  1292. }
  1293. }
  1294. static int cfgfile_read_rom_settings(const struct expansionboardsettings *ebs, const TCHAR *buf, TCHAR *configtext)
  1295. {
  1296. int settings = 0;
  1297. int bitcnt = 0;
  1298. int sstr = 0;
  1299. if (configtext)
  1300. configtext[0] = 0;
  1301. TCHAR *ct = configtext;
  1302. for (int i = 0; ebs[i].name; i++) {
  1303. const struct expansionboardsettings *eb = &ebs[i];
  1304. bitcnt += eb->bitshift;
  1305. if (eb->type == EXPANSIONBOARD_STRING) {
  1306. TCHAR *p = cfgfile_option_get(buf, eb->configname);
  1307. if (p) {
  1308. _tcscpy(ct, p);
  1309. ct += _tcslen(ct);
  1310. xfree(p);
  1311. }
  1312. *ct++ = 0;
  1313. } else if (eb->type == EXPANSIONBOARD_MULTI) {
  1314. int itemcnt = -1;
  1315. int itemfound = 0;
  1316. const TCHAR *p = eb->configname;
  1317. while (p[0]) {
  1318. if (itemcnt >= 0) {
  1319. if (cfgfile_option_find(buf, p)) {
  1320. itemfound = itemcnt;
  1321. }
  1322. }
  1323. itemcnt++;
  1324. p += _tcslen(p) + 1;
  1325. }
  1326. int cnt = 1;
  1327. int bits = 1;
  1328. for (int i = 0; i < 8; i++) {
  1329. if ((1 << i) >= itemcnt) {
  1330. cnt = 1 << i;
  1331. bits = i;
  1332. break;
  1333. }
  1334. }
  1335. int multimask = cnt - 1;
  1336. if (eb->invert)
  1337. itemfound ^= 0x7fffffff;
  1338. itemfound &= multimask;
  1339. settings |= itemfound << bitcnt;
  1340. bitcnt += bits;
  1341. } else {
  1342. int mask = 1 << bitcnt;
  1343. if (cfgfile_option_find(buf, eb->configname)) {
  1344. settings |= mask;
  1345. }
  1346. if (eb->invert)
  1347. settings ^= mask;
  1348. bitcnt++;
  1349. }
  1350. }
  1351. return settings;
  1352. }
  1353. static void cfgfile_write_rom_settings(const struct expansionboardsettings *ebs, TCHAR *buf, int settings, const TCHAR *settingstring)
  1354. {
  1355. int bitcnt = 0;
  1356. int sstr = 0;
  1357. for (int j = 0; ebs[j].name; j++) {
  1358. const struct expansionboardsettings *eb = &ebs[j];
  1359. bitcnt += eb->bitshift;
  1360. if (eb->type == EXPANSIONBOARD_STRING) {
  1361. if (settingstring) {
  1362. TCHAR tmp[MAX_DPATH];
  1363. const TCHAR *p = settingstring;
  1364. for (int i = 0; i < sstr; i++) {
  1365. p += _tcslen(p) + 1;
  1366. }
  1367. if (buf[0])
  1368. _tcscat(buf, _T(","));
  1369. TCHAR *cs = cfgfile_escape_min(p);
  1370. _stprintf(tmp, _T("%s=%s"), eb->configname, cs);
  1371. _tcscat(buf, tmp);
  1372. xfree(cs);
  1373. sstr++;
  1374. }
  1375. } else if (eb->type == EXPANSIONBOARD_MULTI) {
  1376. int itemcnt = -1;
  1377. const TCHAR *p = eb->configname;
  1378. while (p[0]) {
  1379. itemcnt++;
  1380. p += _tcslen(p) + 1;
  1381. }
  1382. int cnt = 1;
  1383. int bits = 1;
  1384. for (int i = 0; i < 8; i++) {
  1385. if ((1 << i) >= itemcnt) {
  1386. cnt = 1 << i;
  1387. bits = i;
  1388. break;
  1389. }
  1390. }
  1391. int multimask = cnt - 1;
  1392. int multivalue = settings;
  1393. if (eb->invert)
  1394. multivalue ^= 0x7fffffff;
  1395. multivalue = (multivalue >> bitcnt) & multimask;
  1396. p = eb->configname;
  1397. while (multivalue >= 0) {
  1398. multivalue--;
  1399. p += _tcslen(p) + 1;
  1400. }
  1401. if (buf[0])
  1402. _tcscat(buf, _T(","));
  1403. _tcscat(buf, p);
  1404. bitcnt += bits;
  1405. } else {
  1406. int value = settings;
  1407. if (eb->invert)
  1408. value ^= 0x7fffffff;
  1409. if (value & (1 << bitcnt)) {
  1410. if (buf[0])
  1411. _tcscat(buf, _T(","));
  1412. _tcscat(buf, eb->configname);
  1413. }
  1414. bitcnt++;
  1415. }
  1416. }
  1417. }
  1418. static bool is_custom_romboard(struct boardromconfig *br)
  1419. {
  1420. return ((br->device_type & ROMTYPE_MASK) == ROMTYPE_UAEBOARDZ2 || (br->device_type & ROMTYPE_MASK) == ROMTYPE_UAEBOARDZ3);
  1421. }
  1422. static void cfgfile_write_board_rom(struct uae_prefs *prefs, struct zfile *f, struct multipath *mp, struct boardromconfig *br)
  1423. {
  1424. TCHAR buf[MAX_DPATH];
  1425. TCHAR name[256];
  1426. const struct expansionromtype *ert;
  1427. if (br->device_type == 0)
  1428. return;
  1429. ert = get_device_expansion_rom(br->device_type);
  1430. if (!ert)
  1431. return;
  1432. for (int i = 0; i < MAX_BOARD_ROMS; i++) {
  1433. struct romconfig *rc = &br->roms[i];
  1434. if (br->device_num == 0)
  1435. _tcscpy(name, ert->name);
  1436. else
  1437. _stprintf(name, _T("%s-%d"), ert->name, br->device_num + 1);
  1438. if (i == 0 || _tcslen(br->roms[i].romfile)) {
  1439. _stprintf(buf, _T("%s%s_rom_file"), name, i ? _T("_ext") : _T(""));
  1440. cfgfile_write_rom (f, mp, br->roms[i].romfile, buf);
  1441. if (rc->romident[0]) {
  1442. _stprintf(buf, _T("%s%s_rom"), name, i ? _T("_ext") : _T(""));
  1443. cfgfile_dwrite_str (f, buf, rc->romident);
  1444. }
  1445. if (rc->autoboot_disabled || rc->dma24bit || rc->inserted || ert->subtypes || ert->settings || ert->id_jumper || br->device_order > 0 || is_custom_romboard(br)) {
  1446. TCHAR buf2[256], *p;
  1447. buf2[0] = 0;
  1448. p = buf2;
  1449. _stprintf(buf, _T("%s%s_rom_options"), name, i ? _T("_ext") : _T(""));
  1450. if (ert->subtypes) {
  1451. const struct expansionsubromtype *srt = ert->subtypes;
  1452. int k = rc->subtype;
  1453. while (k && srt[1].name) {
  1454. srt++;
  1455. k--;
  1456. }
  1457. _stprintf(p, _T("subtype=%s"), srt->configname);
  1458. }
  1459. if (br->device_order > 0 && prefs->autoconfig_custom_sort) {
  1460. if (buf2[0])
  1461. _tcscat(buf2, _T(","));
  1462. TCHAR *p2 = buf2 + _tcslen(buf2);
  1463. _stprintf(p2, _T("order=%d"), br->device_order);
  1464. }
  1465. if (rc->autoboot_disabled) {
  1466. if (buf2[0])
  1467. _tcscat(buf2, _T(","));
  1468. _tcscat(buf2, _T("autoboot_disabled=true"));
  1469. }
  1470. if (rc->dma24bit) {
  1471. if (buf2[0])
  1472. _tcscat(buf2, _T(","));
  1473. _tcscat(buf2, _T("dma24bit=true"));
  1474. }
  1475. if (rc->inserted) {
  1476. if (buf2[0])
  1477. _tcscat(buf2, _T(","));
  1478. _tcscat(buf2, _T("inserted=true"));
  1479. }
  1480. if (ert->id_jumper) {
  1481. TCHAR tmp[256];
  1482. _stprintf(tmp, _T("id=%d"), rc->device_id);
  1483. if (buf2[0])
  1484. _tcscat(buf2, _T(","));
  1485. _tcscat(buf2, tmp);
  1486. }
  1487. if ((rc->device_settings || rc->configtext[0]) && ert->settings) {
  1488. cfgfile_write_rom_settings(ert->settings, buf2, rc->device_settings, rc->configtext);
  1489. }
  1490. if (is_custom_romboard(br)) {
  1491. if (rc->manufacturer) {
  1492. if (buf2[0])
  1493. _tcscat(buf2, _T(","));
  1494. TCHAR *p2 = buf2 + _tcslen(buf2);
  1495. _stprintf(p2, _T("mid=%u,pid=%u"), rc->manufacturer, rc->product);
  1496. }
  1497. if (rc->autoconfig[0]) {
  1498. uae_u8 *ac = rc->autoconfig;
  1499. if (buf2[0])
  1500. _tcscat(buf2, _T(","));
  1501. TCHAR *p2 = buf2 + _tcslen(buf2);
  1502. _stprintf(p2, _T("data=%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x"),
  1503. ac[0], ac[1], ac[2], ac[3], ac[4], ac[5], ac[6], ac[7],
  1504. ac[8], ac[9], ac[10], ac[11], ac[12], ac[13], ac[14], ac[15]);
  1505. }
  1506. }
  1507. if (buf2[0])
  1508. cfgfile_dwrite_str (f, buf, buf2);
  1509. }
  1510. if (rc->board_ram_size) {
  1511. _stprintf(buf, _T("%s%s_mem_size"), name, i ? _T("_ext") : _T(""));
  1512. cfgfile_write(f, buf, _T("%d"), rc->board_ram_size / 0x40000);
  1513. }
  1514. }
  1515. }
  1516. }
  1517. static bool cfgfile_readromboard(const TCHAR *option, const TCHAR *value, struct romboard *rbp)
  1518. {
  1519. TCHAR tmp1[MAX_DPATH];
  1520. for (int i = 0; i < MAX_ROM_BOARDS; i++) {
  1521. struct romboard *rb = &rbp[i];
  1522. if (i > 0)
  1523. _stprintf(tmp1, _T("romboard%d_options"), i + 1);
  1524. else
  1525. _tcscpy(tmp1, _T("romboard_options"));
  1526. if (!_tcsicmp(option, tmp1)) {
  1527. TCHAR *endptr;
  1528. TCHAR *s1, *s2;
  1529. s1 = cfgfile_option_get(value, _T("start"));
  1530. s2 = cfgfile_option_get(value, _T("end"));
  1531. rb->size = 0;
  1532. if (s1 && s2) {
  1533. rb->start_address = _tcstol(s1, &endptr, 16);
  1534. rb->end_address = _tcstol(s2, &endptr, 16);
  1535. if (rb->end_address && rb->end_address > rb->start_address) {
  1536. rb->size = (rb->end_address - rb->start_address + 65535) & ~65535;
  1537. }
  1538. }
  1539. xfree(s1);
  1540. xfree(s2);
  1541. s1 = cfgfile_option_get(value, _T("file"));
  1542. if (s1) {
  1543. TCHAR *p = cfgfile_unescape(s1, NULL);
  1544. _tcscpy(rb->lf.loadfile, p);
  1545. xfree(p);
  1546. }
  1547. xfree(s1);
  1548. s1 = cfgfile_option_get(value, _T("offset"));
  1549. if (s1) {
  1550. rb->lf.loadoffset = _tcstol(s1, &endptr, 16);
  1551. }
  1552. xfree(s1);
  1553. s1 = cfgfile_option_get(value, _T("fileoffset"));
  1554. if (s1) {
  1555. rb->lf.fileoffset = _tcstol(s1, &endptr, 16);
  1556. }
  1557. xfree(s1);
  1558. s1 = cfgfile_option_get(value, _T("filesize"));
  1559. if (s1) {
  1560. rb->lf.filesize = _tcstol(s1, &endptr, 16);
  1561. }
  1562. xfree(s1);
  1563. return true;
  1564. }
  1565. }
  1566. return false;
  1567. }
  1568. static bool cfgfile_readramboard(const TCHAR *option, const TCHAR *value, const TCHAR *name, struct ramboard *rbp)
  1569. {
  1570. TCHAR tmp1[MAX_DPATH];
  1571. int v;
  1572. for (int i = 0; i < MAX_RAM_BOARDS; i++) {
  1573. struct ramboard *rb = &rbp[i];
  1574. if (i > 0)
  1575. _stprintf(tmp1, _T("%s%d_size"), name, i + 1);
  1576. else
  1577. _stprintf(tmp1, _T("%s_size"), name);
  1578. if (!_tcsicmp(option, tmp1)) {
  1579. v = 0;
  1580. if (!_tcsicmp(tmp1, _T("chipmem_size")))
  1581. return false;
  1582. cfgfile_intval(option, value, tmp1, &v, 0x100000);
  1583. rb->size = v;
  1584. return true;
  1585. }
  1586. if (i > 0)
  1587. _stprintf(tmp1, _T("%s%d_size_k"), name, i + 1);
  1588. else
  1589. _stprintf(tmp1, _T("%s_size_k"), name);
  1590. if (!_tcsicmp(option, tmp1)) {
  1591. v = 0;
  1592. cfgfile_intval(option, value, tmp1, &v, 1024);
  1593. rb->size = v;
  1594. return true;
  1595. }
  1596. if (i > 0)
  1597. _stprintf(tmp1, _T("%s%d_options"), name, i + 1);
  1598. else
  1599. _stprintf(tmp1, _T("%s_options"), name);
  1600. if (!_tcsicmp(option, tmp1)) {
  1601. TCHAR *endptr;
  1602. TCHAR *s, *s1, *s2;
  1603. s = cfgfile_option_get(value, _T("order"));
  1604. if (s)
  1605. rb->device_order = _tstol(s);
  1606. xfree(s);
  1607. s = cfgfile_option_get(value, _T("mid"));
  1608. if (s)
  1609. rb->manufacturer = (uae_u16)_tstol(s);
  1610. xfree(s);
  1611. s = cfgfile_option_get(value, _T("pid"));
  1612. if (s)
  1613. rb->product = (uae_u8)_tstol(s);
  1614. xfree(s);
  1615. if (cfgfile_option_get_bool(value, _T("no_reset_unmap")))
  1616. rb->no_reset_unmap = true;
  1617. if (cfgfile_option_get_bool(value, _T("nodma")))
  1618. rb->nodma = true;
  1619. if (cfgfile_option_get_bool(value, _T("force16bit")))
  1620. rb->force16bit = true;
  1621. s = cfgfile_option_get(value, _T("data"));
  1622. if (s && _tcslen(s) >= 3 * 16 - 1) {
  1623. rb->autoconfig_inuse = true;
  1624. for (int i = 0; i < sizeof rb->autoconfig; i++) {
  1625. TCHAR *s2 = &s[i * 3];
  1626. if (i + 1 < sizeof rb->autoconfig && s2[2] != '.')
  1627. break;
  1628. TCHAR *endptr;
  1629. s[2] = 0;
  1630. rb->autoconfig[i] = (uae_u8)_tcstol(s2, &endptr, 16);
  1631. }
  1632. }
  1633. xfree(s);
  1634. s1 = cfgfile_option_get(value, _T("start"));
  1635. s2 = cfgfile_option_get(value, _T("end"));
  1636. if (s1 && s2) {
  1637. rb->start_address = _tcstol(s1, &endptr, 16);
  1638. rb->end_address = _tcstol(s2, &endptr, 16);
  1639. if (rb->start_address && rb->end_address > rb->start_address) {
  1640. rb->manual_config = true;
  1641. rb->autoconfig_inuse = false;
  1642. }
  1643. }
  1644. xfree(s1);
  1645. xfree(s2);
  1646. s1 = cfgfile_option_get(value, _T("write_address"));
  1647. if (s1) {
  1648. TCHAR *endptr;
  1649. rb->write_address = _tcstol(s1, &endptr, 16);
  1650. }
  1651. xfree(s1);
  1652. s1 = cfgfile_option_get(value, _T("file"));
  1653. if (s1) {
  1654. TCHAR *p = cfgfile_unescape(s1, NULL);
  1655. _tcscpy(rb->lf.loadfile, p);
  1656. xfree(p);
  1657. }
  1658. xfree(s1);
  1659. s1 = cfgfile_option_get(value, _T("offset"));
  1660. if (s1) {
  1661. rb->lf.loadoffset = _tcstol(s1, &endptr, 16);
  1662. }
  1663. xfree(s1);
  1664. s1 = cfgfile_option_get(value, _T("fileoffset"));
  1665. if (s1) {
  1666. rb->lf.fileoffset = _tcstol(s1, &endptr, 16);
  1667. }
  1668. xfree(s1);
  1669. s1 = cfgfile_option_get(value, _T("filesize"));
  1670. if (s1) {
  1671. rb->lf.filesize = _tcstol(s1, &endptr, 16);
  1672. }
  1673. xfree(s1);
  1674. rb->readonly = cfgfile_option_find(value, _T("read-only"));
  1675. return true;
  1676. }
  1677. }
  1678. return false;
  1679. }
  1680. static void cfgfile_writeromboard(struct uae_prefs *prefs, struct zfile *f, int num, struct romboard *rb)
  1681. {
  1682. TCHAR tmp1[MAX_DPATH], tmp2[MAX_DPATH];
  1683. if (!rb->end_address)
  1684. return;
  1685. if (num > 0)
  1686. _stprintf(tmp1, _T("romboard%d_options"), num + 1);
  1687. else
  1688. _tcscpy(tmp1, _T("romboard_options"));
  1689. tmp2[0] = 0;
  1690. TCHAR *p = tmp2;
  1691. _stprintf(p, _T("start=%08x,end=%08x"), rb->start_address, rb->end_address);
  1692. p += _tcslen(p);
  1693. if (rb->lf.loadfile[0]) {
  1694. _tcscat(p, _T(","));
  1695. p += _tcslen(p);
  1696. TCHAR *path = cfgfile_escape(rb->lf.loadfile, NULL, true);
  1697. if (rb->lf.loadoffset || rb->lf.fileoffset || rb->lf.filesize) {
  1698. _stprintf(p, _T("offset=%u,fileoffset=%u,filesize=%u,"), rb->lf.loadoffset, rb->lf.fileoffset, rb->lf.filesize);
  1699. p += _tcslen(p);
  1700. }
  1701. _stprintf(p, _T("file=%s"), path);
  1702. xfree(path);
  1703. }
  1704. if (tmp2[0]) {
  1705. cfgfile_write(f, tmp1, tmp2);
  1706. }
  1707. }
  1708. static void cfgfile_writeramboard(struct uae_prefs *prefs, struct zfile *f, const TCHAR *name, int num, struct ramboard *rb)
  1709. {
  1710. TCHAR tmp1[MAX_DPATH], tmp2[MAX_DPATH];
  1711. if (num > 0)
  1712. _stprintf(tmp1, _T("%s%d_options"), name, num + 1);
  1713. else
  1714. _stprintf(tmp1, _T("%s_options"), name);
  1715. tmp2[0] = 0;
  1716. TCHAR *p = tmp2;
  1717. if (rb->device_order > 0 && prefs->autoconfig_custom_sort) {
  1718. if (tmp2[0])
  1719. *p++ = ',';
  1720. _stprintf(p, _T("order=%d"), rb->device_order);
  1721. p += _tcslen(p);
  1722. }
  1723. if (rb->manufacturer) {
  1724. if (tmp2[0])
  1725. *p++ = ',';
  1726. _stprintf(p, _T("mid=%u,pid=%u"), rb->manufacturer, rb->product);
  1727. p += _tcslen(p);
  1728. }
  1729. if (rb->no_reset_unmap) {
  1730. if (tmp2[0])
  1731. *p++ = ',';
  1732. _tcscpy(p, _T("no_reset_unmap=true"));
  1733. p += _tcslen(p);
  1734. }
  1735. if (rb->nodma) {
  1736. if (tmp2[0])
  1737. *p++ = ',';
  1738. _tcscpy(p, _T("nodma=true"));
  1739. p += _tcslen(p);
  1740. }
  1741. if (rb->force16bit) {
  1742. if (tmp2[0])
  1743. *p++ = ',';
  1744. _tcscpy(p, _T("force16bit=true"));
  1745. p += _tcslen(p);
  1746. }
  1747. if (rb->autoconfig_inuse) {
  1748. uae_u8 *ac = rb->autoconfig;
  1749. if (tmp2[0])
  1750. *p++ = ',';
  1751. _stprintf(p, _T("data=%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x"),
  1752. ac[0], ac[1], ac[2], ac[3], ac[4], ac[5], ac[6], ac[7],
  1753. ac[8], ac[9], ac[10], ac[11], ac[12], ac[13], ac[14], ac[15]);
  1754. p += _tcslen(p);
  1755. }
  1756. if (rb->manual_config && rb->start_address && rb->end_address) {
  1757. if (tmp2[0])
  1758. *p++ = ',';
  1759. _stprintf(p, _T("start=%08x,end=%08x"), rb->start_address, rb->end_address);
  1760. p += _tcslen(p);
  1761. }
  1762. if (rb->write_address) {
  1763. _stprintf(p, _T(",write_address=%08x"), rb->write_address);
  1764. p += _tcslen(p);
  1765. }
  1766. if (rb->lf.loadfile[0]) {
  1767. if (tmp2[0]) {
  1768. _tcscat(p, _T(","));
  1769. p += _tcslen(p);
  1770. }
  1771. TCHAR *path = cfgfile_escape(rb->lf.loadfile, NULL, true);
  1772. _stprintf(p, _T("offset=%u,fileoffset=%u,filesize=%u,file=%s"), rb->lf.loadoffset, rb->lf.fileoffset, rb->lf.filesize, path);
  1773. xfree(path);
  1774. }
  1775. if (rb->readonly) {
  1776. if (tmp2[0])
  1777. _tcscat(p, _T(","));
  1778. _tcscat(p, _T("readonly"));
  1779. }
  1780. if (tmp2[0]) {
  1781. cfgfile_write(f, tmp1, tmp2);
  1782. }
  1783. }
  1784. void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
  1785. {
  1786. struct strlist *sl;
  1787. TCHAR tmp[MAX_DPATH];
  1788. int i;
  1789. cfgfile_write_str(f, _T("config_description"), p->description);
  1790. if (p->category[0])
  1791. cfgfile_write_str(f, _T("config_category"), p->category);
  1792. if (p->tags[0])
  1793. cfgfile_write_str(f, _T("config_tags"), p->tags);
  1794. cfgfile_write_bool (f, _T("config_hardware"), type & CONFIG_TYPE_HARDWARE);
  1795. cfgfile_write_bool (f, _T("config_host"), !!(type & CONFIG_TYPE_HOST));
  1796. if (p->info[0])
  1797. cfgfile_write (f, _T("config_info"), p->info);
  1798. cfgfile_write (f, _T("config_version"), _T("%d.%d.%d"), UAEMAJOR, UAEMINOR, UAESUBREV);
  1799. cfgfile_write_str (f, _T("config_hardware_path"), p->config_hardware_path);
  1800. cfgfile_write_str (f, _T("config_host_path"), p->config_host_path);
  1801. cfgfile_write_str (f, _T("config_all_path"), p->config_all_path);
  1802. if (p->config_window_title[0])
  1803. cfgfile_write_str (f, _T("config_window_title"), p->config_window_title);
  1804. for (sl = p->all_lines; sl; sl = sl->next) {
  1805. if (sl->unknown) {
  1806. if (sl->option)
  1807. cfgfile_write_str (f, sl->option, sl->value);
  1808. }
  1809. }
  1810. for (i = 0; i < MAX_PATHS; i++) {
  1811. if (p->path_rom.path[i][0]) {
  1812. _stprintf (tmp, _T("%s.rom_path"), TARGET_NAME);
  1813. cfgfile_write_str (f, tmp, p->path_rom.path[i]);
  1814. }
  1815. }
  1816. for (i = 0; i < MAX_PATHS; i++) {
  1817. if (p->path_floppy.path[i][0]) {
  1818. _stprintf (tmp, _T("%s.floppy_path"), TARGET_NAME);
  1819. cfgfile_write_str (f, tmp, p->path_floppy.path[i]);
  1820. }
  1821. }
  1822. for (i = 0; i < MAX_PATHS; i++) {
  1823. if (p->path_hardfile.path[i][0]) {
  1824. _stprintf (tmp, _T("%s.hardfile_path"), TARGET_NAME);
  1825. cfgfile_write_str (f, tmp, p->path_hardfile.path[i]);
  1826. }
  1827. }
  1828. for (i = 0; i < MAX_PATHS; i++) {
  1829. if (p->path_cd.path[i][0]) {
  1830. _stprintf (tmp, _T("%s.cd_path"), TARGET_NAME);
  1831. cfgfile_write_str (f, tmp, p->path_cd.path[i]);
  1832. }
  1833. }
  1834. cfg_write (_T("; host-specific"), f);
  1835. target_save_options (f, p);
  1836. cfg_write (_T("; common"), f);
  1837. cfgfile_write_str (f, _T("use_gui"), guimode1[p->start_gui]);
  1838. cfgfile_write_bool (f, _T("use_debugger"), p->start_debugger);
  1839. cfgfile_write_multichoice(f, _T("debugging_features"), debugfeatures, p->debugging_features);
  1840. cfgfile_dwrite_str(f, _T("debugging_options"), p->debugging_options);
  1841. cfgfile_write_rom (f, &p->path_rom, p->romfile, _T("kickstart_rom_file"));
  1842. cfgfile_write_rom (f, &p->path_rom, p->romextfile, _T("kickstart_ext_rom_file"));
  1843. if (p->romextfile2addr) {
  1844. cfgfile_write (f, _T("kickstart_ext_rom_file2_address"), _T("%x"), p->romextfile2addr);
  1845. cfgfile_write_rom (f, &p->path_rom, p->romextfile2, _T("kickstart_ext_rom_file2"));
  1846. }
  1847. if (p->romident[0])
  1848. cfgfile_dwrite_str (f, _T("kickstart_rom"), p->romident);
  1849. if (p->romextident[0])
  1850. cfgfile_write_str (f, _T("kickstart_ext_rom="), p->romextident);
  1851. for (int i = 0; i < MAX_ROM_BOARDS; i++) {
  1852. cfgfile_writeromboard(p, f, i, &p->romboards[i]);
  1853. }
  1854. for (int i = 0; i < MAX_EXPANSION_BOARDS; i++) {
  1855. cfgfile_write_board_rom(p, f, &p->path_rom, &p->expansionboard[i]);
  1856. }
  1857. cfgfile_write_path2(f, _T("flash_file"), p->flashfile, PATH_ROM);
  1858. cfgfile_write_path (f, &p->path_rom, _T("cart_file"), p->cartfile);
  1859. cfgfile_write_path2(f, _T("rtc_file"), p->rtcfile, PATH_ROM);
  1860. if (p->cartident[0])
  1861. cfgfile_write_str (f, _T("cart"), p->cartident);
  1862. cfgfile_dwrite_path (f, &p->path_rom, _T("picassoiv_rom_file"), p->picassoivromfile);
  1863. cfgfile_write_bool (f, _T("kickshifter"), p->kickshifter);
  1864. cfgfile_dwrite_bool (f, _T("ks_write_enabled"), p->rom_readwrite);
  1865. cfgfile_write (f, _T("floppy_volume"), _T("%d"), p->dfxclickvolume_disk[0]);
  1866. p->nr_floppies = 4;
  1867. for (i = 0; i < 4; i++) {
  1868. _stprintf (tmp, _T("floppy%d"), i);
  1869. cfgfile_write_path2(f, tmp, p->floppyslots[i].df, PATH_FLOPPY);
  1870. _stprintf (tmp, _T("floppy%dwp"), i);
  1871. cfgfile_dwrite_bool (f, tmp, p->floppyslots[i].forcedwriteprotect);
  1872. _stprintf(tmp, _T("floppy%dtype"), i);
  1873. cfgfile_dwrite(f, tmp, _T("%d"), p->floppyslots[i].dfxtype);
  1874. if (p->floppyslots[i].dfxsubtype) {
  1875. _stprintf(tmp, _T("floppy%dsubtype"), i);
  1876. cfgfile_dwrite(f, tmp, _T("%d"), p->floppyslots[i].dfxsubtype);
  1877. if (p->floppyslots[i].dfxsubtypeid) {
  1878. _stprintf(tmp, _T("floppy%dsubtypeid"), i);
  1879. cfgfile_dwrite_escape(f, tmp, _T("%s"), p->floppyslots[i].dfxsubtypeid);
  1880. }
  1881. }
  1882. _stprintf (tmp, _T("floppy%dsound"), i);
  1883. cfgfile_dwrite (f, tmp, _T("%d"), p->floppyslots[i].dfxclick);
  1884. if (p->floppyslots[i].dfxclick < 0 && p->floppyslots[i].dfxclickexternal[0]) {
  1885. _stprintf (tmp, _T("floppy%dsoundext"), i);
  1886. cfgfile_dwrite (f, tmp, p->floppyslots[i].dfxclickexternal);
  1887. }
  1888. if (p->floppyslots[i].dfxclick) {
  1889. _stprintf (tmp, _T("floppy%dsoundvolume_disk"), i);
  1890. cfgfile_write (f, tmp, _T("%d"), p->dfxclickvolume_disk[i]);
  1891. _stprintf (tmp, _T("floppy%dsoundvolume_empty"), i);
  1892. cfgfile_write (f, tmp, _T("%d"), p->dfxclickvolume_empty[i]);
  1893. }
  1894. if (p->floppyslots[i].dfxtype < 0 && p->nr_floppies > i)
  1895. p->nr_floppies = i;
  1896. }
  1897. for (i = 0; i < MAX_SPARE_DRIVES; i++) {
  1898. if (p->dfxlist[i][0]) {
  1899. _stprintf (tmp, _T("diskimage%d"), i);
  1900. cfgfile_dwrite_path2(f, tmp, p->dfxlist[i], PATH_FLOPPY);
  1901. }
  1902. }
  1903. for (i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
  1904. if (p->cdslots[i].name[0] || p->cdslots[i].inuse) {
  1905. TCHAR tmp2[MAX_DPATH];
  1906. _stprintf (tmp, _T("cdimage%d"), i);
  1907. cfgfile_to_path_save(p->cdslots[i].name, tmp2, PATH_CD);
  1908. if (p->cdslots[i].type != SCSI_UNIT_DEFAULT || _tcschr (p->cdslots[i].name, ',') || p->cdslots[i].delayed) {
  1909. _tcscat (tmp2, _T(","));
  1910. if (p->cdslots[i].delayed) {
  1911. _tcscat (tmp2, _T("delay"));
  1912. _tcscat (tmp2, _T(":"));
  1913. }
  1914. if (p->cdslots[i].type != SCSI_UNIT_DEFAULT) {
  1915. _tcscat (tmp2, cdmodes[p->cdslots[i].type + 1]);
  1916. }
  1917. }
  1918. cfgfile_write_str (f, tmp, tmp2);
  1919. }
  1920. }
  1921. for (i = 0; i < MAX_LUA_STATES; i++) {
  1922. if (p->luafiles[i][0]) {
  1923. cfgfile_write_str (f, _T("lua"), p->luafiles[i]);
  1924. }
  1925. }
  1926. if (p->trainerfile[0])
  1927. cfgfile_write_str(f, _T("trainerfile"), p->trainerfile);
  1928. if (p->statefile[0])
  1929. cfgfile_write_str (f, _T("statefile"), p->statefile);
  1930. if (p->quitstatefile[0])
  1931. cfgfile_write_str (f, _T("statefile_quit"), p->quitstatefile);
  1932. cfgfile_write (f, _T("nr_floppies"), _T("%d"), p->nr_floppies);
  1933. cfgfile_dwrite_bool (f, _T("floppy_write_protect"), p->floppy_read_only);
  1934. cfgfile_write (f, _T("floppy_speed"), _T("%d"), p->floppy_speed);
  1935. cfgfile_dwrite (f, _T("floppy_channel_mask"), _T("0x%x"), p->dfxclickchannelmask);
  1936. cfgfile_write (f, _T("cd_speed"), _T("%d"), p->cd_speed);
  1937. cfgfile_write_bool (f, _T("parallel_on_demand"), p->parallel_demand);
  1938. cfgfile_write_bool (f, _T("serial_on_demand"), p->serial_demand);
  1939. cfgfile_write_bool (f, _T("serial_hardware_ctsrts"), p->serial_hwctsrts);
  1940. cfgfile_write_bool (f, _T("serial_direct"), p->serial_direct);
  1941. cfgfile_dwrite (f, _T("serial_stopbits"), _T("%d"), p->serial_stopbits);
  1942. cfgfile_dwrite_str(f, _T("serial_translate"), serialcrlf[p->serial_crlf]);
  1943. cfgfile_write_str (f, _T("scsi"), scsimode[p->scsi]);
  1944. cfgfile_write_bool (f, _T("uaeserial"), p->uaeserial);
  1945. cfgfile_write_bool (f, _T("sana2"), p->sana2);
  1946. cfgfile_write_str (f, _T("sound_output"), soundmode1[p->produce_sound]);
  1947. cfgfile_write_str (f, _T("sound_channels"), stereomode[p->sound_stereo]);
  1948. cfgfile_write (f, _T("sound_stereo_separation"), _T("%d"), p->sound_stereo_separation);
  1949. cfgfile_write (f, _T("sound_stereo_mixing_delay"), _T("%d"), p->sound_mixed_stereo_delay >= 0 ? p->sound_mixed_stereo_delay : 0);
  1950. cfgfile_write (f, _T("sound_max_buff"), _T("%d"), p->sound_maxbsiz);
  1951. cfgfile_write (f, _T("sound_frequency"), _T("%d"), p->sound_freq);
  1952. cfgfile_write_str (f, _T("sound_interpol"), interpolmode[p->sound_interpol]);
  1953. cfgfile_write_str (f, _T("sound_filter"), soundfiltermode1[p->sound_filter]);
  1954. cfgfile_write_str (f, _T("sound_filter_type"), soundfiltermode2[p->sound_filter_type]);
  1955. cfgfile_write (f, _T("sound_volume"), _T("%d"), p->sound_volume_master);
  1956. cfgfile_write (f, _T("sound_volume_paula"), _T("%d"), p->sound_volume_paula);
  1957. if (p->sound_volume_cd >= 0)
  1958. cfgfile_write (f, _T("sound_volume_cd"), _T("%d"), p->sound_volume_cd);
  1959. if (p->sound_volume_board >= 0)
  1960. cfgfile_write (f, _T("sound_volume_ahi"), _T("%d"), p->sound_volume_board);
  1961. if (p->sound_volume_midi >= 0)
  1962. cfgfile_write (f, _T("sound_volume_midi"), _T("%d"), p->sound_volume_midi);
  1963. if (p->sound_volume_genlock >= 0)
  1964. cfgfile_write (f, _T("sound_volume_genlock"), _T("%d"), p->sound_volume_genlock);
  1965. cfgfile_write_bool (f, _T("sound_auto"), p->sound_auto);
  1966. cfgfile_write_bool (f, _T("sound_cdaudio"), p->sound_cdaudio);
  1967. cfgfile_write_bool (f, _T("sound_stereo_swap_paula"), p->sound_stereo_swap_paula);
  1968. cfgfile_write_bool (f, _T("sound_stereo_swap_ahi"), p->sound_stereo_swap_ahi);
  1969. cfgfile_dwrite_bool(f, _T("sound_volcnt"), p->sound_volcnt);
  1970. cfgfile_dwrite (f, _T("sampler_frequency"), _T("%d"), p->sampler_freq);
  1971. cfgfile_dwrite (f, _T("sampler_buffer"), _T("%d"), p->sampler_buffer);
  1972. cfgfile_dwrite_bool (f, _T("sampler_stereo"), p->sampler_stereo);
  1973. cfgfile_write_str (f, _T("comp_trustbyte"), compmode[p->comptrustbyte]);
  1974. cfgfile_write_str (f, _T("comp_trustword"), compmode[p->comptrustword]);
  1975. cfgfile_write_str (f, _T("comp_trustlong"), compmode[p->comptrustlong]);
  1976. cfgfile_write_str (f, _T("comp_trustnaddr"), compmode[p->comptrustnaddr]);
  1977. cfgfile_write_bool (f, _T("comp_nf"), p->compnf);
  1978. cfgfile_write_bool (f, _T("comp_constjump"), p->comp_constjump);
  1979. cfgfile_write_str (f, _T("comp_flushmode"), flushmode[p->comp_hardflush]);
  1980. #ifdef USE_JIT_FPU
  1981. cfgfile_write_bool (f, _T("compfpu"), p->compfpu);
  1982. #endif
  1983. cfgfile_write_bool(f, _T("comp_catchfault"), p->comp_catchfault);
  1984. cfgfile_write(f, _T("cachesize"), _T("%d"), p->cachesize);
  1985. cfgfile_dwrite_str(f, _T("jit_blacklist"), p->jitblacklist);
  1986. for (i = 0; i < MAX_JPORTS; i++) {
  1987. struct jport *jp = &p->jports[i];
  1988. int v = jp->id;
  1989. TCHAR tmp1[MAX_DPATH], tmp2[MAX_DPATH];
  1990. if (v == JPORT_NONE) {
  1991. _tcscpy (tmp2, _T("none"));
  1992. } else if (v < JSEM_CUSTOM) {
  1993. _stprintf(tmp2, _T("kbd%d"), v + 1);
  1994. } else if (v < JSEM_JOYS) {
  1995. _stprintf(tmp2, _T("custom%d"), v - JSEM_CUSTOM);
  1996. } else if (v < JSEM_MICE) {
  1997. _stprintf (tmp2, _T("joy%d"), v - JSEM_JOYS);
  1998. } else {
  1999. _tcscpy (tmp2, _T("mouse"));
  2000. if (v - JSEM_MICE > 0)
  2001. _stprintf (tmp2, _T("mouse%d"), v - JSEM_MICE);
  2002. }
  2003. if (i < 2 || jp->id >= 0) {
  2004. _stprintf (tmp1, _T("joyport%d"), i);
  2005. cfgfile_write (f, tmp1, tmp2);
  2006. _stprintf (tmp1, _T("joyport%dautofire"), i);
  2007. cfgfile_write (f, tmp1, joyaf[jp->autofire]);
  2008. if (i < 2 && jp->mode > 0) {
  2009. _stprintf (tmp1, _T("joyport%dmode"), i);
  2010. cfgfile_write (f, tmp1, joyportmodes[jp->mode]);
  2011. if (jp->submode > 0 && jp->mode == 8) {
  2012. _stprintf(tmp1, _T("joyport%dsubmode"), i);
  2013. cfgfile_write(f, tmp1, joyportsubmodes_lightpen[jp->submode]);
  2014. }
  2015. }
  2016. if (jp->idc.name[0]) {
  2017. _stprintf (tmp1, _T("joyportfriendlyname%d"), i);
  2018. cfgfile_write (f, tmp1, jp->idc.name);
  2019. }
  2020. if (jp->idc.configname[0]) {
  2021. _stprintf (tmp1, _T("joyportname%d"), i);
  2022. cfgfile_write (f, tmp1, jp->idc.configname);
  2023. }
  2024. if (jp->nokeyboardoverride) {
  2025. _stprintf (tmp1, _T("joyport%dkeyboardoverride"), i);
  2026. cfgfile_write_bool (f, tmp1, !jp->nokeyboardoverride);
  2027. }
  2028. }
  2029. }
  2030. for (i = 0; i < MAX_JPORTS_CUSTOM; i++) {
  2031. struct jport_custom *jp = &p->jports_custom[i];
  2032. if (jp->custom[0]) {
  2033. TCHAR tmp1[MAX_DPATH];
  2034. _stprintf(tmp1, _T("joyportcustom%d"), i);
  2035. cfgfile_write(f, tmp1, jp->custom);
  2036. }
  2037. }
  2038. if (p->dongle) {
  2039. if (p->dongle + 1 >= sizeof (dongles) / sizeof (TCHAR*))
  2040. cfgfile_write (f, _T("dongle"), _T("%d"), p->dongle);
  2041. else
  2042. cfgfile_write_str (f, _T("dongle"), dongles[p->dongle]);
  2043. }
  2044. cfgfile_write_bool (f, _T("bsdsocket_emu"), p->socket_emu);
  2045. {
  2046. // backwards compatibility
  2047. const TCHAR *name;
  2048. struct romconfig *rc;
  2049. rc = get_device_romconfig(p, ROMTYPE_A2065, 0);
  2050. if (rc) {
  2051. name = ethernet_getselectionname(rc ? rc->device_settings : 0);
  2052. cfgfile_write_str(f, _T("a2065"), name);
  2053. }
  2054. rc = get_device_romconfig(p, ROMTYPE_NE2KPCMCIA, 0);
  2055. if (rc) {
  2056. name = ethernet_getselectionname(rc ? rc->device_settings : 0);
  2057. cfgfile_write_str(f, _T("ne2000_pcmcia"), name);
  2058. }
  2059. rc = get_device_romconfig(p, ROMTYPE_NE2KPCI, 0);
  2060. if (rc) {
  2061. name = ethernet_getselectionname(rc ? rc->device_settings : 0);
  2062. cfgfile_write_str(f, _T("ne2000_pci"), name);
  2063. }
  2064. }
  2065. #ifdef WITH_SLIRP
  2066. tmp[0] = 0;
  2067. for (i = 0; i < MAX_SLIRP_REDIRS; i++) {
  2068. struct slirp_redir *sr = &p->slirp_redirs[i];
  2069. if (sr->proto && !sr->srcport) {
  2070. TCHAR *p = tmp + _tcslen (tmp);
  2071. if (p > tmp)
  2072. *p++ = ',';
  2073. _stprintf (p, _T("%d"), sr->dstport);
  2074. }
  2075. }
  2076. if (tmp[0])
  2077. cfgfile_write_str (f, _T("slirp_ports"), tmp);
  2078. for (i = 0; i < MAX_SLIRP_REDIRS; i++) {
  2079. struct slirp_redir *sr = &p->slirp_redirs[i];
  2080. if (sr->proto && sr->srcport) {
  2081. uae_u32 v = htonl (sr->addr);
  2082. if (v) {
  2083. _stprintf (tmp, _T("%s:%d:%d:%d.%d.%d.%d"),
  2084. sr->proto == 1 ? _T("tcp") : _T("udp"),
  2085. sr->dstport, sr->srcport,
  2086. (v >> 24) & 0xff, (v >> 16) & 0xff, (v >> 8) & 0xff, v & 0xff);
  2087. } else {
  2088. _stprintf (tmp, _T("%s:%d:%d"),
  2089. sr->proto == 1 ? _T("tcp") : _T("udp"),
  2090. sr->dstport, sr->srcport);
  2091. }
  2092. cfgfile_write_str (f, _T("slirp_redir"), tmp);
  2093. }
  2094. }
  2095. #endif /* WITH_SLIRP */
  2096. cfgfile_write_bool (f, _T("synchronize_clock"), p->tod_hack);
  2097. cfgfile_write (f, _T("maprom"), _T("0x%x"), p->maprom);
  2098. cfgfile_dwrite_str (f, _T("boot_rom_uae"), uaebootrom[p->boot_rom]);
  2099. if (p->uaeboard_nodiag)
  2100. cfgfile_write_str(f, _T("uaeboard"), uaeboard_off[p->uaeboard]);
  2101. else
  2102. cfgfile_dwrite_str(f, _T("uaeboard"), uaeboard[p->uaeboard]);
  2103. if (p->autoconfig_custom_sort)
  2104. cfgfile_dwrite(f, _T("uaeboard_options"), _T("order=%d"), p->uaeboard_order);
  2105. cfgfile_dwrite_str (f, _T("parallel_matrix_emulation"), epsonprinter[p->parallel_matrix_emulation]);
  2106. cfgfile_write_bool (f, _T("parallel_postscript_emulation"), p->parallel_postscript_emulation);
  2107. cfgfile_write_bool (f, _T("parallel_postscript_detection"), p->parallel_postscript_detection);
  2108. cfgfile_write_str (f, _T("ghostscript_parameters"), p->ghostscript_parameters);
  2109. cfgfile_write (f, _T("parallel_autoflush"), _T("%d"), p->parallel_autoflush_time);
  2110. cfgfile_dwrite (f, _T("uae_hide"), _T("%d"), p->uae_hide);
  2111. cfgfile_dwrite_bool (f, _T("uae_hide_autoconfig"), p->uae_hide_autoconfig);
  2112. cfgfile_dwrite_bool (f, _T("magic_mouse"), (p->input_mouse_untrap & MOUSEUNTRAP_MAGIC) != 0);
  2113. cfgfile_dwrite_str (f, _T("magic_mousecursor"), magiccursors[p->input_magic_mouse_cursor]);
  2114. cfgfile_dwrite_str (f, _T("absolute_mouse"), abspointers[p->input_tablet]);
  2115. cfgfile_dwrite_bool (f, _T("tablet_library"), p->tablet_library);
  2116. cfgfile_dwrite_bool (f, _T("clipboard_sharing"), p->clipboard_sharing);
  2117. cfgfile_dwrite_bool(f, _T("native_code"), p->native_code);
  2118. cfgfile_write (f, _T("gfx_display"), _T("%d"), p->gfx_apmode[APMODE_NATIVE].gfx_display);
  2119. cfgfile_write_str (f, _T("gfx_display_friendlyname"), target_get_display_name (p->gfx_apmode[APMODE_NATIVE].gfx_display, true));
  2120. cfgfile_write_str (f, _T("gfx_display_name"), target_get_display_name (p->gfx_apmode[APMODE_NATIVE].gfx_display, false));
  2121. cfgfile_write (f, _T("gfx_display_rtg"), _T("%d"), p->gfx_apmode[APMODE_RTG].gfx_display);
  2122. cfgfile_write_str (f, _T("gfx_display_friendlyname_rtg"), target_get_display_name (p->gfx_apmode[APMODE_RTG].gfx_display, true));
  2123. cfgfile_write_str (f, _T("gfx_display_name_rtg"), target_get_display_name (p->gfx_apmode[APMODE_RTG].gfx_display, false));
  2124. cfgfile_write(f, _T("gfx_framerate"), _T("%d"), p->gfx_framerate);
  2125. write_resolution(f, _T("gfx_width"), _T("gfx_height"), &p->gfx_monitor[0].gfx_size_win); /* compatibility with old versions */
  2126. cfgfile_write (f, _T("gfx_top_windowed"), _T("%d"), p->gfx_monitor[0].gfx_size_win.x);
  2127. cfgfile_write(f, _T("gfx_left_windowed"), _T("%d"), p->gfx_monitor[0].gfx_size_win.y);
  2128. cfgfile_dwrite_bool(f, _T("gfx_resize_windowed"), p->gfx_windowed_resize);
  2129. write_resolution(f, _T("gfx_width_windowed"), _T("gfx_height_windowed"), &p->gfx_monitor[0].gfx_size_win);
  2130. write_resolution(f, _T("gfx_width_fullscreen"), _T("gfx_height_fullscreen"), &p->gfx_monitor[0].gfx_size_fs);
  2131. cfgfile_write(f, _T("gfx_refreshrate"), _T("%d"), p->gfx_apmode[0].gfx_refreshrate);
  2132. cfgfile_dwrite(f, _T("gfx_refreshrate_rtg"), _T("%d"), p->gfx_apmode[1].gfx_refreshrate);
  2133. cfgfile_write (f, _T("gfx_autoresolution"), _T("%d"), p->gfx_autoresolution);
  2134. cfgfile_dwrite (f, _T("gfx_autoresolution_delay"), _T("%d"), p->gfx_autoresolution_delay);
  2135. cfgfile_dwrite (f, _T("gfx_autoresolution_min_vertical"), vertmode[p->gfx_autoresolution_minv + 1]);
  2136. cfgfile_dwrite (f, _T("gfx_autoresolution_min_horizontal"), horizmode[p->gfx_autoresolution_minh + 1]);
  2137. cfgfile_write_bool (f, _T("gfx_autoresolution_vga"), p->gfx_autoresolution_vga);
  2138. cfgfile_write (f, _T("gfx_backbuffers"), _T("%d"), p->gfx_apmode[0].gfx_backbuffers);
  2139. cfgfile_write (f, _T("gfx_backbuffers_rtg"), _T("%d"), p->gfx_apmode[1].gfx_backbuffers);
  2140. if (p->gfx_apmode[APMODE_NATIVE].gfx_interlaced)
  2141. cfgfile_write_bool (f, _T("gfx_interlace"), p->gfx_apmode[APMODE_NATIVE].gfx_interlaced);
  2142. cfgfile_write_str (f, _T("gfx_vsync"), vsyncmodes[p->gfx_apmode[0].gfx_vsync]);
  2143. cfgfile_write_str (f, _T("gfx_vsyncmode"), vsyncmodes2[p->gfx_apmode[0].gfx_vsyncmode]);
  2144. cfgfile_write_str (f, _T("gfx_vsync_picasso"), vsyncmodes[p->gfx_apmode[1].gfx_vsync]);
  2145. cfgfile_write_str (f, _T("gfx_vsyncmode_picasso"), vsyncmodes2[p->gfx_apmode[1].gfx_vsyncmode]);
  2146. cfgfile_write_bool (f, _T("gfx_lores"), p->gfx_resolution == 0);
  2147. cfgfile_write_str (f, _T("gfx_resolution"), lorestype1[p->gfx_resolution]);
  2148. cfgfile_write_str (f, _T("gfx_lores_mode"), loresmode[p->gfx_lores_mode]);
  2149. cfgfile_write_bool (f, _T("gfx_flickerfixer"), p->gfx_scandoubler);
  2150. cfgfile_write_str (f, _T("gfx_linemode"), p->gfx_vresolution > 0 ? linemode[p->gfx_iscanlines * 4 + p->gfx_pscanlines + 1] : linemode[0]);
  2151. cfgfile_write_str (f, _T("gfx_fullscreen_amiga"), fullmodes[p->gfx_apmode[0].gfx_fullscreen]);
  2152. cfgfile_write_str (f, _T("gfx_fullscreen_picasso"), fullmodes[p->gfx_apmode[1].gfx_fullscreen]);
  2153. cfgfile_write_str (f, _T("gfx_center_horizontal"), centermode1[p->gfx_xcenter]);
  2154. cfgfile_write_str (f, _T("gfx_center_vertical"), centermode1[p->gfx_ycenter]);
  2155. cfgfile_write_str (f, _T("gfx_colour_mode"), colormode1[p->color_mode]);
  2156. cfgfile_write_bool(f, _T("gfx_blacker_than_black"), p->gfx_blackerthanblack);
  2157. cfgfile_dwrite_bool(f, _T("gfx_monochrome"), p->gfx_grayscale);
  2158. cfgfile_dwrite_str(f, _T("gfx_atari_palette_fix"), threebitcolors[p->gfx_threebitcolors]);
  2159. cfgfile_dwrite_bool(f, _T("gfx_black_frame_insertion"), p->lightboost_strobo);
  2160. cfgfile_dwrite(f, _T("gfx_black_frame_insertion_ratio"), _T("%d"), p->lightboost_strobo_ratio);
  2161. cfgfile_write_str(f, _T("gfx_api"), filterapi[p->gfx_api]);
  2162. cfgfile_dwrite_bool(f, _T("gfx_api_hdr"), p->gfx_api == 3);
  2163. cfgfile_write_str(f, _T("gfx_api_options"), filterapiopts[p->gfx_api_options]);
  2164. cfgfile_dwrite(f, _T("gfx_horizontal_extra"), _T("%d"), p->gfx_extrawidth);
  2165. cfgfile_dwrite(f, _T("gfx_vertical_extra"), _T("%d"), p->gfx_extraheight);
  2166. cfgfile_dwrite(f, _T("gfx_frame_slices"), _T("%d"), p->gfx_display_sections);
  2167. cfgfile_dwrite_bool(f, _T("gfx_vrr_monitor"), p->gfx_variable_sync != 0);
  2168. cfgfile_dwrite_str(f, _T("gfx_overscanmode"), overscanmodes[p->gfx_overscanmode]);
  2169. #ifdef GFXFILTER
  2170. for (int j = 0; j < 2; j++) {
  2171. struct gfx_filterdata *gf = &p->gf[j];
  2172. const TCHAR *ext = j == 0 ? NULL : _T("_rtg");
  2173. for (int i = 0; i <MAX_FILTERSHADERS; i++) {
  2174. if (gf->gfx_filtershader[i][0])
  2175. cfgfile_write_ext (f, _T("gfx_filter_pre"), ext, _T("D3D:%s"), gf->gfx_filtershader[i]);
  2176. if (gf->gfx_filtermask[i][0])
  2177. cfgfile_write_str (f, _T("gfx_filtermask_pre"), ext, gf->gfx_filtermask[i]);
  2178. }
  2179. for (int i = 0; i < MAX_FILTERSHADERS; i++) {
  2180. if (gf->gfx_filtershader[i + MAX_FILTERSHADERS][0])
  2181. cfgfile_write_ext (f, _T("gfx_filter_post"), ext, _T("D3D:%s"), gf->gfx_filtershader[i + MAX_FILTERSHADERS]);
  2182. if (gf->gfx_filtermask[i + MAX_FILTERSHADERS][0])
  2183. cfgfile_write_str (f, _T("gfx_filtermask_post"), ext, gf->gfx_filtermask[i + MAX_FILTERSHADERS]);
  2184. }
  2185. cfgfile_dwrite_str (f, _T("gfx_filter_mask"), ext, gf->gfx_filtermask[2 * MAX_FILTERSHADERS]);
  2186. {
  2187. bool d3dfound = false;
  2188. if (gf->gfx_filtershader[2 * MAX_FILTERSHADERS][0] && p->gfx_api) {
  2189. cfgfile_dwrite_ext (f, _T("gfx_filter"), ext, _T("D3D:%s"), gf->gfx_filtershader[2 * MAX_FILTERSHADERS]);
  2190. d3dfound = true;
  2191. }
  2192. if (!d3dfound) {
  2193. if (gf->gfx_filter > 0) {
  2194. int i = 0;
  2195. struct uae_filter *uf;
  2196. while (uaefilters[i].name) {
  2197. uf = &uaefilters[i];
  2198. if (uf->type == gf->gfx_filter) {
  2199. cfgfile_dwrite_str (f, _T("gfx_filter"), ext, uf->cfgname);
  2200. }
  2201. i++;
  2202. }
  2203. } else {
  2204. cfgfile_dwrite_ext (f, _T("gfx_filter"), ext, _T("no"));
  2205. }
  2206. }
  2207. }
  2208. cfgfile_dwrite_str(f, _T("gfx_filter_mode"), ext, filtermode2[gf->gfx_filter_filtermodeh]);
  2209. cfgfile_dwrite_str(f, _T("gfx_filter_mode2"), ext, filtermode2v[gf->gfx_filter_filtermodev]);
  2210. cfgfile_dwrite_ext (f, _T("gfx_filter_vert_zoomf"), ext, _T("%f"), gf->gfx_filter_vert_zoom);
  2211. cfgfile_dwrite_ext (f, _T("gfx_filter_horiz_zoomf"), ext, _T("%f"), gf->gfx_filter_horiz_zoom);
  2212. cfgfile_dwrite_ext (f, _T("gfx_filter_vert_zoom_multf"), ext, _T("%f"), gf->gfx_filter_vert_zoom_mult);
  2213. cfgfile_dwrite_ext (f, _T("gfx_filter_horiz_zoom_multf"), ext, _T("%f"), gf->gfx_filter_horiz_zoom_mult);
  2214. cfgfile_dwrite_ext (f, _T("gfx_filter_vert_offsetf"), ext, _T("%f"), gf->gfx_filter_vert_offset);
  2215. cfgfile_dwrite_ext (f, _T("gfx_filter_horiz_offsetf"), ext, _T("%f"), gf->gfx_filter_horiz_offset);
  2216. cfgfile_dwrite_ext (f, _T("gfx_filter_left_border"), ext, _T("%d"), gf->gfx_filter_left_border);
  2217. cfgfile_dwrite_ext (f, _T("gfx_filter_right_border"), ext, _T("%d"), gf->gfx_filter_right_border);
  2218. cfgfile_dwrite_ext (f, _T("gfx_filter_top_border"), ext, _T("%d"), gf->gfx_filter_top_border);
  2219. cfgfile_dwrite_ext (f, _T("gfx_filter_bottom_border"), ext, _T("%d"), gf->gfx_filter_bottom_border);
  2220. cfgfile_dwrite_ext(f, _T("gfx_filter_scanlines"), ext, _T("%d"), gf->gfx_filter_scanlines);
  2221. cfgfile_dwrite_ext(f, _T("gfx_filter_scanlinelevel"), ext, _T("%d"), gf->gfx_filter_scanlinelevel);
  2222. cfgfile_dwrite_ext(f, _T("gfx_filter_scanlineratio"), ext, _T("%d"), gf->gfx_filter_scanlineratio);
  2223. cfgfile_dwrite_ext(f, _T("gfx_filter_scanlineoffset"), ext, _T("%d"), gf->gfx_filter_scanlineoffset);
  2224. cfgfile_dwrite_ext (f, _T("gfx_filter_luminance"), ext, _T("%d"), gf->gfx_filter_luminance);
  2225. cfgfile_dwrite_ext (f, _T("gfx_filter_contrast"), ext, _T("%d"), gf->gfx_filter_contrast);
  2226. cfgfile_dwrite_ext (f, _T("gfx_filter_saturation"), ext, _T("%d"), gf->gfx_filter_saturation);
  2227. cfgfile_dwrite_ext (f, _T("gfx_filter_gamma"), ext, _T("%d"), gf->gfx_filter_gamma);
  2228. cfgfile_dwrite_ext (f, _T("gfx_filter_gamma_r"), ext, _T("%d"), gf->gfx_filter_gamma_ch[0]);
  2229. cfgfile_dwrite_ext (f, _T("gfx_filter_gamma_g"), ext, _T("%d"), gf->gfx_filter_gamma_ch[1]);
  2230. cfgfile_dwrite_ext (f, _T("gfx_filter_gamma_b"), ext, _T("%d"), gf->gfx_filter_gamma_ch[2]);
  2231. cfgfile_dwrite_ext (f, _T("gfx_filter_blur"), ext, _T("%d"), gf->gfx_filter_blur);
  2232. cfgfile_dwrite_ext (f, _T("gfx_filter_noise"), ext, _T("%d"), gf->gfx_filter_noise);
  2233. cfgfile_dwrite_bool (f, _T("gfx_filter_bilinear"), ext, gf->gfx_filter_bilinear != 0);
  2234. cfgfile_dwrite_ext (f, _T("gfx_filter_keep_autoscale_aspect"), ext, _T("%d"), gf->gfx_filter_keep_autoscale_aspect);
  2235. cfgfile_dwrite_str (f, _T("gfx_filter_keep_aspect"), ext, aspects[gf->gfx_filter_keep_aspect]);
  2236. cfgfile_dwrite_str(f, _T("gfx_filter_autoscale"), ext, ext == NULL ? autoscale[gf->gfx_filter_autoscale] : autoscale_rtg[gf->gfx_filter_autoscale]);
  2237. cfgfile_dwrite_str (f, _T("gfx_filter_autoscale_limit"), ext, autoscalelimit[gf->gfx_filter_integerscalelimit]);
  2238. cfgfile_dwrite_ext (f, _T("gfx_filter_aspect_ratio"), ext, _T("%d:%d"),
  2239. gf->gfx_filter_aspect >= 0 ? (gf->gfx_filter_aspect / ASPECTMULT) : -1,
  2240. gf->gfx_filter_aspect >= 0 ? (gf->gfx_filter_aspect & (ASPECTMULT - 1)) : -1);
  2241. if (gf->gfx_filteroverlay[0]) {
  2242. cfgfile_dwrite_ext(f, _T("gfx_filter_overlay"), ext, _T("%s%s"),
  2243. gf->gfx_filteroverlay, _tcschr (gf->gfx_filteroverlay, ',') ? _T(",") : _T(""));
  2244. }
  2245. }
  2246. cfgfile_dwrite (f, _T("gfx_luminance"), _T("%d"), p->gfx_luminance);
  2247. cfgfile_dwrite (f, _T("gfx_contrast"), _T("%d"), p->gfx_contrast);
  2248. cfgfile_dwrite (f, _T("gfx_gamma"), _T("%d"), p->gfx_gamma);
  2249. cfgfile_dwrite (f, _T("gfx_gamma_r"), _T("%d"), p->gfx_gamma_ch[0]);
  2250. cfgfile_dwrite (f, _T("gfx_gamma_g"), _T("%d"), p->gfx_gamma_ch[1]);
  2251. cfgfile_dwrite (f, _T("gfx_gamma_b"), _T("%d"), p->gfx_gamma_ch[2]);
  2252. cfgfile_dwrite (f, _T("gfx_center_horizontal_position"), _T("%d"), p->gfx_xcenter_pos);
  2253. cfgfile_dwrite (f, _T("gfx_center_vertical_position"), _T("%d"), p->gfx_ycenter_pos);
  2254. cfgfile_dwrite (f, _T("gfx_center_horizontal_size"), _T("%d"), p->gfx_xcenter_size);
  2255. cfgfile_dwrite (f, _T("gfx_center_vertical_size"), _T("%d"), p->gfx_ycenter_size);
  2256. cfgfile_dwrite (f, _T("rtg_vert_zoom_multf"), _T("%.f"), p->rtg_vert_zoom_mult);
  2257. cfgfile_dwrite (f, _T("rtg_horiz_zoom_multf"), _T("%.f"), p->rtg_horiz_zoom_mult);
  2258. #endif
  2259. cfgfile_write_bool (f, _T("immediate_blits"), p->immediate_blits);
  2260. cfgfile_dwrite_str (f, _T("waiting_blits"), waitblits[p->waiting_blits]);
  2261. cfgfile_dwrite (f, _T("blitter_throttle"), _T("%.8f"), p->blitter_speed_throttle);
  2262. cfgfile_write_bool (f, _T("ntsc"), p->ntscmode);
  2263. cfgfile_write_bool(f, _T("genlock"), p->genlock);
  2264. cfgfile_dwrite_bool(f, _T("genlock_alpha"), p->genlock_alpha);
  2265. cfgfile_dwrite_bool(f, _T("genlock_aspect"), p->genlock_aspect);
  2266. cfgfile_dwrite_str(f, _T("genlockmode"), genlockmodes[p->genlock_image]);
  2267. cfgfile_dwrite_str(f, _T("genlock_image"), p->genlock_image_file);
  2268. cfgfile_dwrite_str(f, _T("genlock_video"), p->genlock_video_file);
  2269. cfgfile_dwrite(f, _T("genlock_mix"), _T("%d"), p->genlock_mix);
  2270. cfgfile_dwrite(f, _T("genlock_scale"), _T("%d"), p->genlock_scale);
  2271. cfgfile_dwrite_str(f, _T("monitoremu"), specialmonitorconfignames[p->monitoremu]);
  2272. cfgfile_dwrite(f, _T("monitoremu_monitor"), _T("%d"), p->monitoremu_mon);
  2273. cfgfile_dwrite_coords(f, _T("lightpen_offset"), p->lightpen_offset[0], p->lightpen_offset[1]);
  2274. cfgfile_dwrite_bool(f, _T("lightpen_crosshair"), p->lightpen_crosshair);
  2275. cfgfile_dwrite_bool (f, _T("show_leds"), !!(p->leds_on_screen & STATUSLINE_CHIPSET));
  2276. cfgfile_dwrite_bool (f, _T("show_leds_rtg"), !!(p->leds_on_screen & STATUSLINE_RTG));
  2277. write_leds(f, _T("show_leds_enabled"), p->leds_on_screen_mask[0]);
  2278. write_leds(f, _T("show_leds_enabled_rtg"), p->leds_on_screen_mask[1]);
  2279. for (int i = 0; i < 2; i++) {
  2280. if (p->leds_on_screen_multiplier[i] > 0) {
  2281. cfgfile_dwrite(f, i ? _T("show_leds_size_rtg") : _T("show_leds_size"), _T("%.2f"), p->leds_on_screen_multiplier[i] / 100.0);
  2282. }
  2283. }
  2284. cfgfile_dwrite_bool(f, _T("show_refresh_indicator"), p->refresh_indicator);
  2285. cfgfile_dwrite(f, _T("power_led_dim"), _T("%d"), p->power_led_dim);
  2286. if (p->osd_pos.y || p->osd_pos.x) {
  2287. cfgfile_dwrite (f, _T("osd_position"), _T("%.1f%s:%.1f%s"),
  2288. p->osd_pos.x >= 20000 ? (p->osd_pos.x - 30000) / 10.0 : (float)p->osd_pos.x, p->osd_pos.x >= 20000 ? _T("%") : _T(""),
  2289. p->osd_pos.y >= 20000 ? (p->osd_pos.y - 30000) / 10.0 : (float)p->osd_pos.y, p->osd_pos.y >= 20000 ? _T("%") : _T(""));
  2290. }
  2291. cfgfile_dwrite (f, _T("keyboard_leds"), _T("numlock:%s,capslock:%s,scrolllock:%s"),
  2292. kbleds[p->keyboard_leds[0]], kbleds[p->keyboard_leds[1]], kbleds[p->keyboard_leds[2]]);
  2293. if (p->chipset_mask & CSMASK_AGA)
  2294. cfgfile_write (f, _T("chipset"),_T("aga"));
  2295. else if ((p->chipset_mask & CSMASK_ECS_AGNUS) && (p->chipset_mask & CSMASK_ECS_DENISE))
  2296. cfgfile_write (f, _T("chipset"),_T("ecs"));
  2297. else if (p->chipset_mask & CSMASK_ECS_AGNUS)
  2298. cfgfile_write (f, _T("chipset"),_T("ecs_agnus"));
  2299. else if (p->chipset_mask & CSMASK_ECS_DENISE)
  2300. cfgfile_write (f, _T("chipset"),_T("ecs_denise"));
  2301. else
  2302. cfgfile_write (f, _T("chipset"), _T("ocs"));
  2303. if (p->chipset_refreshrate > 0)
  2304. cfgfile_write (f, _T("chipset_refreshrate"), _T("%f"), p->chipset_refreshrate);
  2305. cfgfile_dwrite_bool(f, _T("chipset_subpixel"), p->chipset_hr);
  2306. for (int i = 0; i < MAX_CHIPSET_REFRESH_TOTAL; i++) {
  2307. struct chipset_refresh *cr = &p->cr[i];
  2308. if (!cr->inuse)
  2309. continue;
  2310. cr->index = i;
  2311. if (cr->rate == 0)
  2312. _tcscpy(tmp, _T("0"));
  2313. else
  2314. _stprintf (tmp, _T("%f"), cr->rate);
  2315. TCHAR *s = tmp + _tcslen (tmp);
  2316. if (cr->label[0] > 0 && i < MAX_CHIPSET_REFRESH)
  2317. s += _stprintf (s, _T(",t=%s"), cr->label);
  2318. if (cr->horiz > 0)
  2319. s += _stprintf (s, _T(",h=%d"), cr->horiz);
  2320. if (cr->vert > 0)
  2321. s += _stprintf (s, _T(",v=%d"), cr->vert);
  2322. if (cr->locked)
  2323. _tcscat (s, _T(",locked"));
  2324. if (cr->ntsc == 1)
  2325. _tcscat (s, _T(",ntsc"));
  2326. else if (cr->ntsc == 0)
  2327. _tcscat (s, _T(",pal"));
  2328. else if (cr->ntsc == 2)
  2329. _tcscat(s, _T(",custom"));
  2330. if (cr->lace > 0)
  2331. _tcscat (s, _T(",lace"));
  2332. else if (cr->lace == 0)
  2333. _tcscat (s, _T(",nlace"));
  2334. if ((cr->resolution & 7) != 7) {
  2335. if (cr->resolution & 1)
  2336. _tcscat(s, _T(",lores"));
  2337. if (cr->resolution & 2)
  2338. _tcscat(s, _T(",hires"));
  2339. if (cr->resolution & 4)
  2340. _tcscat(s, _T(",shres"));
  2341. if (cr->resolution_pct > 0 && cr->resolution_pct < 100)
  2342. s += _stprintf(s, _T("rpct=%d"), cr->resolution_pct);
  2343. }
  2344. if (cr->framelength > 0)
  2345. _tcscat (s, _T(",lof"));
  2346. else if (cr->framelength == 0)
  2347. _tcscat (s, _T(",shf"));
  2348. if (cr->vsync > 0)
  2349. _tcscat (s, _T(",vsync"));
  2350. else if (cr->vsync == 0)
  2351. _tcscat (s, _T(",nvsync"));
  2352. if (cr->rtg)
  2353. _tcscat (s, _T(",rtg"));
  2354. if (cr->exit)
  2355. _tcscat(s, _T(",exit"));
  2356. if (cr->defaultdata)
  2357. _tcscat(s, _T(",default"));
  2358. if (cr->filterprofile[0]) {
  2359. TCHAR *se = cfgfile_escape(cr->filterprofile, _T(","), true);
  2360. s += _stprintf(s, _T(",filter=%s"), se);
  2361. xfree(se);
  2362. }
  2363. if (cr->commands[0]) {
  2364. _tcscat (s, _T(",cmd="));
  2365. _tcscat (s, cr->commands);
  2366. for (int j = 0; j < _tcslen (s); j++) {
  2367. if (s[j] == '\n')
  2368. s[j] = ',';
  2369. }
  2370. s[_tcslen (s) - 1] = 0;
  2371. }
  2372. if (i == CHIPSET_REFRESH_PAL) {
  2373. if (cr->locked)
  2374. cfgfile_dwrite (f, _T("displaydata_pal"), tmp);
  2375. } else if (i == CHIPSET_REFRESH_NTSC) {
  2376. if (cr->locked)
  2377. cfgfile_dwrite (f, _T("displaydata_ntsc"), tmp);
  2378. } else {
  2379. cfgfile_dwrite (f, _T("displaydata"), tmp);
  2380. }
  2381. }
  2382. cfgfile_write_str (f, _T("collision_level"), collmode[p->collision_level]);
  2383. cfgfile_write_str(f, _T("chipset_compatible"), cscompa[p->cs_compatible]);
  2384. cfgfile_dwrite_str(f, _T("ciaatod"), ciaatodmode[p->cs_ciaatod]);
  2385. cfgfile_dwrite_str(f, _T("rtc"), rtctype[p->cs_rtc]);
  2386. cfgfile_dwrite (f, _T("chipset_rtc_adjust"), _T("%d"), p->cs_rtc_adjust);
  2387. cfgfile_dwrite_bool(f, _T("ksmirror_e0"), p->cs_ksmirror_e0);
  2388. cfgfile_dwrite_bool(f, _T("ksmirror_a8"), p->cs_ksmirror_a8);
  2389. cfgfile_dwrite_bool(f, _T("cd32cd"), p->cs_cd32cd);
  2390. cfgfile_dwrite_bool(f, _T("cd32c2p"), p->cs_cd32c2p);
  2391. cfgfile_dwrite_bool(f, _T("cd32nvram"), p->cs_cd32nvram);
  2392. cfgfile_dwrite(f, _T("cd32nvram_size"), _T("%d"), p->cs_cd32nvram_size / 1024);
  2393. cfgfile_dwrite_bool(f, _T("cdtvcd"), p->cs_cdtvcd);
  2394. cfgfile_dwrite_bool(f, _T("cdtv-cr"), p->cs_cdtvcr);
  2395. cfgfile_dwrite_bool(f, _T("cdtvram"), p->cs_cdtvram);
  2396. cfgfile_dwrite_bool(f, _T("a1000ram"), p->cs_a1000ram);
  2397. cfgfile_dwrite(f, _T("fatgary"), _T("%d"), p->cs_fatgaryrev);
  2398. cfgfile_dwrite(f, _T("ramsey"), _T("%d"), p->cs_ramseyrev);
  2399. cfgfile_dwrite_bool(f, _T("pcmcia"), p->cs_pcmcia);
  2400. cfgfile_dwrite_bool(f, _T("bogomem_fast"), p->cs_slowmemisfast);
  2401. cfgfile_dwrite_bool(f, _T("resetwarning"), p->cs_resetwarning);
  2402. cfgfile_dwrite_bool(f, _T("denise_noehb"), p->cs_denisenoehb);
  2403. cfgfile_dwrite_bool(f, _T("agnus_bltbusybug"), p->cs_agnusbltbusybug);
  2404. cfgfile_dwrite_bool(f, _T("bkpt_halt"), p->cs_bkpthang);
  2405. cfgfile_dwrite_bool(f, _T("ics_agnus"), p->cs_dipagnus);
  2406. cfgfile_dwrite_bool(f, _T("cia_todbug"), p->cs_ciatodbug);
  2407. cfgfile_dwrite_bool(f, _T("z3_autoconfig"), p->cs_z3autoconfig);
  2408. cfgfile_dwrite_bool(f, _T("1mchipjumper"), p->cs_1mchipjumper);
  2409. cfgfile_dwrite_bool(f, _T("color_burst"), p->cs_color_burst);
  2410. cfgfile_dwrite_bool(f, _T("toshiba_gary"), p->cs_toshibagary);
  2411. cfgfile_dwrite_bool(f, _T("rom_is_slow"), p->cs_romisslow);
  2412. cfgfile_dwrite_str(f, _T("ciaa_type"), ciatype[p->cs_ciatype[0]]);
  2413. cfgfile_dwrite_str(f, _T("ciab_type"), ciatype[p->cs_ciatype[1]]);
  2414. cfgfile_dwrite_str(f, _T("unmapped_address_space"), unmapped[p->cs_unmapped_space]);
  2415. cfgfile_dwrite(f, _T("keyboard_handshake"), _T("%d"), currprefs.cs_kbhandshake);
  2416. cfgfile_dwrite (f, _T("chipset_hacks"), _T("0x%x"), p->cs_hacks);
  2417. if (is_board_enabled(p, ROMTYPE_CD32CART, 0)) {
  2418. cfgfile_dwrite_bool(f, _T("cd32fmv"), true);
  2419. }
  2420. if (is_board_enabled(p, ROMTYPE_MB_IDE, 0) && p->cs_ide == 1) {
  2421. cfgfile_dwrite_str(f, _T("ide"), _T("a600/a1200"));
  2422. }
  2423. if (is_board_enabled(p, ROMTYPE_MB_IDE, 0) && p->cs_ide == 2) {
  2424. cfgfile_dwrite_str(f, _T("ide"), _T("a4000"));
  2425. }
  2426. if (is_board_enabled(p, ROMTYPE_CDTVSCSI, 0)) {
  2427. cfgfile_dwrite_bool(f, _T("scsi_cdtv"), true);
  2428. }
  2429. if (is_board_enabled(p, ROMTYPE_SCSI_A3000, 0)) {
  2430. cfgfile_dwrite_bool(f, _T("scsi_a3000"), true);
  2431. }
  2432. if (is_board_enabled(p, ROMTYPE_SCSI_A4000T, 0)) {
  2433. cfgfile_dwrite_bool(f, _T("scsi_a4000t"), true);
  2434. }
  2435. cfgfile_dwrite_str (f, _T("z3mapping"), z3mapping[p->z3_mapping_mode]);
  2436. cfgfile_dwrite_bool(f, _T("board_custom_order"), p->autoconfig_custom_sort);
  2437. for (int i = 0; i < MAX_RAM_BOARDS; i++) {
  2438. if (p->fastmem[i].size < 0x100000 && p->fastmem[i].size) {
  2439. if (i > 0)
  2440. _stprintf(tmp, _T("fastmem%d_size_k"), i + 1);
  2441. else
  2442. _tcscpy(tmp, _T("fastmem_size_k"));
  2443. cfgfile_write(f, tmp, _T("%d"), p->fastmem[i].size / 1024);
  2444. } else if (p->fastmem[i].size || i == 0) {
  2445. if (i > 0)
  2446. _stprintf(tmp, _T("fastmem%d_size"), i + 1);
  2447. else
  2448. _tcscpy(tmp, _T("fastmem_size"));
  2449. cfgfile_write(f, tmp, _T("%d"), p->fastmem[i].size / 0x100000);
  2450. }
  2451. cfgfile_writeramboard(p, f, _T("fastmem"), i, &p->fastmem[i]);
  2452. }
  2453. cfgfile_write(f, _T("debugmem_start"), _T("0x%x"), p->debugmem_start);
  2454. cfgfile_write(f, _T("debugmem_size"), _T("%d"), p->debugmem_size / 0x100000);
  2455. cfgfile_write(f, _T("mem25bit_size"), _T("%d"), p->mem25bit.size / 0x100000);
  2456. cfgfile_writeramboard(p, f, _T("mem25bit"), 0, &p->mem25bit);
  2457. cfgfile_write(f, _T("a3000mem_size"), _T("%d"), p->mbresmem_low.size / 0x100000);
  2458. cfgfile_writeramboard(p, f, _T("a3000mem"), 0, &p->mbresmem_low);
  2459. cfgfile_write(f, _T("mbresmem_size"), _T("%d"), p->mbresmem_high.size / 0x100000);
  2460. cfgfile_writeramboard(p, f, _T("mbresmem"), 0, &p->mbresmem_high);
  2461. for (int i = 0; i < MAX_RAM_BOARDS; i++) {
  2462. if (i == 0 || p->z3fastmem[i].size) {
  2463. if (i > 0)
  2464. _stprintf(tmp, _T("z3mem%d_size"), i + 1);
  2465. else
  2466. _tcscpy(tmp, _T("z3mem_size"));
  2467. cfgfile_write(f, tmp, _T("%d"), p->z3fastmem[i].size / 0x100000);
  2468. }
  2469. cfgfile_writeramboard(p, f, _T("z3mem"), i, &p->z3fastmem[i]);
  2470. }
  2471. cfgfile_write(f, _T("z3mem_start"), _T("0x%x"), p->z3autoconfig_start);
  2472. cfgfile_write(f, _T("bogomem_size"), _T("%d"), p->bogomem.size / 0x40000);
  2473. cfgfile_writeramboard(p, f, _T("bogomem"), 0, &p->bogomem);
  2474. if (p->cpuboard_type) {
  2475. const struct cpuboardtype *cbt = &cpuboards[p->cpuboard_type];
  2476. const struct cpuboardsubtype *cbst = &cbt->subtypes[p->cpuboard_subtype];
  2477. const struct expansionboardsettings *cbs = cbst->settings;
  2478. cfgfile_dwrite_str(f, _T("cpuboard_type"), cbst->configname);
  2479. if (cbs && p->cpuboard_settings) {
  2480. tmp[0] = 0;
  2481. cfgfile_write_rom_settings(cbs, tmp, p->cpuboard_settings, NULL);
  2482. cfgfile_dwrite_str(f, _T("cpuboard_settings"), tmp);
  2483. }
  2484. } else {
  2485. cfgfile_dwrite_str(f, _T("cpuboard_type"), _T("none"));
  2486. }
  2487. cfgfile_dwrite(f, _T("cpuboardmem1_size"), _T("%d"), p->cpuboardmem1.size / 0x100000);
  2488. cfgfile_writeramboard(p, f, _T("cpuboardmem1"), 0, &p->cpuboardmem1);
  2489. cfgfile_dwrite(f, _T("cpuboardmem2_size"), _T("%d"), p->cpuboardmem2.size / 0x100000);
  2490. cfgfile_writeramboard(p, f, _T("cpuboardmem2"), 0, &p->cpuboardmem2);
  2491. cfgfile_write_bool(f, _T("gfxcard_hardware_vblank"), p->rtg_hardwareinterrupt);
  2492. cfgfile_write_bool(f, _T("gfxcard_hardware_sprite"), p->rtg_hardwaresprite);
  2493. cfgfile_write_bool(f, _T("gfxcard_multithread"), p->rtg_multithread);
  2494. for (int i = 0; i < MAX_RTG_BOARDS; i++) {
  2495. TCHAR tmp2[100];
  2496. struct rtgboardconfig *rbc = &p->rtgboards[i];
  2497. if (rbc->rtgmem_size) {
  2498. if (i > 0)
  2499. _stprintf(tmp, _T("gfxcard%d_size"), i + 1);
  2500. else
  2501. _tcscpy(tmp, _T("gfxcard_size"));
  2502. cfgfile_write(f, tmp, _T("%d"), rbc->rtgmem_size / 0x100000);
  2503. if (i > 0)
  2504. _stprintf(tmp, _T("gfxcard%d_type"), i + 1);
  2505. else
  2506. _tcscpy(tmp, _T("gfxcard_type"));
  2507. cfgfile_dwrite_str(f, tmp, gfxboard_get_configname(rbc->rtgmem_type));
  2508. tmp2[0] = 0;
  2509. if (rbc->device_order > 0 && p->autoconfig_custom_sort) {
  2510. _stprintf(tmp2, _T("order=%d"), rbc->device_order);
  2511. }
  2512. if (rbc->monitor_id) {
  2513. if (tmp2)
  2514. _tcscat(tmp2, _T(","));
  2515. _stprintf(tmp2 + _tcslen(tmp2), _T("monitor=%d"), rbc->monitor_id);
  2516. }
  2517. if (tmp2[0]) {
  2518. if (i > 0)
  2519. _stprintf(tmp, _T("gfxcard%d_options"), i + 1);
  2520. else
  2521. _tcscpy(tmp, _T("gfxcard_options"));
  2522. cfgfile_dwrite_str(f, tmp, tmp2);
  2523. }
  2524. }
  2525. }
  2526. cfgfile_write (f, _T("chipmem_size"), _T("%d"), p->chipmem.size == 0x20000 ? -1 : (p->chipmem.size == 0x40000 ? 0 : p->chipmem.size / 0x80000));
  2527. cfgfile_writeramboard(p, f, _T("chipmem"), 0, &p->chipmem);
  2528. cfgfile_dwrite (f, _T("megachipmem_size"), _T("%d"), p->z3chipmem.size / 0x100000);
  2529. cfgfile_writeramboard(p, f, _T("megachipmem"), 0, &p->z3chipmem);
  2530. // do not save aros rom special space
  2531. if (!(p->custom_memory_sizes[0] == 512 * 1024 && p->custom_memory_sizes[1] == 512 * 1024 && p->custom_memory_addrs[0] == 0xa80000 && p->custom_memory_addrs[1] == 0xb00000)) {
  2532. if (p->custom_memory_sizes[0])
  2533. cfgfile_write (f, _T("addmem1"), _T("0x%x,0x%x"), p->custom_memory_addrs[0], p->custom_memory_sizes[0]);
  2534. if (p->custom_memory_sizes[1])
  2535. cfgfile_write (f, _T("addmem2"), _T("0x%x,0x%x"), p->custom_memory_addrs[1], p->custom_memory_sizes[1]);
  2536. }
  2537. if (p->m68k_speed > 0) {
  2538. cfgfile_write (f, _T("finegrain_cpu_speed"), _T("%d"), p->m68k_speed);
  2539. } else {
  2540. cfgfile_write_str (f, _T("cpu_speed"), p->m68k_speed < 0 ? _T("max") : _T("real"));
  2541. }
  2542. cfgfile_write (f, _T("cpu_throttle"), _T("%.1f"), p->m68k_speed_throttle);
  2543. cfgfile_dwrite(f, _T("cpu_x86_throttle"), _T("%.1f"), p->x86_speed_throttle);
  2544. /* do not reorder start */
  2545. write_compatibility_cpu(f, p);
  2546. cfgfile_write (f, _T("cpu_model"), _T("%d"), p->cpu_model);
  2547. if (p->fpu_model)
  2548. cfgfile_write (f, _T("fpu_model"), _T("%d"), p->fpu_model);
  2549. if (p->mmu_model) {
  2550. if (p->mmu_ec)
  2551. cfgfile_write (f, _T("mmu_model"), _T("68ec0%d"), p->mmu_model % 100);
  2552. else
  2553. cfgfile_write (f, _T("mmu_model"), _T("%d"), p->mmu_model);
  2554. }
  2555. if (p->ppc_mode) {
  2556. cfgfile_write_str(f, _T("ppc_model"), p->ppc_model[0] ? p->ppc_model : (p->ppc_mode == 1 ? _T("automatic") : _T("manual")));
  2557. cfgfile_write_str(f, _T("ppc_cpu_idle"), ppc_cpu_idle[p->ppc_cpu_idle]);
  2558. }
  2559. cfgfile_write_bool (f, _T("cpu_compatible"), p->cpu_compatible);
  2560. cfgfile_write_bool (f, _T("cpu_24bit_addressing"), p->address_space_24);
  2561. cfgfile_write_bool (f, _T("cpu_data_cache"), p->cpu_data_cache);
  2562. /* do not reorder end */
  2563. cfgfile_dwrite_bool(f, _T("cpu_reset_pause"), p->reset_delay);
  2564. cfgfile_dwrite_bool(f, _T("cpu_halt_auto_reset"), p->crash_auto_reset);
  2565. cfgfile_dwrite_bool(f, _T("cpu_threaded"), p->cpu_thread);
  2566. if (p->ppc_mode)
  2567. cfgfile_write_str(f, _T("ppc_implementation"), ppc_implementations[p->ppc_implementation]);
  2568. if (p->cpu_cycle_exact) {
  2569. if (p->cpu_frequency)
  2570. cfgfile_write(f, _T("cpu_frequency"), _T("%d"), p->cpu_frequency);
  2571. }
  2572. if (p->cpu_compatible) {
  2573. if (p->m68k_speed == 0 && p->cpu_clock_multiplier >= 256) {
  2574. cfgfile_write(f, _T("cpu_multiplier"), _T("%d"), p->cpu_clock_multiplier / 256);
  2575. }
  2576. }
  2577. cfgfile_write_bool (f, _T("cpu_cycle_exact"), p->cpu_cycle_exact);
  2578. // must be after cpu_cycle_exact
  2579. cfgfile_write_bool (f, _T("cpu_memory_cycle_exact"), p->cpu_memory_cycle_exact);
  2580. cfgfile_write_bool (f, _T("blitter_cycle_exact"), p->blitter_cycle_exact);
  2581. // must be after cpu_cycle_exact, cpu_memory_cycle_exact and blitter_cycle_exact
  2582. if (p->cpu_cycle_exact && p->blitter_cycle_exact)
  2583. cfgfile_write_str (f, _T("cycle_exact"), cycleexact[2]);
  2584. else if (p->cpu_memory_cycle_exact && p->blitter_cycle_exact)
  2585. cfgfile_write_str (f, _T("cycle_exact"), cycleexact[1]);
  2586. else
  2587. cfgfile_write_str (f, _T("cycle_exact"), cycleexact[0]);
  2588. cfgfile_dwrite_bool (f, _T("fpu_no_unimplemented"), p->fpu_no_unimplemented);
  2589. cfgfile_dwrite_bool (f, _T("cpu_no_unimplemented"), p->int_no_unimplemented);
  2590. cfgfile_write_bool (f, _T("fpu_strict"), p->fpu_strict);
  2591. cfgfile_dwrite_bool (f, _T("fpu_softfloat"), p->fpu_mode > 0);
  2592. #ifdef MSVC_LONG_DOUBLE
  2593. cfgfile_dwrite_bool(f, _T("fpu_msvc_long_double"), p->fpu_mode < 0);
  2594. #endif
  2595. cfgfile_write_bool (f, _T("rtg_nocustom"), p->picasso96_nocustom);
  2596. cfgfile_write (f, _T("rtg_modes"), _T("0x%x"), p->picasso96_modeflags);
  2597. cfgfile_write_bool(f, _T("debug_mem"), p->debug_mem);
  2598. cfgfile_write_bool(f, _T("log_illegal_mem"), p->illegal_mem);
  2599. #if 0
  2600. if (p->catweasel >= 100)
  2601. cfgfile_dwrite (f, _T("catweasel"), _T("0x%x"), p->catweasel);
  2602. else
  2603. cfgfile_dwrite (f, _T("catweasel"), _T("%d"), p->catweasel);
  2604. cfgfile_write_bool(f, _T("toccata"), p->obs_sound_toccata);
  2605. if (p->obs_sound_toccata_mixer)
  2606. cfgfile_write_bool(f, _T("toccata_mixer"), p->obs_sound_toccata_mixer);
  2607. cfgfile_write_bool(f, _T("es1370_pci"), p->obs_sound_es1370);
  2608. cfgfile_write_bool(f, _T("fm801_pci"), p->obs_sound_fm801);
  2609. #endif
  2610. cfgfile_dwrite_bool(f, _T("keyboard_connected"), p->keyboard_connected);
  2611. cfgfile_write_str (f, _T("kbd_lang"), (p->keyboard_lang == KBD_LANG_DE ? _T("de")
  2612. : p->keyboard_lang == KBD_LANG_DK ? _T("dk")
  2613. : p->keyboard_lang == KBD_LANG_ES ? _T("es")
  2614. : p->keyboard_lang == KBD_LANG_US ? _T("us")
  2615. : p->keyboard_lang == KBD_LANG_SE ? _T("se")
  2616. : p->keyboard_lang == KBD_LANG_FR ? _T("fr")
  2617. : p->keyboard_lang == KBD_LANG_IT ? _T("it")
  2618. : _T("FOO")));
  2619. cfgfile_dwrite (f, _T("state_replay_rate"), _T("%d"), p->statecapturerate);
  2620. cfgfile_dwrite (f, _T("state_replay_buffers"), _T("%d"), p->statecapturebuffersize);
  2621. cfgfile_dwrite_bool (f, _T("state_replay_autoplay"), p->inprec_autoplay);
  2622. cfgfile_dwrite_bool (f, _T("warp"), p->turbo_emulation);
  2623. cfgfile_dwrite (f, _T("warp_limit"), _T("%d"), p->turbo_emulation_limit);
  2624. #ifdef FILESYS
  2625. write_filesys_config (p, f);
  2626. if (p->filesys_no_uaefsdb)
  2627. cfgfile_write_bool (f, _T("filesys_no_fsdb"), p->filesys_no_uaefsdb);
  2628. cfgfile_dwrite (f, _T("filesys_max_size"), _T("%d"), p->filesys_limit);
  2629. cfgfile_dwrite (f, _T("filesys_max_name_length"), _T("%d"), p->filesys_max_name);
  2630. cfgfile_dwrite (f, _T("filesys_max_file_size"), _T("%d"), p->filesys_max_file_size);
  2631. cfgfile_dwrite_bool (f, _T("filesys_inject_icons"), p->filesys_inject_icons);
  2632. cfgfile_dwrite_str (f, _T("filesys_inject_icons_drawer"), p->filesys_inject_icons_drawer);
  2633. cfgfile_dwrite_str (f, _T("filesys_inject_icons_project"), p->filesys_inject_icons_project);
  2634. cfgfile_dwrite_str (f, _T("filesys_inject_icons_tool"), p->filesys_inject_icons_tool);
  2635. cfgfile_dwrite_str (f, _T("scsidev_mode"), uaescsidevmodes[p->uaescsidevmode]);
  2636. #endif
  2637. cfgfile_dwrite_bool(f, _T("harddrive_write_protect"), p->harddrive_read_only);
  2638. write_inputdevice_config (p, f);
  2639. }
  2640. static int cfgfile_coords(const TCHAR *option, const TCHAR *value, const TCHAR *name, int *x, int *y)
  2641. {
  2642. if (name != NULL && _tcscmp (option, name) != 0)
  2643. return 0;
  2644. TCHAR tmp[MAX_DPATH];
  2645. _tcscpy(tmp, value);
  2646. TCHAR *p = _tcschr(tmp, ',');
  2647. if (!p)
  2648. return 0;
  2649. *p++ = 0;
  2650. *x = _tstol(tmp);
  2651. *y = _tstol(p);
  2652. return 1;
  2653. }
  2654. static int cfgfile_yesno (const TCHAR *option, const TCHAR *value, const TCHAR *name, int *location, bool numbercheck)
  2655. {
  2656. if (name != NULL && _tcscmp (option, name) != 0)
  2657. return 0;
  2658. if (strcasecmp (value, _T("yes")) == 0 || strcasecmp (value, _T("y")) == 0
  2659. || strcasecmp (value, _T("true")) == 0 || strcasecmp (value, _T("t")) == 0
  2660. || (numbercheck && strcasecmp (value, _T("1")) == 0))
  2661. *location = 1;
  2662. else if (strcasecmp (value, _T("no")) == 0 || strcasecmp (value, _T("n")) == 0
  2663. || strcasecmp (value, _T("false")) == 0 || strcasecmp (value, _T("f")) == 0
  2664. || (numbercheck && strcasecmp (value, _T("0")) == 0))
  2665. *location = 0;
  2666. else {
  2667. cfgfile_warning(_T("Option '%s' requires a value of either 'true' or 'false' (was '%s').\n"), option, value);
  2668. return -1;
  2669. }
  2670. return 1;
  2671. }
  2672. static int cfgfile_yesno (const TCHAR *option, const TCHAR *value, const TCHAR *name, int *location)
  2673. {
  2674. return cfgfile_yesno (option, value, name, location, true);
  2675. }
  2676. static int cfgfile_yesno (const TCHAR *option, const TCHAR *value, const TCHAR *name, bool *location, bool numbercheck)
  2677. {
  2678. int val;
  2679. int ret = cfgfile_yesno (option, value, name, &val, numbercheck);
  2680. if (ret == 0)
  2681. return 0;
  2682. if (ret < 0)
  2683. *location = false;
  2684. else
  2685. *location = val != 0;
  2686. return 1;
  2687. }
  2688. int cfgfile_yesno (const TCHAR *option, const TCHAR *value, const TCHAR *name, bool *location)
  2689. {
  2690. return cfgfile_yesno (option, value, name, location, true);
  2691. }
  2692. static int cfgfile_doubleval (const TCHAR *option, const TCHAR *value, const TCHAR *name, double *location)
  2693. {
  2694. TCHAR *endptr;
  2695. if (name != NULL && _tcscmp (option, name) != 0)
  2696. return 0;
  2697. *location = _tcstod (value, &endptr);
  2698. return 1;
  2699. }
  2700. static int cfgfile_floatval (const TCHAR *option, const TCHAR *value, const TCHAR *name, const TCHAR *nameext, float *location)
  2701. {
  2702. TCHAR *endptr;
  2703. if (name == NULL)
  2704. return 0;
  2705. if (nameext) {
  2706. TCHAR tmp[MAX_DPATH];
  2707. _tcscpy (tmp, name);
  2708. _tcscat (tmp, nameext);
  2709. if (_tcscmp (tmp, option) != 0)
  2710. return 0;
  2711. } else {
  2712. if (_tcscmp (option, name) != 0)
  2713. return 0;
  2714. }
  2715. *location = (float)_tcstod (value, &endptr);
  2716. return 1;
  2717. }
  2718. static int cfgfile_floatval (const TCHAR *option, const TCHAR *value, const TCHAR *name, float *location)
  2719. {
  2720. return cfgfile_floatval (option, value, name, NULL, location);
  2721. }
  2722. static int cfgfile_intval (const TCHAR *option, const TCHAR *value, const TCHAR *name, const TCHAR *nameext, unsigned int *location, int scale)
  2723. {
  2724. int base = 10;
  2725. TCHAR *endptr;
  2726. TCHAR tmp[MAX_DPATH];
  2727. if (name == NULL)
  2728. return 0;
  2729. if (nameext) {
  2730. _tcscpy (tmp, name);
  2731. _tcscat (tmp, nameext);
  2732. if (_tcscmp (tmp, option) != 0)
  2733. return 0;
  2734. } else {
  2735. if (_tcscmp (option, name) != 0)
  2736. return 0;
  2737. }
  2738. /* I guess octal isn't popular enough to worry about here... */
  2739. if (value[0] == '0' && _totupper (value[1]) == 'X')
  2740. value += 2, base = 16;
  2741. *location = _tcstol (value, &endptr, base) * scale;
  2742. if (*endptr != '\0' || *value == '\0') {
  2743. if (strcasecmp (value, _T("false")) == 0 || strcasecmp (value, _T("no")) == 0) {
  2744. *location = 0;
  2745. return 1;
  2746. }
  2747. if (strcasecmp (value, _T("true")) == 0 || strcasecmp (value, _T("yes")) == 0) {
  2748. *location = 1;
  2749. return 1;
  2750. }
  2751. cfgfile_warning(_T("Option '%s' requires a numeric argument but got '%s'\n"), nameext ? tmp : option, value);
  2752. return -1;
  2753. }
  2754. return 1;
  2755. }
  2756. static int cfgfile_intval (const TCHAR *option, const TCHAR *value, const TCHAR *name, unsigned int *location, int scale)
  2757. {
  2758. return cfgfile_intval (option, value, name, NULL, location, scale);
  2759. }
  2760. int cfgfile_intval (const TCHAR *option, const TCHAR *value, const TCHAR *name, int *location, int scale)
  2761. {
  2762. unsigned int v = 0;
  2763. int r = cfgfile_intval (option, value, name, NULL, &v, scale);
  2764. if (!r)
  2765. return 0;
  2766. *location = (int)v;
  2767. return r;
  2768. }
  2769. static int cfgfile_intval (const TCHAR *option, const TCHAR *value, const TCHAR *name, const TCHAR *nameext, int *location, int scale)
  2770. {
  2771. unsigned int v = 0;
  2772. int r = cfgfile_intval (option, value, name, nameext, &v, scale);
  2773. if (!r)
  2774. return 0;
  2775. *location = (int)v;
  2776. return r;
  2777. }
  2778. static int cfgfile_strval (const TCHAR *option, const TCHAR *value, const TCHAR *name, const TCHAR *nameext, int *location, const TCHAR *table[], int more)
  2779. {
  2780. int val;
  2781. TCHAR tmp[MAX_DPATH];
  2782. if (name == NULL)
  2783. return 0;
  2784. if (nameext) {
  2785. _tcscpy (tmp, name);
  2786. _tcscat (tmp, nameext);
  2787. if (_tcscmp (tmp, option) != 0)
  2788. return 0;
  2789. } else {
  2790. if (_tcscmp (option, name) != 0)
  2791. return 0;
  2792. }
  2793. val = match_string (table, value);
  2794. if (val == -1) {
  2795. if (more)
  2796. return 0;
  2797. if (!strcasecmp (value, _T("yes")) || !strcasecmp (value, _T("true"))) {
  2798. val = 1;
  2799. } else if (!strcasecmp (value, _T("no")) || !strcasecmp (value, _T("false"))) {
  2800. val = 0;
  2801. } else {
  2802. cfgfile_warning(_T("Unknown value ('%s') for option '%s'.\n"), value, nameext ? tmp : option);
  2803. return -1;
  2804. }
  2805. }
  2806. *location = val;
  2807. return 1;
  2808. }
  2809. int cfgfile_strval (const TCHAR *option, const TCHAR *value, const TCHAR *name, int *location, const TCHAR *table[], int more)
  2810. {
  2811. return cfgfile_strval (option, value, name, NULL, location, table, more);
  2812. }
  2813. static int cfgfile_strboolval (const TCHAR *option, const TCHAR *value, const TCHAR *name, bool *location, const TCHAR *table[], int more)
  2814. {
  2815. int locationint;
  2816. if (!cfgfile_strval (option, value, name, &locationint, table, more))
  2817. return 0;
  2818. *location = locationint != 0;
  2819. return 1;
  2820. }
  2821. int cfgfile_string_escape(const TCHAR *option, const TCHAR *value, const TCHAR *name, TCHAR *location, int maxsz)
  2822. {
  2823. if (_tcscmp(option, name) != 0)
  2824. return 0;
  2825. TCHAR *s = cfgfile_unescape_min(value);
  2826. _tcsncpy(location, s, maxsz - 1);
  2827. xfree(s);
  2828. location[maxsz - 1] = '\0';
  2829. return 1;
  2830. }
  2831. int cfgfile_string(const TCHAR *option, const TCHAR *value, const TCHAR *name, TCHAR *location, int maxsz)
  2832. {
  2833. if (_tcscmp (option, name) != 0)
  2834. return 0;
  2835. _tcsncpy (location, value, maxsz - 1);
  2836. location[maxsz - 1] = '\0';
  2837. return 1;
  2838. }
  2839. static int cfgfile_string (const TCHAR *option, const TCHAR *value, const TCHAR *name, const TCHAR *nameext, TCHAR *location, int maxsz)
  2840. {
  2841. if (nameext) {
  2842. TCHAR tmp[MAX_DPATH];
  2843. _tcscpy (tmp, name);
  2844. _tcscat (tmp, nameext);
  2845. if (_tcscmp (tmp, option) != 0)
  2846. return 0;
  2847. } else {
  2848. if (_tcscmp (option, name) != 0)
  2849. return 0;
  2850. }
  2851. _tcsncpy (location, value, maxsz - 1);
  2852. location[maxsz - 1] = '\0';
  2853. return 1;
  2854. }
  2855. static bool cfgfile_multichoice(const TCHAR *option, const TCHAR *value, const TCHAR *name, int *location, const TCHAR *table[])
  2856. {
  2857. if (_tcscmp(option, name) != 0)
  2858. return false;
  2859. int v = 0;
  2860. for (int i = 0; table[i]; i++) {
  2861. if (cfgfile_option_find(value, table[i])) {
  2862. v |= 1 << i;
  2863. }
  2864. }
  2865. *location = v;
  2866. return true;
  2867. }
  2868. static int cfgfile_path (const TCHAR *option, const TCHAR *value, const TCHAR *name, TCHAR *location, int maxsz, struct multipath *mp)
  2869. {
  2870. if (!cfgfile_string (option, value, name, location, maxsz))
  2871. return 0;
  2872. cfgfile_adjust_path(location, maxsz, mp);
  2873. return 1;
  2874. }
  2875. static int cfgfile_path (const TCHAR *option, const TCHAR *value, const TCHAR *name, TCHAR *location, int maxsz)
  2876. {
  2877. return cfgfile_path (option, value, name, location, maxsz, NULL);
  2878. }
  2879. static int cfgfile_multipath (const TCHAR *option, const TCHAR *value, const TCHAR *name, struct multipath *mp, struct uae_prefs *p)
  2880. {
  2881. TCHAR tmploc[MAX_DPATH];
  2882. if (!cfgfile_string (option, value, name, tmploc, MAX_DPATH))
  2883. return 0;
  2884. for (int i = 0; i < MAX_PATHS; i++) {
  2885. if (mp->path[i][0] == 0 || (i == 0 && (!_tcscmp (mp->path[i], _T(".\\")) || !_tcscmp (mp->path[i], _T("./"))))) {
  2886. TCHAR *s = target_expand_environment (tmploc, NULL, 0);
  2887. _tcsncpy (mp->path[i], s, PATH_MAX - 1);
  2888. mp->path[i][PATH_MAX - 1] = 0;
  2889. fixtrailing (mp->path[i]);
  2890. xfree (s);
  2891. target_multipath_modified(p);
  2892. return 1;
  2893. }
  2894. }
  2895. return 1;
  2896. }
  2897. static int cfgfile_rom (const TCHAR *option, const TCHAR *value, const TCHAR *name, TCHAR *location, int maxsz)
  2898. {
  2899. TCHAR id[MAX_DPATH];
  2900. if (!cfgfile_string (option, value, name, id, sizeof id / sizeof (TCHAR)))
  2901. return 0;
  2902. TCHAR *p = _tcschr (id, ',');
  2903. if (p) {
  2904. TCHAR *endptr, tmp;
  2905. *p = 0;
  2906. tmp = id[4];
  2907. id[4] = 0;
  2908. uae_u32 crc32 = _tcstol (id, &endptr, 16) << 16;
  2909. id[4] = tmp;
  2910. crc32 |= _tcstol (id + 4, &endptr, 16);
  2911. struct romdata *rd = getromdatabycrc (crc32, true);
  2912. if (rd) {
  2913. struct romdata *rd2 = getromdatabyid (rd->id);
  2914. if (rd->group == 0 && rd2 == rd) {
  2915. if (zfile_exists (location))
  2916. return 1;
  2917. }
  2918. if (rd->group && rd2)
  2919. rd = rd2;
  2920. struct romlist *rl = getromlistbyromdata (rd);
  2921. if (rl) {
  2922. write_log (_T("%s: %s -> %s\n"), name, location, rl->path);
  2923. _tcsncpy (location, rl->path, maxsz);
  2924. }
  2925. }
  2926. }
  2927. return 1;
  2928. }
  2929. static int getintval (TCHAR **p, int *result, int delim)
  2930. {
  2931. TCHAR *value = *p;
  2932. int base = 10;
  2933. TCHAR *endptr;
  2934. TCHAR *p2 = _tcschr (*p, delim);
  2935. if (p2 == 0)
  2936. return 0;
  2937. *p2++ = '\0';
  2938. if (value[0] == '0' && _totupper (value[1]) == 'X')
  2939. value += 2, base = 16;
  2940. *result = _tcstol (value, &endptr, base);
  2941. *p = p2;
  2942. if (*endptr != '\0' || *value == '\0')
  2943. return 0;
  2944. return 1;
  2945. }
  2946. static int getintval2 (TCHAR **p, int *result, int delim, bool last)
  2947. {
  2948. TCHAR *value = *p;
  2949. int base = 10;
  2950. TCHAR *endptr;
  2951. TCHAR *p2;
  2952. p2 = _tcschr (*p, delim);
  2953. if (p2 == 0) {
  2954. if (last) {
  2955. if (delim != '.')
  2956. p2 = _tcschr (*p, ',');
  2957. if (p2 == 0) {
  2958. p2 = *p;
  2959. while(*p2)
  2960. p2++;
  2961. if (p2 == *p)
  2962. return 0;
  2963. }
  2964. } else {
  2965. return 0;
  2966. }
  2967. }
  2968. if (!_istdigit(**p) && **p != '-' && **p != '+')
  2969. return 0;
  2970. if (*p2 != 0)
  2971. *p2++ = '\0';
  2972. if (value[0] == '0' && _totupper (value[1]) == 'X')
  2973. value += 2, base = 16;
  2974. *result = _tcstol (value, &endptr, base);
  2975. *p = p2;
  2976. if (*endptr != '\0' || *value == '\0') {
  2977. *p = 0;
  2978. return 0;
  2979. }
  2980. return 1;
  2981. }
  2982. static int cfgfile_option_select(TCHAR *s, const TCHAR *option, const TCHAR *select)
  2983. {
  2984. TCHAR buf[MAX_DPATH];
  2985. if (!s)
  2986. return -1;
  2987. _tcscpy(buf, s);
  2988. _tcscat(buf, _T(","));
  2989. TCHAR *p = buf;
  2990. for (;;) {
  2991. TCHAR *tmpp = _tcschr (p, ',');
  2992. if (tmpp == NULL)
  2993. return -1;
  2994. *tmpp++ = 0;
  2995. TCHAR *tmpp2 = _tcschr(p, '=');
  2996. if (!tmpp2)
  2997. return -1;
  2998. *tmpp2++ = 0;
  2999. if (!strcasecmp(p, option)) {
  3000. int idx = 0;
  3001. while (select[0]) {
  3002. if (!strcasecmp(select, tmpp2))
  3003. return idx;
  3004. idx++;
  3005. select += _tcslen(select) + 1;
  3006. }
  3007. }
  3008. p = tmpp;
  3009. }
  3010. }
  3011. static int cfgfile_option_bool(TCHAR *s, const TCHAR *option)
  3012. {
  3013. TCHAR buf[MAX_DPATH];
  3014. if (!s)
  3015. return -1;
  3016. _tcscpy(buf, s);
  3017. _tcscat(buf, _T(","));
  3018. TCHAR *p = buf;
  3019. for (;;) {
  3020. TCHAR *tmpp = _tcschr (p, ',');
  3021. if (tmpp == NULL)
  3022. return -1;
  3023. *tmpp++ = 0;
  3024. TCHAR *tmpp2 = _tcschr(p, '=');
  3025. if (tmpp2)
  3026. *tmpp2++ = 0;
  3027. if (!strcasecmp(p, option)) {
  3028. if (!tmpp2)
  3029. return 0;
  3030. TCHAR *tmpp3 = _tcschr (tmpp2, ',');
  3031. if (tmpp3)
  3032. *tmpp3 = 0;
  3033. if (tmpp2 && !strcasecmp(tmpp2, _T("true")))
  3034. return 1;
  3035. if (tmpp2 && !strcasecmp(tmpp2, _T("false")))
  3036. return 0;
  3037. return 1;
  3038. }
  3039. p = tmpp;
  3040. }
  3041. }
  3042. static void set_chipset_mask (struct uae_prefs *p, int val)
  3043. {
  3044. p->chipset_mask = (val == 0 ? 0
  3045. : val == 1 ? CSMASK_ECS_AGNUS
  3046. : val == 2 ? CSMASK_ECS_DENISE
  3047. : val == 3 ? CSMASK_ECS_DENISE | CSMASK_ECS_AGNUS
  3048. : CSMASK_AGA | CSMASK_ECS_DENISE | CSMASK_ECS_AGNUS);
  3049. }
  3050. static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value)
  3051. {
  3052. int i, v;
  3053. bool vb;
  3054. TCHAR *section = 0;
  3055. TCHAR *tmpp;
  3056. TCHAR tmpbuf[CONFIG_BLEN];
  3057. if (_tcsncmp (option, _T("input."), 6) == 0 || _tcsncmp(option, _T("input_"), 6) == 0) {
  3058. read_inputdevice_config (p, option, value);
  3059. return 1;
  3060. }
  3061. for (tmpp = option; *tmpp != '\0'; tmpp++)
  3062. if (_istupper (*tmpp))
  3063. *tmpp = _totlower (*tmpp);
  3064. tmpp = _tcschr (option, '.');
  3065. if (tmpp) {
  3066. section = option;
  3067. option = tmpp + 1;
  3068. *tmpp = '\0';
  3069. if (_tcscmp (section, TARGET_NAME) == 0) {
  3070. /* We special case the various path options here. */
  3071. if (cfgfile_multipath (option, value, _T("rom_path"), &p->path_rom, p)
  3072. || cfgfile_multipath (option, value, _T("floppy_path"), &p->path_floppy, p)
  3073. || cfgfile_multipath (option, value, _T("cd_path"), &p->path_cd, p)
  3074. || cfgfile_multipath (option, value, _T("hardfile_path"), &p->path_hardfile, p))
  3075. return 1;
  3076. return target_parse_option (p, option, value);
  3077. }
  3078. return 0;
  3079. }
  3080. for (i = 0; i < MAX_SPARE_DRIVES; i++) {
  3081. _stprintf (tmpbuf, _T("diskimage%d"), i);
  3082. if (cfgfile_string(option, value, tmpbuf, p->dfxlist[i], sizeof p->dfxlist[i] / sizeof(TCHAR))) {
  3083. return 1;
  3084. }
  3085. }
  3086. for (i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
  3087. TCHAR tmp[20];
  3088. _stprintf (tmp, _T("cdimage%d"), i);
  3089. if (!_tcsicmp (option, tmp)) {
  3090. if (!_tcsicmp (value, _T("autodetect"))) {
  3091. p->cdslots[i].type = SCSI_UNIT_DEFAULT;
  3092. p->cdslots[i].inuse = true;
  3093. p->cdslots[i].name[0] = 0;
  3094. } else {
  3095. p->cdslots[i].delayed = false;
  3096. TCHAR *next = _tcsrchr (value, ',');
  3097. int type = SCSI_UNIT_DEFAULT;
  3098. int mode = 0;
  3099. int unitnum = 0;
  3100. for (;;) {
  3101. if (!next)
  3102. break;
  3103. *next++ = 0;
  3104. TCHAR *next2 = _tcschr (next, ':');
  3105. if (next2)
  3106. *next2++ = 0;
  3107. if (!_tcsicmp (next, _T("delay"))) {
  3108. p->cdslots[i].delayed = true;
  3109. next = next2;
  3110. if (!next)
  3111. break;
  3112. next2 = _tcschr (next, ':');
  3113. if (next2)
  3114. *next2++ = 0;
  3115. }
  3116. type = match_string (cdmodes, next);
  3117. if (type < 0)
  3118. type = SCSI_UNIT_DEFAULT;
  3119. else
  3120. type--;
  3121. next = next2;
  3122. if (!next)
  3123. break;
  3124. next2 = _tcschr (next, ':');
  3125. if (next2)
  3126. *next2++ = 0;
  3127. mode = match_string (cdconmodes, next);
  3128. if (mode < 0)
  3129. mode = 0;
  3130. next = next2;
  3131. if (!next)
  3132. break;
  3133. next2 = _tcschr (next, ':');
  3134. if (next2)
  3135. *next2++ = 0;
  3136. cfgfile_intval (option, next, tmp, &unitnum, 1);
  3137. }
  3138. if (_tcslen (value) > 0) {
  3139. _tcsncpy (p->cdslots[i].name, value, sizeof(p->cdslots[i].name) / sizeof (TCHAR));
  3140. }
  3141. p->cdslots[i].name[sizeof(p->cdslots[i].name) / sizeof(TCHAR) - 1] = 0;
  3142. p->cdslots[i].inuse = true;
  3143. p->cdslots[i].type = type;
  3144. if (value[0] == 0 || !_tcsicmp(value, _T("empty")) || !_tcscmp(value, _T("."))) {
  3145. value[0] = 0;
  3146. p->cdslots[i].name[0] = 0;
  3147. p->cdslots[i].inuse = false;
  3148. }
  3149. }
  3150. // disable all following units
  3151. i++;
  3152. while (i < MAX_TOTAL_SCSI_DEVICES) {
  3153. p->cdslots[i].type = SCSI_UNIT_DISABLED;
  3154. i++;
  3155. }
  3156. return 1;
  3157. }
  3158. }
  3159. if (!_tcsicmp (option, _T("lua"))) {
  3160. for (i = 0; i < MAX_LUA_STATES; i++) {
  3161. if (!p->luafiles[i][0]) {
  3162. _tcscpy (p->luafiles[i], value);
  3163. break;
  3164. }
  3165. }
  3166. return 1;
  3167. }
  3168. if (cfgfile_strval (option, value, _T("gfx_autoresolution_min_vertical"), &p->gfx_autoresolution_minv, vertmode, 0)) {
  3169. p->gfx_autoresolution_minv--;
  3170. return 1;
  3171. }
  3172. if (cfgfile_strval (option, value, _T("gfx_autoresolution_min_horizontal"), &p->gfx_autoresolution_minh, horizmode, 0)) {
  3173. p->gfx_autoresolution_minh--;
  3174. return 1;
  3175. }
  3176. if (!_tcsicmp (option, _T("gfx_autoresolution"))) {
  3177. p->gfx_autoresolution = 0;
  3178. cfgfile_intval (option, value, _T("gfx_autoresolution"), &p->gfx_autoresolution, 1);
  3179. if (!p->gfx_autoresolution) {
  3180. v = cfgfile_yesno (option, value, _T("gfx_autoresolution"), &vb);
  3181. if (v > 0)
  3182. p->gfx_autoresolution = vb ? 10 : 0;
  3183. }
  3184. return 1;
  3185. }
  3186. if (cfgfile_intval (option, value, _T("sound_frequency"), &p->sound_freq, 1)
  3187. || cfgfile_intval (option, value, _T("sound_max_buff"), &p->sound_maxbsiz, 1)
  3188. || cfgfile_intval (option, value, _T("state_replay_rate"), &p->statecapturerate, 1)
  3189. || cfgfile_intval (option, value, _T("state_replay_buffers"), &p->statecapturebuffersize, 1)
  3190. || cfgfile_yesno (option, value, _T("state_replay_autoplay"), &p->inprec_autoplay)
  3191. || cfgfile_intval (option, value, _T("sound_frequency"), &p->sound_freq, 1)
  3192. || cfgfile_intval (option, value, _T("sound_volume"), &p->sound_volume_master, 1)
  3193. || cfgfile_intval (option, value, _T("sound_volume_paula"), &p->sound_volume_paula, 1)
  3194. || cfgfile_intval (option, value, _T("sound_volume_cd"), &p->sound_volume_cd, 1)
  3195. || cfgfile_intval (option, value, _T("sound_volume_ahi"), &p->sound_volume_board, 1)
  3196. || cfgfile_intval (option, value, _T("sound_volume_midi"), &p->sound_volume_midi, 1)
  3197. || cfgfile_intval (option, value, _T("sound_volume_genlock"), &p->sound_volume_genlock, 1)
  3198. || cfgfile_intval (option, value, _T("sound_stereo_separation"), &p->sound_stereo_separation, 1)
  3199. || cfgfile_intval (option, value, _T("sound_stereo_mixing_delay"), &p->sound_mixed_stereo_delay, 1)
  3200. || cfgfile_intval (option, value, _T("sampler_frequency"), &p->sampler_freq, 1)
  3201. || cfgfile_intval (option, value, _T("sampler_buffer"), &p->sampler_buffer, 1)
  3202. || cfgfile_intval(option, value, _T("warp_limit"), &p->turbo_emulation_limit, 1)
  3203. || cfgfile_intval(option, value, _T("power_led_dim"), &p->power_led_dim, 1)
  3204. || cfgfile_intval(option, value, _T("gfx_frame_slices"), &p->gfx_display_sections, 1)
  3205. || cfgfile_intval(option, value, _T("gfx_framerate"), &p->gfx_framerate, 1)
  3206. || cfgfile_intval(option, value, _T("gfx_top_windowed"), &p->gfx_monitor[0].gfx_size_win.x, 1)
  3207. || cfgfile_intval(option, value, _T("gfx_left_windowed"), &p->gfx_monitor[0].gfx_size_win.y, 1)
  3208. || cfgfile_intval(option, value, _T("gfx_refreshrate"), &p->gfx_apmode[APMODE_NATIVE].gfx_refreshrate, 1)
  3209. || cfgfile_intval(option, value, _T("gfx_refreshrate_rtg"), &p->gfx_apmode[APMODE_RTG].gfx_refreshrate, 1)
  3210. || cfgfile_intval(option, value, _T("gfx_autoresolution_delay"), &p->gfx_autoresolution_delay, 1)
  3211. || cfgfile_intval(option, value, _T("gfx_backbuffers"), &p->gfx_apmode[APMODE_NATIVE].gfx_backbuffers, 1)
  3212. || cfgfile_intval(option, value, _T("gfx_backbuffers_rtg"), &p->gfx_apmode[APMODE_RTG].gfx_backbuffers, 1)
  3213. || cfgfile_yesno(option, value, _T("gfx_interlace"), &p->gfx_apmode[APMODE_NATIVE].gfx_interlaced)
  3214. || cfgfile_yesno(option, value, _T("gfx_interlace_rtg"), &p->gfx_apmode[APMODE_RTG].gfx_interlaced)
  3215. || cfgfile_yesno(option, value, _T("gfx_vrr_monitor"), &p->gfx_variable_sync)
  3216. || cfgfile_yesno(option, value, _T("gfx_resize_windowed"), &p->gfx_windowed_resize)
  3217. || cfgfile_intval(option, value, _T("gfx_black_frame_insertion_ratio"), &p->lightboost_strobo_ratio, 1)
  3218. || cfgfile_intval (option, value, _T("gfx_center_horizontal_position"), &p->gfx_xcenter_pos, 1)
  3219. || cfgfile_intval (option, value, _T("gfx_center_vertical_position"), &p->gfx_ycenter_pos, 1)
  3220. || cfgfile_intval (option, value, _T("gfx_center_horizontal_size"), &p->gfx_xcenter_size, 1)
  3221. || cfgfile_intval (option, value, _T("gfx_center_vertical_size"), &p->gfx_ycenter_size, 1)
  3222. || cfgfile_intval (option, value, _T("filesys_max_size"), &p->filesys_limit, 1)
  3223. || cfgfile_intval (option, value, _T("filesys_max_name_length"), &p->filesys_max_name, 1)
  3224. || cfgfile_intval (option, value, _T("filesys_max_file_size"), &p->filesys_max_file_size, 1)
  3225. || cfgfile_yesno (option, value, _T("filesys_inject_icons"), &p->filesys_inject_icons)
  3226. || cfgfile_string (option, value, _T("filesys_inject_icons_drawer"), p->filesys_inject_icons_drawer, sizeof p->filesys_inject_icons_drawer / sizeof (TCHAR))
  3227. || cfgfile_string (option, value, _T("filesys_inject_icons_project"), p->filesys_inject_icons_project, sizeof p->filesys_inject_icons_project / sizeof (TCHAR))
  3228. || cfgfile_string (option, value, _T("filesys_inject_icons_tool"), p->filesys_inject_icons_tool, sizeof p->filesys_inject_icons_tool / sizeof (TCHAR))
  3229. || cfgfile_intval(option, value, _T("gfx_luminance"), &p->gfx_luminance, 1)
  3230. || cfgfile_intval(option, value, _T("gfx_contrast"), &p->gfx_contrast, 1)
  3231. || cfgfile_intval(option, value, _T("gfx_gamma"), &p->gfx_gamma, 1)
  3232. || cfgfile_intval(option, value, _T("gfx_gamma_r"), &p->gfx_gamma_ch[0], 1)
  3233. || cfgfile_intval(option, value, _T("gfx_gamma_g"), &p->gfx_gamma_ch[1], 1)
  3234. || cfgfile_intval(option, value, _T("gfx_gamma_b"), &p->gfx_gamma_ch[2], 1)
  3235. || cfgfile_floatval(option, value, _T("rtg_vert_zoom_multf"), &p->rtg_vert_zoom_mult)
  3236. || cfgfile_floatval(option, value, _T("rtg_horiz_zoom_multf"), &p->rtg_horiz_zoom_mult)
  3237. || cfgfile_intval(option, value, _T("gfx_horizontal_extra"), &p->gfx_extrawidth, 1)
  3238. || cfgfile_intval(option, value, _T("gfx_vertical_extra"), &p->gfx_extraheight, 1)
  3239. || cfgfile_intval (option, value, _T("floppy0sound"), &p->floppyslots[0].dfxclick, 1)
  3240. || cfgfile_intval (option, value, _T("floppy1sound"), &p->floppyslots[1].dfxclick, 1)
  3241. || cfgfile_intval (option, value, _T("floppy2sound"), &p->floppyslots[2].dfxclick, 1)
  3242. || cfgfile_intval (option, value, _T("floppy3sound"), &p->floppyslots[3].dfxclick, 1)
  3243. || cfgfile_intval (option, value, _T("floppy0soundvolume_disk"), &p->dfxclickvolume_disk[0], 1)
  3244. || cfgfile_intval (option, value, _T("floppy1soundvolume_disk"), &p->dfxclickvolume_disk[1], 1)
  3245. || cfgfile_intval (option, value, _T("floppy2soundvolume_disk"), &p->dfxclickvolume_disk[2], 1)
  3246. || cfgfile_intval (option, value, _T("floppy3soundvolume_disk"), &p->dfxclickvolume_disk[3], 1)
  3247. || cfgfile_intval (option, value, _T("floppy0soundvolume_empty"), &p->dfxclickvolume_empty[0], 1)
  3248. || cfgfile_intval (option, value, _T("floppy1soundvolume_empty"), &p->dfxclickvolume_empty[1], 1)
  3249. || cfgfile_intval (option, value, _T("floppy2soundvolume_empty"), &p->dfxclickvolume_empty[2], 1)
  3250. || cfgfile_intval (option, value, _T("floppy3soundvolume_empty"), &p->dfxclickvolume_empty[3], 1)
  3251. || cfgfile_intval (option, value, _T("floppy_channel_mask"), &p->dfxclickchannelmask, 1))
  3252. return 1;
  3253. if (cfgfile_string(option, value, _T("floppy0soundext"), p->floppyslots[0].dfxclickexternal, sizeof p->floppyslots[0].dfxclickexternal / sizeof (TCHAR))
  3254. || cfgfile_string(option, value, _T("floppy1soundext"), p->floppyslots[1].dfxclickexternal, sizeof p->floppyslots[1].dfxclickexternal / sizeof (TCHAR))
  3255. || cfgfile_string(option, value, _T("floppy2soundext"), p->floppyslots[2].dfxclickexternal, sizeof p->floppyslots[2].dfxclickexternal / sizeof (TCHAR))
  3256. || cfgfile_string(option, value, _T("floppy3soundext"), p->floppyslots[3].dfxclickexternal, sizeof p->floppyslots[3].dfxclickexternal / sizeof (TCHAR))
  3257. || cfgfile_string(option, value, _T("debugging_options"), p->debugging_options, sizeof p->debugging_options / sizeof(TCHAR))
  3258. || cfgfile_string(option, value, _T("config_window_title"), p->config_window_title, sizeof p->config_window_title / sizeof (TCHAR))
  3259. || cfgfile_string(option, value, _T("config_info"), p->info, sizeof p->info / sizeof (TCHAR))
  3260. || cfgfile_string(option, value, _T("config_description"), p->description, sizeof p->description / sizeof(TCHAR))
  3261. || cfgfile_string(option, value, _T("config_category"), p->category, sizeof p->category / sizeof(TCHAR))
  3262. || cfgfile_string(option, value, _T("config_tags"), p->tags, sizeof p->tags / sizeof(TCHAR)))
  3263. return 1;
  3264. if (cfgfile_yesno(option, value, _T("use_debugger"), &p->start_debugger)
  3265. || cfgfile_yesno(option, value, _T("floppy0wp"), &p->floppyslots[0].forcedwriteprotect)
  3266. || cfgfile_yesno(option, value, _T("floppy1wp"), &p->floppyslots[1].forcedwriteprotect)
  3267. || cfgfile_yesno(option, value, _T("floppy2wp"), &p->floppyslots[2].forcedwriteprotect)
  3268. || cfgfile_yesno(option, value, _T("floppy3wp"), &p->floppyslots[3].forcedwriteprotect)
  3269. || cfgfile_yesno(option, value, _T("sampler_stereo"), &p->sampler_stereo)
  3270. || cfgfile_yesno(option, value, _T("sound_auto"), &p->sound_auto)
  3271. || cfgfile_yesno(option, value, _T("sound_cdaudio"), &p->sound_cdaudio)
  3272. || cfgfile_yesno(option, value, _T("sound_volcnt"), &p->sound_volcnt)
  3273. || cfgfile_yesno(option, value, _T("sound_stereo_swap_paula"), &p->sound_stereo_swap_paula)
  3274. || cfgfile_yesno(option, value, _T("sound_stereo_swap_ahi"), &p->sound_stereo_swap_ahi)
  3275. || cfgfile_yesno(option, value, _T("debug_mem"), &p->debug_mem)
  3276. || cfgfile_yesno(option, value, _T("log_illegal_mem"), &p->illegal_mem)
  3277. || cfgfile_yesno(option, value, _T("filesys_no_fsdb"), &p->filesys_no_uaefsdb)
  3278. || cfgfile_yesno(option, value, _T("gfx_monochrome"), &p->gfx_grayscale)
  3279. || cfgfile_yesno(option, value, _T("gfx_blacker_than_black"), &p->gfx_blackerthanblack)
  3280. || cfgfile_yesno(option, value, _T("gfx_black_frame_insertion"), &p->lightboost_strobo)
  3281. || cfgfile_yesno(option, value, _T("gfx_flickerfixer"), &p->gfx_scandoubler)
  3282. || cfgfile_yesno(option, value, _T("gfx_autoresolution_vga"), &p->gfx_autoresolution_vga)
  3283. || cfgfile_yesno(option, value, _T("show_refresh_indicator"), &p->refresh_indicator)
  3284. || cfgfile_yesno(option, value, _T("warp"), &p->turbo_emulation)
  3285. || cfgfile_yesno(option, value, _T("headless"), &p->headless)
  3286. || cfgfile_yesno(option, value, _T("clipboard_sharing"), &p->clipboard_sharing)
  3287. || cfgfile_yesno(option, value, _T("native_code"), &p->native_code)
  3288. || cfgfile_yesno(option, value, _T("tablet_library"), &p->tablet_library)
  3289. || cfgfile_yesno(option, value, _T("bsdsocket_emu"), &p->socket_emu))
  3290. return 1;
  3291. if (cfgfile_strval (option, value, _T("sound_output"), &p->produce_sound, soundmode1, 1)
  3292. || cfgfile_strval (option, value, _T("sound_output"), &p->produce_sound, soundmode2, 0)
  3293. || cfgfile_strval (option, value, _T("sound_interpol"), &p->sound_interpol, interpolmode, 0)
  3294. || cfgfile_strval (option, value, _T("sound_filter"), &p->sound_filter, soundfiltermode1, 0)
  3295. || cfgfile_strval (option, value, _T("sound_filter_type"), &p->sound_filter_type, soundfiltermode2, 0)
  3296. || cfgfile_strboolval (option, value, _T("use_gui"), &p->start_gui, guimode1, 1)
  3297. || cfgfile_strboolval (option, value, _T("use_gui"), &p->start_gui, guimode2, 1)
  3298. || cfgfile_strboolval (option, value, _T("use_gui"), &p->start_gui, guimode3, 0)
  3299. || cfgfile_strval (option, value, _T("gfx_resolution"), &p->gfx_resolution, lorestype1, 0)
  3300. || cfgfile_strval (option, value, _T("gfx_lores"), &p->gfx_resolution, lorestype2, 0)
  3301. || cfgfile_strval (option, value, _T("gfx_lores_mode"), &p->gfx_lores_mode, loresmode, 0)
  3302. || cfgfile_strval (option, value, _T("gfx_fullscreen_amiga"), &p->gfx_apmode[APMODE_NATIVE].gfx_fullscreen, fullmodes, 0)
  3303. || cfgfile_strval (option, value, _T("gfx_fullscreen_picasso"), &p->gfx_apmode[APMODE_RTG].gfx_fullscreen, fullmodes, 0)
  3304. || cfgfile_strval (option, value, _T("gfx_center_horizontal"), &p->gfx_xcenter, centermode1, 1)
  3305. || cfgfile_strval (option, value, _T("gfx_center_vertical"), &p->gfx_ycenter, centermode1, 1)
  3306. || cfgfile_strval (option, value, _T("gfx_center_horizontal"), &p->gfx_xcenter, centermode2, 0)
  3307. || cfgfile_strval (option, value, _T("gfx_center_vertical"), &p->gfx_ycenter, centermode2, 0)
  3308. || cfgfile_strval (option, value, _T("gfx_colour_mode"), &p->color_mode, colormode1, 1)
  3309. || cfgfile_strval (option, value, _T("gfx_colour_mode"), &p->color_mode, colormode2, 0)
  3310. || cfgfile_strval (option, value, _T("gfx_color_mode"), &p->color_mode, colormode1, 1)
  3311. || cfgfile_strval (option, value, _T("gfx_color_mode"), &p->color_mode, colormode2, 0)
  3312. || cfgfile_strval (option, value, _T("gfx_max_horizontal"), &p->gfx_max_horizontal, maxhoriz, 0)
  3313. || cfgfile_strval (option, value, _T("gfx_max_vertical"), &p->gfx_max_vertical, maxvert, 0)
  3314. || cfgfile_strval(option, value, _T("gfx_api"), &p->gfx_api, filterapi, 0)
  3315. || cfgfile_strval(option, value, _T("gfx_api_options"), &p->gfx_api_options, filterapiopts, 0)
  3316. || cfgfile_strval(option, value, _T("gfx_atari_palette_fix"), &p->gfx_threebitcolors, threebitcolors, 0)
  3317. || cfgfile_strval(option, value, _T("gfx_overscanmode"), &p->gfx_overscanmode, overscanmodes, 0)
  3318. || cfgfile_strval(option, value, _T("magic_mousecursor"), &p->input_magic_mouse_cursor, magiccursors, 0)
  3319. || cfgfile_strval (option, value, _T("absolute_mouse"), &p->input_tablet, abspointers, 0))
  3320. return 1;
  3321. if (cfgfile_multichoice(option, value, _T("debugging_features"), &p->debugging_features, debugfeatures))
  3322. return 1;
  3323. if (cfgfile_yesno(option, value, _T("gfx_api_hdr"), &vb)) {
  3324. if (vb && p->gfx_api == 2) {
  3325. p->gfx_api = 3;
  3326. }
  3327. return 1;
  3328. }
  3329. if (cfgfile_yesno(option, value, _T("magic_mouse"), &vb)) {
  3330. if (vb)
  3331. p->input_mouse_untrap |= MOUSEUNTRAP_MAGIC;
  3332. else
  3333. p->input_mouse_untrap &= ~MOUSEUNTRAP_MAGIC;
  3334. return 1;
  3335. }
  3336. #ifdef GFXFILTER
  3337. for (int j = 0; j < 2; j++) {
  3338. struct gfx_filterdata *gf = &p->gf[j];
  3339. const TCHAR *ext = j == 0 ? NULL : _T("_rtg");
  3340. if (cfgfile_strval (option, value, _T("gfx_filter_autoscale"), ext, &gf->gfx_filter_autoscale, j == 0 ? autoscale : autoscale_rtg, 0)
  3341. || cfgfile_strval (option, value, _T("gfx_filter_keep_aspect"), ext, &gf->gfx_filter_keep_aspect, aspects, 0)
  3342. || cfgfile_strval (option, value, _T("gfx_filter_autoscale_limit"), ext, &gf->gfx_filter_integerscalelimit, autoscalelimit, 0))
  3343. return 1;
  3344. if (cfgfile_floatval(option, value, _T("gfx_filter_vert_zoomf"), ext, &gf->gfx_filter_vert_zoom)
  3345. || cfgfile_floatval(option, value, _T("gfx_filter_horiz_zoomf"), ext, &gf->gfx_filter_horiz_zoom)
  3346. || cfgfile_floatval(option, value, _T("gfx_filter_vert_zoom_multf"), ext, &gf->gfx_filter_vert_zoom_mult)
  3347. || cfgfile_floatval(option, value, _T("gfx_filter_horiz_zoom_multf"), ext, &gf->gfx_filter_horiz_zoom_mult)
  3348. || cfgfile_floatval(option, value, _T("gfx_filter_vert_offsetf"), ext, &gf->gfx_filter_vert_offset)
  3349. || cfgfile_floatval(option, value, _T("gfx_filter_horiz_offsetf"), ext, &gf->gfx_filter_horiz_offset)
  3350. || cfgfile_intval(option, value, _T("gfx_filter_left_border"), ext, &gf->gfx_filter_left_border, 1)
  3351. || cfgfile_intval(option, value, _T("gfx_filter_right_border"), ext, &gf->gfx_filter_right_border, 1)
  3352. || cfgfile_intval(option, value, _T("gfx_filter_top_border"), ext, &gf->gfx_filter_top_border, 1)
  3353. || cfgfile_intval(option, value, _T("gfx_filter_bottom_border"), ext, &gf->gfx_filter_bottom_border, 1)
  3354. || cfgfile_intval(option, value, _T("gfx_filter_scanlines"), ext, &gf->gfx_filter_scanlines, 1)
  3355. || cfgfile_intval(option, value, _T("gfx_filter_scanlinelevel"), ext, &gf->gfx_filter_scanlinelevel, 1)
  3356. || cfgfile_intval(option, value, _T("gfx_filter_scanlineratio"), ext, &gf->gfx_filter_scanlineratio, 1)
  3357. || cfgfile_intval(option, value, _T("gfx_filter_scanlineoffset"), ext, &gf->gfx_filter_scanlineoffset, 1)
  3358. || cfgfile_intval(option, value, _T("gfx_filter_luminance"), ext, &gf->gfx_filter_luminance, 1)
  3359. || cfgfile_intval(option, value, _T("gfx_filter_contrast"), ext, &gf->gfx_filter_contrast, 1)
  3360. || cfgfile_intval(option, value, _T("gfx_filter_saturation"), ext, &gf->gfx_filter_saturation, 1)
  3361. || cfgfile_intval(option, value, _T("gfx_filter_gamma"), ext, &gf->gfx_filter_gamma, 1)
  3362. || cfgfile_intval(option, value, _T("gfx_filter_gamma_r"), ext, &gf->gfx_filter_gamma_ch[0], 1)
  3363. || cfgfile_intval(option, value, _T("gfx_filter_gamma_g"), ext, &gf->gfx_filter_gamma_ch[1], 1)
  3364. || cfgfile_intval(option, value, _T("gfx_filter_gamma_b"), ext, &gf->gfx_filter_gamma_ch[2], 1)
  3365. || cfgfile_intval(option, value, _T("gfx_filter_blur"), ext, &gf->gfx_filter_blur, 1)
  3366. || cfgfile_intval(option, value, _T("gfx_filter_noise"), ext, &gf->gfx_filter_noise, 1)
  3367. || cfgfile_intval(option, value, _T("gfx_filter_bilinear"), ext, &gf->gfx_filter_bilinear, 1)
  3368. || cfgfile_intval(option, value, _T("gfx_filter_keep_autoscale_aspect"), ext, &gf->gfx_filter_keep_autoscale_aspect, 1)
  3369. || cfgfile_string(option, value, _T("gfx_filter_mask"), ext, gf->gfx_filtermask[2 * MAX_FILTERSHADERS], sizeof gf->gfx_filtermask[2 * MAX_FILTERSHADERS] / sizeof (TCHAR)))
  3370. return 1;
  3371. }
  3372. #endif
  3373. if (cfgfile_intval (option, value, _T("floppy_volume"), &v, 1)) {
  3374. for (int i = 0; i < 4; i++) {
  3375. p->dfxclickvolume_disk[i] = v;
  3376. p->dfxclickvolume_empty[i] = v;
  3377. }
  3378. return 1;
  3379. }
  3380. if (_tcscmp (option, _T("gfx_width_windowed")) == 0) {
  3381. if (!_tcscmp (value, _T("native"))) {
  3382. p->gfx_monitor[0].gfx_size_win.width = 0;
  3383. p->gfx_monitor[0].gfx_size_win.height = 0;
  3384. } else {
  3385. cfgfile_intval (option, value, _T("gfx_width_windowed"), &p->gfx_monitor[0].gfx_size_win.width, 1);
  3386. }
  3387. return 1;
  3388. }
  3389. if (_tcscmp (option, _T("gfx_height_windowed")) == 0) {
  3390. if (!_tcscmp (value, _T("native"))) {
  3391. p->gfx_monitor[0].gfx_size_win.width = 0;
  3392. p->gfx_monitor[0].gfx_size_win.height = 0;
  3393. } else {
  3394. cfgfile_intval (option, value, _T("gfx_height_windowed"), &p->gfx_monitor[0].gfx_size_win.height, 1);
  3395. }
  3396. return 1;
  3397. }
  3398. if (_tcscmp (option, _T("gfx_width_fullscreen")) == 0) {
  3399. if (!_tcscmp (value, _T("native"))) {
  3400. p->gfx_monitor[0].gfx_size_fs.width = 0;
  3401. p->gfx_monitor[0].gfx_size_fs.height = 0;
  3402. p->gfx_monitor[0].gfx_size_fs.special = WH_NATIVE;
  3403. } else {
  3404. cfgfile_intval (option, value, _T("gfx_width_fullscreen"), &p->gfx_monitor[0].gfx_size_fs.width, 1);
  3405. p->gfx_monitor[0].gfx_size_fs.special = 0;
  3406. }
  3407. return 1;
  3408. }
  3409. if (_tcscmp (option, _T("gfx_height_fullscreen")) == 0) {
  3410. if (!_tcscmp (value, _T("native"))) {
  3411. p->gfx_monitor[0].gfx_size_fs.width = 0;
  3412. p->gfx_monitor[0].gfx_size_fs.height = 0;
  3413. p->gfx_monitor[0].gfx_size_fs.special = WH_NATIVE;
  3414. } else {
  3415. cfgfile_intval (option, value, _T("gfx_height_fullscreen"), &p->gfx_monitor[0].gfx_size_fs.height, 1);
  3416. p->gfx_monitor[0].gfx_size_fs.special = 0;
  3417. }
  3418. return 1;
  3419. }
  3420. if (cfgfile_intval (option, value, _T("gfx_display"), &p->gfx_apmode[APMODE_NATIVE].gfx_display, 1)) {
  3421. p->gfx_apmode[APMODE_RTG].gfx_display = p->gfx_apmode[APMODE_NATIVE].gfx_display;
  3422. return 1;
  3423. }
  3424. if (cfgfile_intval (option, value, _T("gfx_display_rtg"), &p->gfx_apmode[APMODE_RTG].gfx_display, 1)) {
  3425. return 1;
  3426. }
  3427. if (_tcscmp (option, _T("gfx_display_friendlyname")) == 0 || _tcscmp (option, _T("gfx_display_name")) == 0) {
  3428. TCHAR tmp[MAX_DPATH];
  3429. if (cfgfile_string (option, value, _T("gfx_display_friendlyname"), tmp, sizeof tmp / sizeof (TCHAR))) {
  3430. int num = target_get_display (tmp);
  3431. if (num >= 0)
  3432. p->gfx_apmode[APMODE_RTG].gfx_display = p->gfx_apmode[APMODE_NATIVE].gfx_display = num;
  3433. }
  3434. if (cfgfile_string (option, value, _T("gfx_display_name"), tmp, sizeof tmp / sizeof (TCHAR))) {
  3435. int num = target_get_display (tmp);
  3436. if (num >= 0)
  3437. p->gfx_apmode[APMODE_RTG].gfx_display = p->gfx_apmode[APMODE_NATIVE].gfx_display = num;
  3438. }
  3439. return 1;
  3440. }
  3441. if (_tcscmp (option, _T("gfx_display_friendlyname_rtg")) == 0 || _tcscmp (option, _T("gfx_display_name_rtg")) == 0) {
  3442. TCHAR tmp[MAX_DPATH];
  3443. if (cfgfile_string (option, value, _T("gfx_display_friendlyname_rtg"), tmp, sizeof tmp / sizeof (TCHAR))) {
  3444. int num = target_get_display (tmp);
  3445. if (num >= 0)
  3446. p->gfx_apmode[APMODE_RTG].gfx_display = num;
  3447. }
  3448. if (cfgfile_string (option, value, _T("gfx_display_name_rtg"), tmp, sizeof tmp / sizeof (TCHAR))) {
  3449. int num = target_get_display (tmp);
  3450. if (num >= 0)
  3451. p->gfx_apmode[APMODE_RTG].gfx_display = num;
  3452. }
  3453. return 1;
  3454. }
  3455. if (_tcscmp (option, _T("gfx_linemode")) == 0) {
  3456. int v = 0;
  3457. p->gfx_vresolution = VRES_DOUBLE;
  3458. p->gfx_pscanlines = 0;
  3459. p->gfx_iscanlines = 0;
  3460. if (cfgfile_strval(option, value, _T("gfx_linemode"), &v, linemode, 0)) {
  3461. p->gfx_vresolution = VRES_NONDOUBLE;
  3462. if (v > 0) {
  3463. p->gfx_iscanlines = (v - 1) / 4;
  3464. p->gfx_pscanlines = (v - 1) % 4;
  3465. p->gfx_vresolution = VRES_DOUBLE;
  3466. }
  3467. }
  3468. return 1;
  3469. }
  3470. if (_tcscmp (option, _T("gfx_vsync")) == 0) {
  3471. if (cfgfile_strval (option, value, _T("gfx_vsync"), &p->gfx_apmode[APMODE_NATIVE].gfx_vsync, vsyncmodes, 0) >= 0) {
  3472. return 1;
  3473. }
  3474. return cfgfile_yesno (option, value, _T("gfx_vsync"), &p->gfx_apmode[APMODE_NATIVE].gfx_vsync);
  3475. }
  3476. if (_tcscmp (option, _T("gfx_vsync_picasso")) == 0) {
  3477. if (cfgfile_strval (option, value, _T("gfx_vsync_picasso"), &p->gfx_apmode[APMODE_RTG].gfx_vsync, vsyncmodes, 0) >= 0) {
  3478. return 1;
  3479. }
  3480. return cfgfile_yesno (option, value, _T("gfx_vsync_picasso"), &p->gfx_apmode[APMODE_RTG].gfx_vsync);
  3481. }
  3482. if (cfgfile_strval (option, value, _T("gfx_vsyncmode"), &p->gfx_apmode[APMODE_NATIVE].gfx_vsyncmode, vsyncmodes2, 0))
  3483. return 1;
  3484. if (cfgfile_strval (option, value, _T("gfx_vsyncmode_picasso"), &p->gfx_apmode[APMODE_RTG].gfx_vsyncmode, vsyncmodes2, 0))
  3485. return 1;
  3486. if (cfgfile_yesno (option, value, _T("show_leds"), &vb)) {
  3487. if (vb)
  3488. p->leds_on_screen |= STATUSLINE_CHIPSET;
  3489. else
  3490. p->leds_on_screen &= ~STATUSLINE_CHIPSET;
  3491. return 1;
  3492. }
  3493. if (cfgfile_yesno (option, value, _T("show_leds_rtg"), &vb)) {
  3494. if (vb)
  3495. p->leds_on_screen |= STATUSLINE_RTG;
  3496. else
  3497. p->leds_on_screen &= ~STATUSLINE_RTG;
  3498. return 1;
  3499. }
  3500. if (_tcscmp(option, _T("show_leds_size")) == 0 || _tcscmp(option, _T("show_leds_size_rtg")) == 0) {
  3501. int idx = _tcscmp(option, _T("show_leds_size")) == 0 ? 0 : 1;
  3502. p->leds_on_screen_multiplier[idx] = 0;
  3503. float f = 0;
  3504. if (cfgfile_floatval(option, value, option, &f)) {
  3505. p->leds_on_screen_multiplier[idx] = (int)(f * 100);
  3506. }
  3507. return 1;
  3508. }
  3509. if (_tcscmp (option, _T("show_leds_enabled")) == 0 || _tcscmp (option, _T("show_leds_enabled_rtg")) == 0) {
  3510. TCHAR tmp[MAX_DPATH];
  3511. int idx = _tcscmp (option, _T("show_leds_enabled")) == 0 ? 0 : 1;
  3512. p->leds_on_screen_mask[idx] = 0;
  3513. _tcscpy (tmp, value);
  3514. _tcscat (tmp, _T(","));
  3515. TCHAR *s = tmp;
  3516. for (;;) {
  3517. TCHAR *s2 = s;
  3518. TCHAR *s3 = _tcschr (s, ':');
  3519. s = _tcschr (s, ',');
  3520. if (!s)
  3521. break;
  3522. if (s3 && s3 < s)
  3523. s = s3;
  3524. *s = 0;
  3525. for (int i = 0; leds[i]; i++) {
  3526. if (!_tcsicmp (s2, leds[i])) {
  3527. p->leds_on_screen_mask[idx] |= 1 << i;
  3528. }
  3529. }
  3530. s++;
  3531. }
  3532. return 1;
  3533. }
  3534. if (!_tcscmp (option, _T("osd_position"))) {
  3535. TCHAR *s = value;
  3536. p->osd_pos.x = 0;
  3537. p->osd_pos.y = 0;
  3538. while (s) {
  3539. if (!_tcschr (s, ':'))
  3540. break;
  3541. p->osd_pos.x = (int)(_tstof (s) * 10.0);
  3542. s = _tcschr (s, ':');
  3543. if (!s)
  3544. break;
  3545. if (s[-1] == '%')
  3546. p->osd_pos.x += 30000;
  3547. s++;
  3548. p->osd_pos.y = (int)(_tstof (s) * 10.0);
  3549. s += _tcslen (s);
  3550. if (s[-1] == '%')
  3551. p->osd_pos.y += 30000;
  3552. break;
  3553. }
  3554. return 1;
  3555. }
  3556. #ifdef GFXFILTER
  3557. for (int j = 0; j < 2; j++) {
  3558. struct gfx_filterdata *gf = &p->gf[j];
  3559. if ((j == 0 && _tcscmp (option, _T("gfx_filter_overlay")) == 0) || (j == 1 && _tcscmp (option, _T("gfx_filter_overlay_rtg")) == 0)) {
  3560. TCHAR *s = _tcschr (value, ',');
  3561. gf->gfx_filteroverlay_overscan = 0;
  3562. gf->gfx_filteroverlay_pos.x = 0;
  3563. gf->gfx_filteroverlay_pos.y = 0;
  3564. gf->gfx_filteroverlay_pos.width = 0;
  3565. gf->gfx_filteroverlay_pos.height = 0;
  3566. if (s)
  3567. *s = 0;
  3568. while (s) {
  3569. *s++ = 0;
  3570. gf->gfx_filteroverlay_overscan = _tstol (s);
  3571. s = _tcschr (s, ':');
  3572. if (!s)
  3573. break;
  3574. break;
  3575. }
  3576. _tcsncpy (gf->gfx_filteroverlay, value, sizeof gf->gfx_filteroverlay / sizeof (TCHAR) - 1);
  3577. gf->gfx_filteroverlay[sizeof gf->gfx_filteroverlay / sizeof (TCHAR) - 1] = 0;
  3578. return 1;
  3579. }
  3580. if ((j == 0 && (_tcscmp (option, _T("gfx_filtermask_pre")) == 0 || _tcscmp (option, _T("gfx_filtermask_post")) == 0)) ||
  3581. (j == 1 && (_tcscmp (option, _T("gfx_filtermask_pre_rtg")) == 0 || _tcscmp (option, _T("gfx_filtermask_post_rtg")) == 0))) {
  3582. if (_tcscmp (option, _T("gfx_filtermask_pre")) == 0 || _tcscmp (option, _T("gfx_filtermask_pre_rtg")) == 0) {
  3583. for (int i = 0; i < MAX_FILTERSHADERS; i++) {
  3584. if (gf->gfx_filtermask[i][0] == 0) {
  3585. _tcscpy (gf->gfx_filtermask[i], value);
  3586. break;
  3587. }
  3588. }
  3589. } else {
  3590. for (int i = 0; i < MAX_FILTERSHADERS; i++) {
  3591. if (gf->gfx_filtermask[i + MAX_FILTERSHADERS][0] == 0) {
  3592. _tcscpy (gf->gfx_filtermask[i + MAX_FILTERSHADERS], value);
  3593. break;
  3594. }
  3595. }
  3596. }
  3597. return 1;
  3598. }
  3599. if ((j == 0 && (_tcscmp (option, _T("gfx_filter_pre")) == 0 || _tcscmp (option, _T("gfx_filter_post")) == 0)) ||
  3600. (j == 1 && (_tcscmp (option, _T("gfx_filter_pre_rtg")) == 0 || _tcscmp (option, _T("gfx_filter_post_rtg")) == 0))) {
  3601. TCHAR *s = _tcschr (value, ':');
  3602. if (s) {
  3603. *s++ = 0;
  3604. if (!_tcscmp (value, _T("D3D"))) {
  3605. if (!p->gfx_api)
  3606. p->gfx_api = 1;
  3607. if (_tcscmp (option, _T("gfx_filter_pre")) == 0 || _tcscmp (option, _T("gfx_filter_pre_rtg")) == 0) {
  3608. for (int i = 0; i < MAX_FILTERSHADERS; i++) {
  3609. if (gf->gfx_filtershader[i][0] == 0) {
  3610. _tcscpy (gf->gfx_filtershader[i], s);
  3611. break;
  3612. }
  3613. }
  3614. } else {
  3615. for (int i = 0; i < MAX_FILTERSHADERS; i++) {
  3616. if (gf->gfx_filtershader[i + MAX_FILTERSHADERS][0] == 0) {
  3617. _tcscpy (gf->gfx_filtershader[i + MAX_FILTERSHADERS], s);
  3618. break;
  3619. }
  3620. }
  3621. }
  3622. }
  3623. }
  3624. return 1;
  3625. }
  3626. if ((j == 0 && _tcscmp (option, _T("gfx_filter")) == 0) || (j == 1 && _tcscmp (option, _T("gfx_filter_rtg")) == 0)) {
  3627. TCHAR *s = _tcschr (value, ':');
  3628. gf->gfx_filter = 0;
  3629. if (s) {
  3630. *s++ = 0;
  3631. if (!_tcscmp (value, _T("D3D"))) {
  3632. if (!p->gfx_api)
  3633. p->gfx_api = 1;
  3634. _tcscpy (gf->gfx_filtershader[2 * MAX_FILTERSHADERS], s);
  3635. for (int i = 0; i < 2 * MAX_FILTERSHADERS; i++) {
  3636. if (!_tcsicmp (gf->gfx_filtershader[i], s)) {
  3637. gf->gfx_filtershader[i][0] = 0;
  3638. gf->gfx_filtermask[i][0] = 0;
  3639. }
  3640. }
  3641. }
  3642. }
  3643. if (!_tcscmp(value, _T("none"))) {
  3644. gf->gfx_filtershader[2 * MAX_FILTERSHADERS][0] = 0;
  3645. for (int i = 0; i < 2 * MAX_FILTERSHADERS; i++) {
  3646. gf->gfx_filtershader[i][0] = 0;
  3647. gf->gfx_filtermask[i][0] = 0;
  3648. }
  3649. } else if (!_tcscmp (value, _T("direct3d"))) {
  3650. if (!p->gfx_api)
  3651. p->gfx_api = 1; // forwards compatibiity
  3652. } else {
  3653. int i = 0;
  3654. while(uaefilters[i].name) {
  3655. if (!_tcscmp (uaefilters[i].cfgname, value)) {
  3656. gf->gfx_filter = uaefilters[i].type;
  3657. break;
  3658. }
  3659. i++;
  3660. }
  3661. }
  3662. return 1;
  3663. }
  3664. if (j == 0 && _tcscmp(option, _T("gfx_filter_mode")) == 0) {
  3665. cfgfile_strval(option, value, _T("gfx_filter_mode"), &gf->gfx_filter_filtermodeh, filtermode2, 0);
  3666. return 1;
  3667. }
  3668. if (j == 1 && _tcscmp(option, _T("gfx_filter_mode_rtg")) == 0) {
  3669. cfgfile_strval(option, value, _T("gfx_filter_mode_rtg"), &gf->gfx_filter_filtermodeh, filtermode2, 0);
  3670. return 1;
  3671. }
  3672. if (j == 0 && _tcscmp(option, _T("gfx_filter_mode2")) == 0) {
  3673. cfgfile_strval(option, value, _T("gfx_filter_mode2"), &gf->gfx_filter_filtermodev, filtermode2v, 0);
  3674. return 1;
  3675. }
  3676. if (j == 1 && _tcscmp(option, _T("gfx_filter_mode2_rtg")) == 0) {
  3677. cfgfile_strval(option, value, _T("gfx_filter_mode2_rtg"), &gf->gfx_filter_filtermodev, filtermode2v, 0);
  3678. return 1;
  3679. }
  3680. if ((j == 0 && cfgfile_string (option, value, _T("gfx_filter_aspect_ratio"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) ||
  3681. (j == 1 && cfgfile_string (option, value, _T("gfx_filter_aspect_ratio_rtg"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR)))) {
  3682. int v1, v2;
  3683. TCHAR *s;
  3684. gf->gfx_filter_aspect = -1;
  3685. v1 = _tstol (tmpbuf);
  3686. s = _tcschr (tmpbuf, ':');
  3687. if (s) {
  3688. v2 = _tstol (s + 1);
  3689. if (v1 < 0 || v2 < 0)
  3690. gf->gfx_filter_aspect = -1;
  3691. else if (v1 == 0 || v2 == 0)
  3692. gf->gfx_filter_aspect = 0;
  3693. else
  3694. gf->gfx_filter_aspect = v1 * ASPECTMULT + v2;
  3695. }
  3696. return 1;
  3697. }
  3698. }
  3699. #endif
  3700. if (_tcscmp (option, _T("gfx_width")) == 0 || _tcscmp (option, _T("gfx_height")) == 0) {
  3701. cfgfile_intval (option, value, _T("gfx_width"), &p->gfx_monitor[0].gfx_size_win.width, 1);
  3702. cfgfile_intval (option, value, _T("gfx_height"), &p->gfx_monitor[0].gfx_size_win.height, 1);
  3703. p->gfx_monitor[0].gfx_size_fs.width = p->gfx_monitor[0].gfx_size_win.width;
  3704. p->gfx_monitor[0].gfx_size_fs.height = p->gfx_monitor[0].gfx_size_win.height;
  3705. return 1;
  3706. }
  3707. if (_tcscmp (option, _T("gfx_fullscreen_multi")) == 0 || _tcscmp (option, _T("gfx_windowed_multi")) == 0) {
  3708. TCHAR tmp[256], *tmpp, *tmpp2;
  3709. struct wh *wh = p->gfx_monitor[0].gfx_size_win_xtra;
  3710. if (_tcscmp (option, _T("gfx_fullscreen_multi")) == 0)
  3711. wh = p->gfx_monitor[0].gfx_size_fs_xtra;
  3712. _stprintf (tmp, _T(",%s,"), value);
  3713. tmpp2 = tmp;
  3714. for (i = 0; i < 4; i++) {
  3715. tmpp = _tcschr (tmpp2, ',');
  3716. tmpp++;
  3717. wh[i].width = _tstol (tmpp);
  3718. while (*tmpp != ',' && *tmpp != 'x' && *tmpp != '*')
  3719. tmpp++;
  3720. wh[i].height = _tstol (tmpp + 1);
  3721. tmpp2 = tmpp;
  3722. }
  3723. return 1;
  3724. }
  3725. if (cfgfile_string(option, value, _T("joyportcustom0"), p->jports_custom[0].custom, sizeof p->jports_custom[0].custom / sizeof(TCHAR)))
  3726. return 1;
  3727. if (cfgfile_string(option, value, _T("joyportcustom1"), p->jports_custom[1].custom, sizeof p->jports_custom[1].custom / sizeof(TCHAR)))
  3728. return 1;
  3729. if (cfgfile_string(option, value, _T("joyportcustom2"), p->jports_custom[2].custom, sizeof p->jports_custom[2].custom / sizeof(TCHAR)))
  3730. return 1;
  3731. if (cfgfile_string(option, value, _T("joyportcustom3"), p->jports_custom[3].custom, sizeof p->jports_custom[3].custom / sizeof(TCHAR)))
  3732. return 1;
  3733. if (cfgfile_string(option, value, _T("joyportcustom4"), p->jports_custom[4].custom, sizeof p->jports_custom[4].custom / sizeof(TCHAR)))
  3734. return 1;
  3735. if (cfgfile_string(option, value, _T("joyportcustom5"), p->jports_custom[5].custom, sizeof p->jports_custom[5].custom / sizeof(TCHAR)))
  3736. return 1;
  3737. if (_tcscmp (option, _T("joyportfriendlyname0")) == 0 || _tcscmp (option, _T("joyportfriendlyname1")) == 0) {
  3738. inputdevice_joyport_config_store(p, value, _tcscmp (option, _T("joyportfriendlyname0")) == 0 ? 0 : 1, -1, -1, 2);
  3739. return 1;
  3740. }
  3741. if (_tcscmp (option, _T("joyportfriendlyname2")) == 0 || _tcscmp (option, _T("joyportfriendlyname3")) == 0) {
  3742. inputdevice_joyport_config_store(p, value, _tcscmp (option, _T("joyportfriendlyname2")) == 0 ? 2 : 3, -1, -1, 2);
  3743. return 1;
  3744. }
  3745. if (_tcscmp (option, _T("joyportname0")) == 0 || _tcscmp (option, _T("joyportname1")) == 0) {
  3746. inputdevice_joyport_config_store(p, value, _tcscmp (option, _T("joyportname0")) == 0 ? 0 : 1, -1, -1, 1);
  3747. return 1;
  3748. }
  3749. if (_tcscmp (option, _T("joyportname2")) == 0 || _tcscmp (option, _T("joyportname3")) == 0) {
  3750. inputdevice_joyport_config_store(p, value, _tcscmp (option, _T("joyportname2")) == 0 ? 2 : 3, -1, -1, 1);
  3751. return 1;
  3752. }
  3753. if (_tcscmp (option, _T("joyport0")) == 0 || _tcscmp (option, _T("joyport1")) == 0) {
  3754. int port = _tcscmp (option, _T("joyport0")) == 0 ? 0 : 1;
  3755. inputdevice_joyport_config_store(p, _T(""), port, -1, -1, 1);
  3756. inputdevice_joyport_config_store(p, _T(""), port, -1, -1, 2);
  3757. inputdevice_joyport_config_store(p, value, port, -1, -1, 0);
  3758. return 1;
  3759. }
  3760. if (_tcscmp (option, _T("joyport2")) == 0 || _tcscmp (option, _T("joyport3")) == 0) {
  3761. int port = _tcscmp (option, _T("joyport2")) == 0 ? 2 : 3;
  3762. inputdevice_joyport_config_store(p, _T(""), port, -1, -1, 1);
  3763. inputdevice_joyport_config_store(p, _T(""), port, -1, -1, 2);
  3764. inputdevice_joyport_config_store(p, value, port, -1, -1, 0);
  3765. return 1;
  3766. }
  3767. if (cfgfile_strval(option, value, _T("joyport0mode"), &p->jports[0].mode, joyportmodes, 0))
  3768. return 1;
  3769. if (cfgfile_strval(option, value, _T("joyport1mode"), &p->jports[1].mode, joyportmodes, 0))
  3770. return 1;
  3771. if (cfgfile_strval(option, value, _T("joyport2mode"), &p->jports[2].mode, joyportmodes, 0))
  3772. return 1;
  3773. if (cfgfile_strval(option, value, _T("joyport3mode"), &p->jports[3].mode, joyportmodes, 0))
  3774. return 1;
  3775. if (cfgfile_strval(option, value, _T("joyport0submode"), &p->jports[0].submode, joyportsubmodes_lightpen, 0))
  3776. return 1;
  3777. if (cfgfile_strval(option, value, _T("joyport1submode"), &p->jports[1].submode, joyportsubmodes_lightpen, 0))
  3778. return 1;
  3779. if (cfgfile_strval(option, value, _T("joyport2submode"), &p->jports[2].submode, joyportsubmodes_lightpen, 0))
  3780. return 1;
  3781. if (cfgfile_strval(option, value, _T("joyport3submode"), &p->jports[3].submode, joyportsubmodes_lightpen, 0))
  3782. return 1;
  3783. if (cfgfile_strval(option, value, _T("joyport0autofire"), &p->jports[0].autofire, joyaf, 0))
  3784. return 1;
  3785. if (cfgfile_strval(option, value, _T("joyport1autofire"), &p->jports[1].autofire, joyaf, 0))
  3786. return 1;
  3787. if (cfgfile_strval(option, value, _T("joyport2autofire"), &p->jports[2].autofire, joyaf, 0))
  3788. return 1;
  3789. if (cfgfile_strval(option, value, _T("joyport3autofire"), &p->jports[3].autofire, joyaf, 0))
  3790. return 1;
  3791. if (cfgfile_yesno (option, value, _T("joyport0keyboardoverride"), &vb)) {
  3792. p->jports[0].nokeyboardoverride = !vb;
  3793. return 1;
  3794. }
  3795. if (cfgfile_yesno (option, value, _T("joyport1keyboardoverride"), &vb)) {
  3796. p->jports[1].nokeyboardoverride = !vb;
  3797. return 1;
  3798. }
  3799. if (cfgfile_yesno (option, value, _T("joyport2keyboardoverride"), &vb)) {
  3800. p->jports[2].nokeyboardoverride = !vb;
  3801. return 1;
  3802. }
  3803. if (cfgfile_yesno (option, value, _T("joyport3keyboardoverride"), &vb)) {
  3804. p->jports[3].nokeyboardoverride = !vb;
  3805. return 1;
  3806. }
  3807. if (cfgfile_path(option, value, _T("trainerfile"), p->trainerfile, sizeof p->trainerfile / sizeof(TCHAR)))
  3808. return 1;
  3809. if (cfgfile_path (option, value, _T("statefile_quit"), p->quitstatefile, sizeof p->quitstatefile / sizeof (TCHAR)))
  3810. return 1;
  3811. if (cfgfile_string (option, value, _T("statefile_name"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) {
  3812. fetch_statefilepath (savestate_fname, sizeof savestate_fname / sizeof (TCHAR));
  3813. _tcscat (savestate_fname, tmpbuf);
  3814. if (_tcslen (savestate_fname) >= 4 && _tcsicmp (savestate_fname + _tcslen (savestate_fname) - 4, _T(".uss")))
  3815. _tcscat (savestate_fname, _T(".uss"));
  3816. return 1;
  3817. }
  3818. if (cfgfile_path (option, value, _T("statefile"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) {
  3819. _tcscpy (p->statefile, tmpbuf);
  3820. _tcscpy (savestate_fname, tmpbuf);
  3821. if (zfile_exists (savestate_fname)) {
  3822. savestate_state = STATE_DORESTORE;
  3823. } else {
  3824. int ok = 0;
  3825. if (savestate_fname[0]) {
  3826. for (;;) {
  3827. TCHAR *p;
  3828. if (my_existsdir (savestate_fname)) {
  3829. ok = 1;
  3830. break;
  3831. }
  3832. p = _tcsrchr (savestate_fname, '\\');
  3833. if (!p)
  3834. p = _tcsrchr (savestate_fname, '/');
  3835. if (!p)
  3836. break;
  3837. *p = 0;
  3838. }
  3839. }
  3840. if (!ok) {
  3841. TCHAR tmp[MAX_DPATH];
  3842. fetch_statefilepath (tmp, sizeof tmp / sizeof (TCHAR));
  3843. _tcscat (tmp, savestate_fname);
  3844. if (zfile_exists (tmp)) {
  3845. _tcscpy (savestate_fname, tmp);
  3846. savestate_state = STATE_DORESTORE;
  3847. } else {
  3848. savestate_fname[0] = 0;
  3849. }
  3850. }
  3851. }
  3852. return 1;
  3853. }
  3854. if (cfgfile_strval (option, value, _T("sound_channels"), &p->sound_stereo, stereomode, 1)) {
  3855. if (p->sound_stereo == SND_NONE) { /* "mixed stereo" compatibility hack */
  3856. p->sound_stereo = SND_STEREO;
  3857. p->sound_mixed_stereo_delay = 5;
  3858. p->sound_stereo_separation = 7;
  3859. }
  3860. return 1;
  3861. }
  3862. if (_tcscmp (option, _T("kbd_lang")) == 0) {
  3863. KbdLang l;
  3864. if ((l = KBD_LANG_DE, strcasecmp (value, _T("de")) == 0)
  3865. || (l = KBD_LANG_DK, strcasecmp (value, _T("dk")) == 0)
  3866. || (l = KBD_LANG_SE, strcasecmp (value, _T("se")) == 0)
  3867. || (l = KBD_LANG_US, strcasecmp (value, _T("us")) == 0)
  3868. || (l = KBD_LANG_FR, strcasecmp (value, _T("fr")) == 0)
  3869. || (l = KBD_LANG_IT, strcasecmp (value, _T("it")) == 0)
  3870. || (l = KBD_LANG_ES, strcasecmp (value, _T("es")) == 0))
  3871. p->keyboard_lang = l;
  3872. else
  3873. cfgfile_warning(_T("Unknown keyboard language\n"));
  3874. return 1;
  3875. }
  3876. if (cfgfile_string (option, value, _T("config_version"), tmpbuf, sizeof (tmpbuf) / sizeof (TCHAR))) {
  3877. TCHAR *tmpp2;
  3878. tmpp = _tcschr (value, '.');
  3879. if (tmpp) {
  3880. *tmpp++ = 0;
  3881. tmpp2 = tmpp;
  3882. p->config_version = _tstol (tmpbuf) << 16;
  3883. tmpp = _tcschr (tmpp, '.');
  3884. if (tmpp) {
  3885. *tmpp++ = 0;
  3886. p->config_version |= _tstol (tmpp2) << 8;
  3887. p->config_version |= _tstol (tmpp);
  3888. }
  3889. }
  3890. return 1;
  3891. }
  3892. if (cfgfile_string (option, value, _T("keyboard_leds"), tmpbuf, sizeof (tmpbuf) / sizeof (TCHAR))) {
  3893. TCHAR *tmpp2 = tmpbuf;
  3894. int i, num;
  3895. p->keyboard_leds[0] = p->keyboard_leds[1] = p->keyboard_leds[2] = 0;
  3896. p->keyboard_leds_in_use = 0;
  3897. _tcscat (tmpbuf, _T(","));
  3898. for (i = 0; i < 3; i++) {
  3899. tmpp = _tcschr (tmpp2, ':');
  3900. if (!tmpp)
  3901. break;
  3902. *tmpp++= 0;
  3903. num = -1;
  3904. if (!strcasecmp (tmpp2, _T("numlock")))
  3905. num = 0;
  3906. if (!strcasecmp (tmpp2, _T("capslock")))
  3907. num = 1;
  3908. if (!strcasecmp (tmpp2, _T("scrolllock")))
  3909. num = 2;
  3910. tmpp2 = tmpp;
  3911. tmpp = _tcschr (tmpp2, ',');
  3912. if (!tmpp)
  3913. break;
  3914. *tmpp++= 0;
  3915. if (num >= 0) {
  3916. p->keyboard_leds[num] = match_string (kbleds, tmpp2);
  3917. if (p->keyboard_leds[num])
  3918. p->keyboard_leds_in_use = 1;
  3919. }
  3920. tmpp2 = tmpp;
  3921. }
  3922. return 1;
  3923. }
  3924. if (_tcscmp (option, _T("displaydata")) == 0 || _tcscmp (option, _T("displaydata_pal")) == 0 || _tcscmp (option, _T("displaydata_ntsc")) == 0) {
  3925. _tcsncpy (tmpbuf, value, sizeof tmpbuf / sizeof (TCHAR) - 1);
  3926. tmpbuf[sizeof tmpbuf / sizeof (TCHAR) - 1] = '\0';
  3927. int vert = -1, horiz = -1, lace = -1, ntsc = -1, framelength = -1, vsync = -1, hres = 0;
  3928. bool locked = false, rtg = false, exit = false;
  3929. bool cmdmode = false, defaultdata = false;
  3930. double rate = -1;
  3931. int rpct = 0;
  3932. TCHAR cmd[MAX_DPATH], filter[64] = { 0 }, label[16] = { 0 };
  3933. TCHAR *tmpp = tmpbuf;
  3934. TCHAR *end = tmpbuf + _tcslen (tmpbuf);
  3935. cmd[0] = 0;
  3936. for (;;) {
  3937. TCHAR *next = _tcschr (tmpp, ',');
  3938. TCHAR *equals = _tcschr (tmpp, '=');
  3939. if (!next)
  3940. next = end;
  3941. if (equals == NULL || equals > next)
  3942. equals = NULL;
  3943. else
  3944. equals++;
  3945. *next = 0;
  3946. if (cmdmode) {
  3947. if (_tcslen(cmd) + _tcslen(tmpp) + 2 < sizeof(cmd) / sizeof(TCHAR)) {
  3948. _tcscat(cmd, tmpp);
  3949. _tcscat(cmd, _T("\n"));
  3950. }
  3951. } else {
  3952. if (!_tcsnicmp(tmpp, _T("cmd="), 4)) {
  3953. cmdmode = true;
  3954. tmpp += 4;
  3955. }
  3956. if (rate < 0)
  3957. rate = _tstof(tmpp);
  3958. else if (!_tcsnicmp(tmpp, _T("v="), 2))
  3959. vert = _tstol(equals);
  3960. else if (!_tcsnicmp(tmpp, _T("h="), 2))
  3961. horiz = _tstol(equals);
  3962. else if (!_tcsnicmp(tmpp, _T("t="), 2))
  3963. _tcsncpy(label, equals, sizeof label / sizeof(TCHAR) - 1);
  3964. else if (!_tcsnicmp(tmpp, _T("filter="), 7))
  3965. _tcsncpy(filter, equals, sizeof filter / sizeof(TCHAR) - 1);
  3966. else if (!_tcsnicmp(tmpp, _T("rpct="), 5))
  3967. rpct = _tstol(equals);
  3968. else if (equals) {
  3969. if (_tcslen(cmd) + _tcslen (tmpp) + 2 < sizeof (cmd) / sizeof (TCHAR)) {
  3970. _tcscat(cmd, tmpp);
  3971. _tcscat(cmd, _T("\n"));
  3972. }
  3973. }
  3974. if (!_tcsnicmp(tmpp, _T("locked"), 4))
  3975. locked = true;
  3976. if (!_tcsnicmp(tmpp, _T("nlace"), 5))
  3977. lace = 0;
  3978. if (!_tcsnicmp(tmpp, _T("lace"), 4))
  3979. lace = 1;
  3980. if (!_tcsnicmp(tmpp, _T("lores"), 5))
  3981. hres |= 1 << RES_LORES;
  3982. if (!_tcsnicmp(tmpp, _T("hires"), 5))
  3983. hres |= 1 << RES_HIRES;
  3984. if (!_tcsnicmp(tmpp, _T("shres"), 5))
  3985. hres |= 1 << RES_SUPERHIRES;
  3986. if (!_tcsnicmp(tmpp, _T("nvsync"), 5))
  3987. vsync = 0;
  3988. if (!_tcsnicmp(tmpp, _T("vsync"), 4))
  3989. vsync = 1;
  3990. if (!_tcsnicmp(tmpp, _T("ntsc"), 4))
  3991. ntsc = 1;
  3992. if (!_tcsnicmp(tmpp, _T("pal"), 3))
  3993. ntsc = 0;
  3994. if (!_tcsnicmp(tmpp, _T("custom"), 6))
  3995. ntsc = 2;
  3996. if (!_tcsnicmp(tmpp, _T("lof"), 3))
  3997. framelength = 1;
  3998. if (!_tcsnicmp(tmpp, _T("shf"), 3))
  3999. framelength = 0;
  4000. if (!_tcsnicmp(tmpp, _T("rtg"), 3))
  4001. rtg = true;
  4002. if (!_tcsnicmp(tmpp, _T("exit"), 4))
  4003. exit = true;
  4004. if (!_tcsnicmp(tmpp, _T("default"), 7))
  4005. defaultdata = true;
  4006. }
  4007. tmpp = next;
  4008. if (tmpp >= end)
  4009. break;
  4010. tmpp++;
  4011. }
  4012. for (int i = 0; i < MAX_CHIPSET_REFRESH; i++) {
  4013. struct chipset_refresh *cr = &p->cr[i];
  4014. if (_tcscmp (option, _T("displaydata_pal")) == 0) {
  4015. i = CHIPSET_REFRESH_PAL;
  4016. cr = &p->cr[i];
  4017. cr->inuse = false;
  4018. _tcscpy (label, _T("PAL"));
  4019. } else if (_tcscmp (option, _T("displaydata_ntsc")) == 0) {
  4020. i = CHIPSET_REFRESH_NTSC;
  4021. cr = &p->cr[i];
  4022. cr->inuse = false;
  4023. _tcscpy (label, _T("NTSC"));
  4024. }
  4025. if (!cr->inuse) {
  4026. cr->inuse = true;
  4027. cr->horiz = horiz;
  4028. cr->vert = vert;
  4029. cr->lace = lace;
  4030. cr->resolution = hres ? hres : 1 + 2 + 4;
  4031. cr->resolution_pct = rpct;
  4032. cr->ntsc = ntsc;
  4033. cr->vsync = vsync;
  4034. cr->locked = locked;
  4035. cr->rtg = rtg;
  4036. cr->exit = exit;
  4037. cr->framelength = framelength;
  4038. cr->rate = rate;
  4039. cr->defaultdata = defaultdata;
  4040. _tcscpy(cr->commands, cmd);
  4041. _tcscpy(cr->label, label);
  4042. TCHAR *se = cfgfile_unescape(filter, NULL);
  4043. _tcscpy(cr->filterprofile, se);
  4044. xfree(se);
  4045. break;
  4046. }
  4047. }
  4048. return 1;
  4049. }
  4050. #ifdef WITH_SLIRP
  4051. if (cfgfile_string (option, value, _T("slirp_ports"), tmpbuf, sizeof (tmpbuf) / sizeof (TCHAR))) {
  4052. TCHAR *tmpp2 = tmpbuf;
  4053. _tcscat (tmpbuf, _T(","));
  4054. for (;;) {
  4055. tmpp = _tcschr (tmpp2, ',');
  4056. if (!tmpp)
  4057. break;
  4058. *tmpp++= 0;
  4059. for (i = 0; i < MAX_SLIRP_REDIRS; i++) {
  4060. struct slirp_redir *sr = &p->slirp_redirs[i];
  4061. if (sr->proto == 0) {
  4062. sr->dstport = _tstol (tmpp2);
  4063. sr->proto = 1;
  4064. break;
  4065. }
  4066. }
  4067. tmpp2 = tmpp;
  4068. }
  4069. return 1;
  4070. }
  4071. if (cfgfile_string (option, value, _T("slirp_redir"), tmpbuf, sizeof (tmpbuf) / sizeof(TCHAR))) {
  4072. TCHAR *tmpp2 = tmpbuf;
  4073. _tcscat (tmpbuf, _T(":"));
  4074. for (i = 0; i < MAX_SLIRP_REDIRS; i++) {
  4075. struct slirp_redir *sr = &p->slirp_redirs[i];
  4076. if (sr->proto == 0) {
  4077. char *s;
  4078. tmpp = _tcschr (tmpp2, ':');
  4079. if (!tmpp)
  4080. break;
  4081. *tmpp++= 0;
  4082. if (!_tcsicmp (tmpp2, _T("tcp")))
  4083. sr->proto = 1;
  4084. else if (!_tcsicmp (tmpp2, _T("udp")))
  4085. sr->proto = 2;
  4086. else
  4087. break;
  4088. tmpp2 = tmpp;
  4089. tmpp = _tcschr (tmpp2, ':');
  4090. if (!tmpp) {
  4091. sr->proto = 0;
  4092. break;
  4093. }
  4094. *tmpp++= 0;
  4095. sr->dstport = _tstol (tmpp2);
  4096. tmpp2 = tmpp;
  4097. tmpp = _tcschr (tmpp2, ':');
  4098. if (!tmpp) {
  4099. sr->proto = 0;
  4100. break;
  4101. }
  4102. *tmpp++= 0;
  4103. sr->srcport = _tstol (tmpp2);
  4104. tmpp2 = tmpp;
  4105. tmpp = _tcschr (tmpp2, ':');
  4106. if (!tmpp)
  4107. break;
  4108. *tmpp++= 0;
  4109. s = ua (tmpp2);
  4110. sr->addr = inet_addr (s);
  4111. xfree (s);
  4112. }
  4113. }
  4114. return 1;
  4115. }
  4116. #endif
  4117. return 0;
  4118. }
  4119. static void decode_rom_ident (TCHAR *romfile, int maxlen, const TCHAR *ident, int romflags)
  4120. {
  4121. const TCHAR *p;
  4122. int ver, rev, subver, subrev, round, i;
  4123. TCHAR model[64], *modelp;
  4124. struct romlist **rl;
  4125. TCHAR *romtxt;
  4126. if (!ident[0])
  4127. return;
  4128. romtxt = xmalloc (TCHAR, 10000);
  4129. romtxt[0] = 0;
  4130. for (round = 0; round < 2; round++) {
  4131. ver = rev = subver = subrev = -1;
  4132. modelp = NULL;
  4133. memset (model, 0, sizeof model);
  4134. p = ident;
  4135. while (*p) {
  4136. TCHAR c = *p++;
  4137. int *pp1 = NULL, *pp2 = NULL;
  4138. if (_totupper (c) == 'V' && _istdigit (*p)) {
  4139. pp1 = &ver;
  4140. pp2 = &rev;
  4141. } else if (_totupper (c) == 'R' && _istdigit (*p)) {
  4142. pp1 = &subver;
  4143. pp2 = &subrev;
  4144. } else if (!_istdigit (c) && c != ' ') {
  4145. _tcsncpy (model, p - 1, (sizeof model) / sizeof (TCHAR) - 1);
  4146. p += _tcslen (model);
  4147. modelp = model;
  4148. }
  4149. if (pp1) {
  4150. *pp1 = _tstol (p);
  4151. while (*p != 0 && *p != '.' && *p != ' ')
  4152. p++;
  4153. if (*p == '.') {
  4154. p++;
  4155. if (pp2)
  4156. *pp2 = _tstol (p);
  4157. }
  4158. }
  4159. if (*p == 0 || *p == ';') {
  4160. rl = getromlistbyident (ver, rev, subver, subrev, modelp, romflags, round > 0);
  4161. if (rl) {
  4162. for (i = 0; rl[i]; i++) {
  4163. if (rl[i]->path && !_tcscmp(rl[i]->path, romfile)) {
  4164. xfree(rl);
  4165. round = 0;
  4166. goto end;
  4167. }
  4168. }
  4169. if (!rl[i]) {
  4170. for (i = 0; rl[i]; i++) {
  4171. if (round) {
  4172. TCHAR romname[MAX_DPATH];
  4173. getromname(rl[i]->rd, romname);
  4174. _tcscat (romtxt, romname);
  4175. _tcscat (romtxt, _T("\n"));
  4176. } else {
  4177. _tcsncpy (romfile, rl[i]->path, maxlen);
  4178. goto end;
  4179. }
  4180. }
  4181. }
  4182. xfree (rl);
  4183. }
  4184. }
  4185. }
  4186. }
  4187. end:
  4188. if (round && romtxt[0]) {
  4189. notify_user_parms (NUMSG_ROMNEED, romtxt, romtxt);
  4190. }
  4191. xfree (romtxt);
  4192. }
  4193. static struct uaedev_config_data *getuci (struct uae_prefs *p)
  4194. {
  4195. if (p->mountitems < MOUNT_CONFIG_SIZE)
  4196. return &p->mountconfig[p->mountitems++];
  4197. return NULL;
  4198. }
  4199. struct uaedev_config_data *add_filesys_config (struct uae_prefs *p, int index, struct uaedev_config_info *ci)
  4200. {
  4201. struct uaedev_config_data *uci;
  4202. int i;
  4203. if (index < 0 && (ci->type == UAEDEV_DIR || ci->type == UAEDEV_HDF) && ci->devname && _tcslen (ci->devname) > 0) {
  4204. for (i = 0; i < p->mountitems; i++) {
  4205. if (p->mountconfig[i].ci.devname && !_tcscmp (p->mountconfig[i].ci.devname, ci->devname))
  4206. return NULL;
  4207. }
  4208. }
  4209. for (;;) {
  4210. if (ci->type == UAEDEV_CD) {
  4211. if (ci->controller_type >= HD_CONTROLLER_TYPE_IDE_FIRST && ci->controller_type <= HD_CONTROLLER_TYPE_IDE_LAST)
  4212. break;
  4213. if (ci->controller_type >= HD_CONTROLLER_TYPE_SCSI_FIRST && ci->controller_type <= HD_CONTROLLER_TYPE_SCSI_LAST)
  4214. break;
  4215. } else if (ci->type == UAEDEV_TAPE) {
  4216. if (ci->controller_type == HD_CONTROLLER_TYPE_UAE)
  4217. break;
  4218. if (ci->controller_type >= HD_CONTROLLER_TYPE_IDE_FIRST && ci->controller_type <= HD_CONTROLLER_TYPE_IDE_LAST)
  4219. break;
  4220. if (ci->controller_type >= HD_CONTROLLER_TYPE_SCSI_FIRST && ci->controller_type <= HD_CONTROLLER_TYPE_SCSI_LAST)
  4221. break;
  4222. } else {
  4223. break;
  4224. }
  4225. return NULL;
  4226. }
  4227. if (index < 0) {
  4228. if (ci->controller_type != HD_CONTROLLER_TYPE_UAE) {
  4229. int ctrl = ci->controller_type;
  4230. int ctrlunit = ci->controller_type_unit;
  4231. int cunit = ci->controller_unit;
  4232. for (;;) {
  4233. for (i = 0; i < p->mountitems; i++) {
  4234. if (p->mountconfig[i].ci.controller_type == ctrl && p->mountconfig[i].ci.controller_type_unit == ctrlunit && p->mountconfig[i].ci.controller_unit == cunit) {
  4235. cunit++;
  4236. if (ctrl >= HD_CONTROLLER_TYPE_IDE_FIRST && ctrl <= HD_CONTROLLER_TYPE_IDE_LAST && cunit == 4)
  4237. return NULL;
  4238. if (ctrl >= HD_CONTROLLER_TYPE_SCSI_FIRST && ctrl <= HD_CONTROLLER_TYPE_SCSI_LAST && cunit >= 7)
  4239. return NULL;
  4240. }
  4241. }
  4242. if (i == p->mountitems) {
  4243. ci->controller_unit = cunit;
  4244. break;
  4245. }
  4246. }
  4247. } else if (ci->controller_type == HD_CONTROLLER_TYPE_UAE) {
  4248. int ctrl = ci->controller_type;
  4249. int ctrlunit = ci->controller_type_unit;
  4250. int cunit = ci->controller_unit;
  4251. for (;;) {
  4252. for (i = 0; i < p->mountitems; i++) {
  4253. if (p->mountconfig[i].ci.controller_type == ctrl && p->mountconfig[i].ci.controller_type_unit == ctrlunit && p->mountconfig[i].ci.controller_unit == cunit) {
  4254. cunit++;
  4255. if (cunit >= MAX_FILESYSTEM_UNITS)
  4256. return NULL;
  4257. }
  4258. }
  4259. if (i == p->mountitems) {
  4260. ci->controller_unit = cunit;
  4261. break;
  4262. }
  4263. }
  4264. }
  4265. if (ci->type == UAEDEV_CD) {
  4266. for (i = 0; i < p->mountitems; i++) {
  4267. if (p->mountconfig[i].ci.type == ci->type)
  4268. return NULL;
  4269. }
  4270. }
  4271. uci = getuci (p);
  4272. uci->configoffset = -1;
  4273. uci->unitnum = -1;
  4274. } else {
  4275. uci = &p->mountconfig[index];
  4276. }
  4277. if (!uci)
  4278. return NULL;
  4279. memcpy (&uci->ci, ci, sizeof (struct uaedev_config_info));
  4280. validatedevicename (uci->ci.devname, NULL);
  4281. validatevolumename (uci->ci.volname, NULL);
  4282. if (!uci->ci.devname[0] && ci->type != UAEDEV_CD && ci->type != UAEDEV_TAPE) {
  4283. TCHAR base[32];
  4284. TCHAR base2[32];
  4285. int num = 0;
  4286. if (uci->ci.rootdir[0] == 0 && ci->type == UAEDEV_DIR)
  4287. _tcscpy (base, _T("RDH"));
  4288. else
  4289. _tcscpy (base, _T("DH"));
  4290. _tcscpy (base2, base);
  4291. for (i = 0; i < p->mountitems; i++) {
  4292. _stprintf (base2, _T("%s%d"), base, num);
  4293. if (!_tcsicmp(base2, p->mountconfig[i].ci.devname)) {
  4294. num++;
  4295. i = -1;
  4296. continue;
  4297. }
  4298. }
  4299. _tcscpy (uci->ci.devname, base2);
  4300. validatedevicename (uci->ci.devname, NULL);
  4301. }
  4302. if (ci->type == UAEDEV_DIR) {
  4303. TCHAR *s = filesys_createvolname (uci->ci.volname, uci->ci.rootdir, NULL, _T("Harddrive"));
  4304. _tcscpy (uci->ci.volname, s);
  4305. xfree (s);
  4306. }
  4307. return uci;
  4308. }
  4309. static void parse_addmem (struct uae_prefs *p, TCHAR *buf, int num)
  4310. {
  4311. int size = 0, addr = 0;
  4312. if (!getintval2 (&buf, &addr, ',', false))
  4313. return;
  4314. if (!getintval2 (&buf, &size, 0, true))
  4315. return;
  4316. if (addr & 0xffff)
  4317. return;
  4318. if ((size & 0xffff) || (size & 0xffff0000) == 0)
  4319. return;
  4320. p->custom_memory_addrs[num] = addr;
  4321. p->custom_memory_sizes[num] = size;
  4322. }
  4323. static void get_filesys_controller (const TCHAR *hdc, int *type, int *typenum, int *num)
  4324. {
  4325. int hdcv = HD_CONTROLLER_TYPE_UAE;
  4326. int hdunit = 0;
  4327. int idx = 0;
  4328. if(_tcslen (hdc) >= 4 && !_tcsncmp (hdc, _T("ide"), 3)) {
  4329. hdcv = HD_CONTROLLER_TYPE_IDE_AUTO;
  4330. hdunit = hdc[3] - '0';
  4331. if (hdunit < 0 || hdunit >= 6)
  4332. hdunit = 0;
  4333. } else if (_tcslen(hdc) >= 5 && !_tcsncmp(hdc, _T("scsi"), 4)) {
  4334. hdcv = HD_CONTROLLER_TYPE_SCSI_AUTO;
  4335. hdunit = hdc[4] - '0';
  4336. if (hdunit < 0 || hdunit >= 8 + 2)
  4337. hdunit = 0;
  4338. } else if (_tcslen(hdc) >= 7 && !_tcsncmp(hdc, _T("custom"), 6)) {
  4339. hdcv = HD_CONTROLLER_TYPE_CUSTOM_FIRST;
  4340. hdunit = hdc[6] - '0';
  4341. if (hdunit < 0 || hdunit >= 8)
  4342. hdunit = 0;
  4343. }
  4344. if (hdcv == HD_CONTROLLER_TYPE_UAE) {
  4345. hdunit = _tstol(hdc + 3);
  4346. if (hdunit >= MAX_FILESYSTEM_UNITS)
  4347. hdunit = 0;
  4348. } else if (hdcv > HD_CONTROLLER_TYPE_UAE) {
  4349. TCHAR control[MAX_DPATH];
  4350. bool found = false;
  4351. _tcscpy(control, hdc);
  4352. TCHAR *extend = (TCHAR*)_tcschr(control, ',');
  4353. if (extend)
  4354. extend[0] = 0;
  4355. const TCHAR *ext = _tcsrchr(control, '_');
  4356. if (ext) {
  4357. ext++;
  4358. int len = _tcslen(ext);
  4359. if (len > 2 && ext[len - 2] == '-' && ext[len - 1] >= '2' && ext[len - 1] <= '9') {
  4360. idx = ext[len - 1] - '1';
  4361. len -= 2;
  4362. }
  4363. for (int i = 0; hdcontrollers[i].label; i++) {
  4364. const TCHAR *ext2 = _tcsrchr(hdcontrollers[i].label, '_');
  4365. if (ext2) {
  4366. ext2++;
  4367. if (_tcslen(ext2) == len && !_tcsnicmp(ext, ext2, len) && hdc[0] == hdcontrollers[i].label[0]) {
  4368. if (hdcontrollers[i].romtype) {
  4369. for (int j = 0; expansionroms[j].name; j++) {
  4370. if ((expansionroms[j].romtype & ROMTYPE_MASK) == hdcontrollers[i].romtype) {
  4371. if (hdcv == HD_CONTROLLER_TYPE_IDE_AUTO) {
  4372. hdcv = j + HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST;
  4373. } else if (hdcv == HD_CONTROLLER_TYPE_SCSI_AUTO) {
  4374. hdcv = j + HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST;
  4375. } else {
  4376. hdcv = j + HD_CONTROLLER_TYPE_CUSTOM_FIRST;
  4377. }
  4378. break;
  4379. }
  4380. }
  4381. }
  4382. if (hdcv == HD_CONTROLLER_TYPE_IDE_AUTO) {
  4383. hdcv = i;
  4384. } else if (hdcv == HD_CONTROLLER_TYPE_SCSI_AUTO) {
  4385. hdcv = i + HD_CONTROLLER_EXPANSION_MAX;
  4386. }
  4387. found = true;
  4388. break;
  4389. }
  4390. }
  4391. }
  4392. if (!found) {
  4393. for (int i = 0; expansionroms[i].name; i++) {
  4394. const struct expansionromtype *ert = &expansionroms[i];
  4395. if (_tcslen(ert->name) == len && !_tcsnicmp(ext, ert->name, len)) {
  4396. if (hdcv == HD_CONTROLLER_TYPE_IDE_AUTO) {
  4397. hdcv = HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST + i;
  4398. } else if (hdcv == HD_CONTROLLER_TYPE_SCSI_AUTO) {
  4399. hdcv = HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST + i;
  4400. } else {
  4401. hdcv = HD_CONTROLLER_TYPE_CUSTOM_FIRST + i;
  4402. }
  4403. break;
  4404. }
  4405. }
  4406. }
  4407. }
  4408. }
  4409. if (idx >= MAX_DUPLICATE_EXPANSION_BOARDS)
  4410. idx = MAX_DUPLICATE_EXPANSION_BOARDS - 1;
  4411. if (hdunit < 0)
  4412. hdunit = 0;
  4413. *type = hdcv;
  4414. *typenum = idx;
  4415. *num = hdunit;
  4416. }
  4417. static bool parse_geo (const TCHAR *tname, struct uaedev_config_info *uci, struct hardfiledata *hfd, bool empty, bool addgeom)
  4418. {
  4419. int found = 0;
  4420. TCHAR tmp[200], section[200];
  4421. struct ini_data *ini;
  4422. bool ret = false;
  4423. TCHAR tgname[MAX_DPATH];
  4424. cfgfile_resolve_path_out_load(tname, tgname, MAX_DPATH, PATH_HDF);
  4425. ini = ini_load(tgname, true);
  4426. if (!ini)
  4427. return ret;
  4428. _tcscpy(tmp, _T("empty"));
  4429. section[0] = 0;
  4430. if (empty && ini_getstring(ini, tmp, NULL, NULL)) {
  4431. _tcscpy(section, tmp);
  4432. found = 1;
  4433. }
  4434. _tcscpy(tmp, _T("default"));
  4435. if (!empty && ini_getstring(ini, tmp, NULL, NULL)) {
  4436. _tcscpy(section, tmp);
  4437. found = 1;
  4438. }
  4439. _tcscpy(tmp, _T("geometry"));
  4440. if (ini_getstring(ini, tmp, NULL, NULL)) {
  4441. _tcscpy(section, tmp);
  4442. found = 1;
  4443. }
  4444. if (hfd) {
  4445. _stprintf(tmp, _T("%llu"), hfd->virtsize);
  4446. if (ini_getstring(ini, tmp, NULL, NULL)) {
  4447. _tcscpy(section, tmp);
  4448. found = 1;
  4449. }
  4450. }
  4451. if (found) {
  4452. ret = true;
  4453. write_log(_T("Geometry file '%s' section '%s' found\n"), tgname, section);
  4454. if (addgeom) {
  4455. _tcscpy(uci->geometry, tname);
  4456. }
  4457. int idx = 0;
  4458. for (;;) {
  4459. TCHAR *key = NULL, *val = NULL;
  4460. int v;
  4461. if (!ini_getsectionstring(ini, section, idx, &key, &val))
  4462. break;
  4463. //write_log(_T("%s:%s\n"), key, val);
  4464. if (val[0] == '0' && _totupper (val[1]) == 'X') {
  4465. TCHAR *endptr;
  4466. v = _tcstol (val, &endptr, 16);
  4467. } else {
  4468. v = _tstol (val);
  4469. }
  4470. if (!_tcsicmp (key, _T("psurfaces")))
  4471. uci->pheads = v;
  4472. if (!_tcsicmp (key, _T("psectorspertrack")) || !_tcsicmp (key, _T("pblockspertrack")))
  4473. uci->psecs = v;
  4474. if (!_tcsicmp (key, _T("pcyls")))
  4475. uci->pcyls = v;
  4476. if (!_tcsicmp (key, _T("surfaces")))
  4477. uci->surfaces = v;
  4478. if (!_tcsicmp (key, _T("sectorspertrack")) || !_tcsicmp (key, _T("blockspertrack")))
  4479. uci->sectors = v;
  4480. if (!_tcsicmp (key, _T("sectorsperblock")))
  4481. uci->sectorsperblock = v;
  4482. if (!_tcsicmp (key, _T("reserved")))
  4483. uci->reserved = v;
  4484. if (!_tcsicmp (key, _T("lowcyl")))
  4485. uci->lowcyl = v;
  4486. if (!_tcsicmp (key, _T("highcyl")) || !_tcsicmp (key, _T("cyl")) || !_tcsicmp (key, _T("cyls")))
  4487. uci->highcyl = v;
  4488. if (!_tcsicmp (key, _T("blocksize")) || !_tcsicmp (key, _T("sectorsize")))
  4489. uci->blocksize = v;
  4490. if (!_tcsicmp (key, _T("buffers")))
  4491. uci->buffers = v;
  4492. if (!_tcsicmp (key, _T("maxtransfer")))
  4493. uci->maxtransfer = v;
  4494. if (!_tcsicmp (key, _T("interleave")))
  4495. uci->interleave = v;
  4496. if (!_tcsicmp (key, _T("dostype")))
  4497. uci->dostype = v;
  4498. if (!_tcsicmp (key, _T("bufmemtype")))
  4499. uci->bufmemtype = v;
  4500. if (!_tcsicmp (key, _T("stacksize")))
  4501. uci->stacksize = v;
  4502. if (!_tcsicmp (key, _T("mask")))
  4503. uci->mask = v;
  4504. if (!_tcsicmp (key, _T("unit")))
  4505. uci->unit = v;
  4506. if (!_tcsicmp (key, _T("controller")))
  4507. get_filesys_controller (val, &uci->controller_type, &uci->controller_type_unit, &uci->controller_unit);
  4508. if (!_tcsicmp (key, _T("flags")))
  4509. uci->flags = v;
  4510. if (!_tcsicmp (key, _T("priority")))
  4511. uci->priority = v;
  4512. if (!_tcsicmp (key, _T("forceload")))
  4513. uci->forceload = v;
  4514. if (!_tcsicmp (key, _T("bootpri"))) {
  4515. if (v < -129)
  4516. v = -129;
  4517. if (v > 127)
  4518. v = 127;
  4519. uci->bootpri = v;
  4520. }
  4521. if (!_tcsicmp (key, _T("filesystem")))
  4522. _tcscpy (uci->filesys, val);
  4523. if (!_tcsicmp (key, _T("device")))
  4524. _tcscpy (uci->devname, val);
  4525. if (!_tcsicmp(key, _T("badblocks"))) {
  4526. TCHAR *p = val;
  4527. while (p && *p && uci->badblock_num < MAX_UAEDEV_BADBLOCKS) {
  4528. struct uaedev_badblock *bb = &uci->badblocks[uci->badblock_num];
  4529. if (!_istdigit(*p))
  4530. break;
  4531. bb->first = _tstol(p);
  4532. bb->last = bb->first;
  4533. TCHAR *p1 = _tcschr(p, ',');
  4534. TCHAR *p2 = NULL;
  4535. if (p1) {
  4536. p2 = p1 + 1;
  4537. *p1 = 0;
  4538. }
  4539. p1 = _tcschr(p, '-');
  4540. if (p1) {
  4541. bb->last = _tstol(p1 + 1);
  4542. }
  4543. uci->badblock_num++;
  4544. p = p2;
  4545. }
  4546. }
  4547. xfree (val);
  4548. xfree (key);
  4549. idx++;
  4550. }
  4551. }
  4552. uae_u8 *out;
  4553. int outsize;
  4554. if (ini_getdata(ini, _T("MODE SENSE"), _T("03"), &out, &outsize) && outsize >= 16) {
  4555. uci->psecs = (out[10] << 8) | (out[11] << 0);
  4556. uci->blocksize = (out[12] << 8) | (out[13] << 0);
  4557. xfree(out);
  4558. ret = true;
  4559. }
  4560. if (ini_getdata(ini, _T("MODE SENSE"), _T("04"), &out, &outsize) && outsize >= 20) {
  4561. uci->pheads = out[5];
  4562. uci->pcyls = (out[2] << 16) | (out[3] << 8) | (out[4] << 0);
  4563. xfree(out);
  4564. ret = true;
  4565. }
  4566. if (ini_getdata(ini, _T("READ CAPACITY"), _T("DATA"), &out, &outsize) && outsize >= 8) {
  4567. uci->blocksize = (out[4] << 24) | (out[5] << 16) | (out[6] << 8) | (out[7] << 0);
  4568. uci->max_lba = ((out[0] << 24) | (out[1] << 16) | (out[2] << 8) | (out[3] << 0)) + 1;
  4569. xfree(out);
  4570. ret = true;
  4571. }
  4572. void ata_parse_identity(uae_u8 *out, struct uaedev_config_info *uci, bool *lba, bool *lba48, int *max_multiple);
  4573. bool ata_get_identity(struct ini_data *ini, uae_u8 *out, bool overwrite);
  4574. uae_u8 ident[512];
  4575. if (ata_get_identity(ini, ident, true)) {
  4576. bool lba, lba48;
  4577. int max_multiple;
  4578. ata_parse_identity(ident, uci, &lba, &lba48, &max_multiple);
  4579. ret = true;
  4580. }
  4581. ini_free(ini);
  4582. return ret;
  4583. }
  4584. bool get_hd_geometry (struct uaedev_config_info *uci)
  4585. {
  4586. TCHAR tname[MAX_DPATH];
  4587. fetch_configurationpath (tname, sizeof tname / sizeof (TCHAR));
  4588. _tcscat (tname, _T("default.geo"));
  4589. if (zfile_exists (tname)) {
  4590. struct hardfiledata hfd;
  4591. memset (&hfd, 0, sizeof hfd);
  4592. hfd.ci.readonly = true;
  4593. hfd.ci.blocksize = 512;
  4594. if (hdf_open (&hfd, uci->rootdir) > 0) {
  4595. parse_geo (tname, uci, &hfd, false, false);
  4596. hdf_close (&hfd);
  4597. } else {
  4598. parse_geo (tname, uci, NULL, true, false);
  4599. }
  4600. }
  4601. if (uci->geometry[0]) {
  4602. return parse_geo (uci->geometry, uci, NULL, false, true);
  4603. } else if (uci->rootdir[0]) {
  4604. _tcscpy (tname, uci->rootdir);
  4605. _tcscat (tname, _T(".geo"));
  4606. return parse_geo (tname, uci, NULL, false, true);
  4607. }
  4608. return false;
  4609. }
  4610. static int cfgfile_parse_partial_newfilesys (struct uae_prefs *p, int nr, int type, const TCHAR *value, int unit, bool uaehfentry)
  4611. {
  4612. TCHAR *tmpp;
  4613. TCHAR *name = NULL, *path = NULL;
  4614. // read only harddrive name
  4615. if (!uaehfentry)
  4616. return 0;
  4617. if (type != 1)
  4618. return 0;
  4619. tmpp = getnextentry (&value, ',');
  4620. if (!tmpp)
  4621. return 0;
  4622. xfree (tmpp);
  4623. tmpp = getnextentry (&value, ':');
  4624. if (!tmpp)
  4625. return 0;
  4626. xfree (tmpp);
  4627. name = getnextentry (&value, ':');
  4628. if (name && _tcslen (name) > 0) {
  4629. path = getnextentry (&value, ',');
  4630. if (path && _tcslen (path) > 0) {
  4631. for (int i = 0; i < MAX_FILESYSTEM_UNITS; i++) {
  4632. struct uaedev_config_info *uci = &p->mountconfig[i].ci;
  4633. if (_tcsicmp (uci->rootdir, name) == 0) {
  4634. _tcscat (uci->rootdir, _T(":"));
  4635. _tcscat (uci->rootdir, path);
  4636. }
  4637. }
  4638. }
  4639. }
  4640. xfree (path);
  4641. xfree (name);
  4642. return 1;
  4643. }
  4644. static int cfgfile_parse_newfilesys (struct uae_prefs *p, int nr, int type, TCHAR *value, int unit, bool uaehfentry)
  4645. {
  4646. struct uaedev_config_info uci;
  4647. TCHAR *tmpp = _tcschr (value, ','), *tmpp2;
  4648. TCHAR *str = NULL;
  4649. TCHAR devname[MAX_DPATH], volname[MAX_DPATH];
  4650. devname[0] = volname[0] = 0;
  4651. uci_set_defaults (&uci, false);
  4652. config_newfilesystem = 1;
  4653. if (tmpp == 0)
  4654. goto invalid_fs;
  4655. *tmpp++ = '\0';
  4656. if (strcasecmp (value, _T("ro")) == 0)
  4657. uci.readonly = true;
  4658. else if (strcasecmp (value, _T("rw")) == 0)
  4659. uci.readonly = false;
  4660. else
  4661. goto invalid_fs;
  4662. value = tmpp;
  4663. if (type == 0) {
  4664. uci.type = UAEDEV_DIR;
  4665. tmpp = _tcschr (value, ':');
  4666. if (tmpp == 0)
  4667. goto empty_fs;
  4668. *tmpp++ = 0;
  4669. _tcscpy (devname, value);
  4670. tmpp2 = tmpp;
  4671. tmpp = _tcschr (tmpp, ':');
  4672. if (tmpp == 0)
  4673. goto empty_fs;
  4674. *tmpp++ = 0;
  4675. _tcscpy (volname, tmpp2);
  4676. tmpp2 = tmpp;
  4677. // quoted special case
  4678. if (tmpp2[0] == '\"') {
  4679. const TCHAR *end;
  4680. TCHAR *n = cfgfile_unescape (tmpp2, &end, 0, false);
  4681. if (!n)
  4682. goto invalid_fs;
  4683. _tcscpy (uci.rootdir, n);
  4684. xfree(n);
  4685. tmpp = (TCHAR*)end;
  4686. *tmpp++ = 0;
  4687. } else {
  4688. tmpp = _tcschr (tmpp, ',');
  4689. if (tmpp == 0)
  4690. goto empty_fs;
  4691. *tmpp++ = 0;
  4692. _tcscpy (uci.rootdir, tmpp2);
  4693. }
  4694. _tcscpy (uci.volname, volname);
  4695. _tcscpy (uci.devname, devname);
  4696. if (! getintval (&tmpp, &uci.bootpri, 0))
  4697. goto empty_fs;
  4698. } else if (type == 1 || ((type == 2 || type == 3) && uaehfentry)) {
  4699. tmpp = _tcschr (value, ':');
  4700. if (tmpp == 0)
  4701. goto invalid_fs;
  4702. *tmpp++ = '\0';
  4703. _tcscpy (devname, value);
  4704. tmpp2 = tmpp;
  4705. // quoted special case
  4706. if (tmpp2[0] == '\"') {
  4707. const TCHAR *end;
  4708. TCHAR *n = cfgfile_unescape (tmpp2, &end, 0, false);
  4709. if (!n)
  4710. goto invalid_fs;
  4711. _tcscpy (uci.rootdir, n);
  4712. xfree(n);
  4713. tmpp = (TCHAR*)end;
  4714. *tmpp++ = 0;
  4715. } else {
  4716. tmpp = _tcschr (tmpp, ',');
  4717. if (tmpp == 0)
  4718. goto invalid_fs;
  4719. *tmpp++ = 0;
  4720. _tcscpy (uci.rootdir, tmpp2);
  4721. }
  4722. if (uci.rootdir[0] != ':')
  4723. get_hd_geometry (&uci);
  4724. _tcscpy (uci.devname, devname);
  4725. if (! getintval (&tmpp, &uci.sectors, ',')
  4726. || ! getintval (&tmpp, &uci.surfaces, ',')
  4727. || ! getintval (&tmpp, &uci.reserved, ',')
  4728. || ! getintval (&tmpp, &uci.blocksize, ','))
  4729. goto invalid_fs;
  4730. if (getintval2 (&tmpp, &uci.bootpri, ',', false)) {
  4731. const TCHAR *end;
  4732. TCHAR *n;
  4733. tmpp2 = tmpp;
  4734. // quoted special case
  4735. if (tmpp2[0] == '\"') {
  4736. const TCHAR *end;
  4737. TCHAR *n = cfgfile_unescape (tmpp2, &end, 0, false);
  4738. if (!n)
  4739. goto invalid_fs;
  4740. _tcscpy (uci.filesys, n);
  4741. xfree(n);
  4742. tmpp = (TCHAR*)end;
  4743. *tmpp++ = 0;
  4744. } else {
  4745. tmpp = _tcschr (tmpp, ',');
  4746. if (tmpp == 0)
  4747. goto empty_fs;
  4748. *tmpp++ = 0;
  4749. _tcscpy (uci.filesys, tmpp2);
  4750. }
  4751. get_filesys_controller (tmpp, &uci.controller_type, &uci.controller_type_unit, &uci.controller_unit);
  4752. tmpp2 = _tcschr (tmpp, ',');
  4753. if (tmpp2) {
  4754. tmpp2++;
  4755. if (getintval2 (&tmpp2, &uci.highcyl, ',', false)) {
  4756. getintval (&tmpp2, &uci.pcyls, '/');
  4757. getintval (&tmpp2, &uci.pheads, '/');
  4758. getintval2 (&tmpp2, &uci.psecs, '/', true);
  4759. if (uci.pheads && uci.psecs) {
  4760. uci.physical_geometry = true;
  4761. } else {
  4762. uci.pheads = uci.psecs = uci.pcyls = 0;
  4763. uci.physical_geometry = false;
  4764. }
  4765. if (tmpp2[0]) {
  4766. if (tmpp2[0] == '\"') {
  4767. n = cfgfile_unescape (tmpp2, &end, 0, false);
  4768. if (!n)
  4769. goto invalid_fs;
  4770. _tcscpy(uci.geometry, n);
  4771. xfree(n);
  4772. }
  4773. }
  4774. }
  4775. }
  4776. uci.controller_media_type = 0;
  4777. uci.unit_feature_level = 1;
  4778. if (cfgfile_option_find(tmpp2, _T("CF")))
  4779. uci.controller_media_type = 1;
  4780. else if (cfgfile_option_find(tmpp2, _T("HD")))
  4781. uci.controller_media_type = 0;
  4782. TCHAR *pflags;
  4783. if ((pflags = cfgfile_option_get(tmpp2, _T("flags")))) {
  4784. getintval(&pflags, &uci.unit_special_flags, 0);
  4785. xfree(pflags);
  4786. }
  4787. if (cfgfile_option_find(tmpp2, _T("lock")))
  4788. uci.lock = true;
  4789. if (cfgfile_option_find(tmpp2, _T("identity")))
  4790. uci.loadidentity = true;
  4791. if (cfgfile_option_find(tmpp2, _T("SCSI2")))
  4792. uci.unit_feature_level = HD_LEVEL_SCSI_2;
  4793. else if (cfgfile_option_find(tmpp2, _T("SCSI1")))
  4794. uci.unit_feature_level = HD_LEVEL_SCSI_1;
  4795. else if (cfgfile_option_find(tmpp2, _T("SASIE")))
  4796. uci.unit_feature_level = HD_LEVEL_SASI_ENHANCED;
  4797. else if (cfgfile_option_find(tmpp2, _T("SASI")))
  4798. uci.unit_feature_level = HD_LEVEL_SASI;
  4799. else if (cfgfile_option_find(tmpp2, _T("SASI_CHS")))
  4800. uci.unit_feature_level = HD_LEVEL_SASI_CHS;
  4801. else if (cfgfile_option_find(tmpp2, _T("ATA2+S")))
  4802. uci.unit_feature_level = HD_LEVEL_ATA_2S;
  4803. else if (cfgfile_option_find(tmpp2, _T("ATA2+")))
  4804. uci.unit_feature_level = HD_LEVEL_ATA_2;
  4805. else if (cfgfile_option_find(tmpp2, _T("ATA1")))
  4806. uci.unit_feature_level = HD_LEVEL_ATA_1;
  4807. }
  4808. if (type == 2) {
  4809. uci.device_emu_unit = unit;
  4810. uci.blocksize = 2048;
  4811. uci.readonly = true;
  4812. uci.type = UAEDEV_CD;
  4813. } else if (type == 3) {
  4814. uci.device_emu_unit = unit;
  4815. uci.blocksize = 512;
  4816. uci.type = UAEDEV_TAPE;
  4817. } else {
  4818. uci.type = UAEDEV_HDF;
  4819. }
  4820. } else {
  4821. goto invalid_fs;
  4822. }
  4823. empty_fs:
  4824. if (uci.rootdir[0]) {
  4825. if (_tcslen (uci.rootdir) > 3 && uci.rootdir[0] == 'H' && uci.rootdir[1] == 'D' && uci.rootdir[2] == '_') {
  4826. memmove (uci.rootdir, uci.rootdir + 2, (_tcslen (uci.rootdir + 2) + 1) * sizeof (TCHAR));
  4827. uci.rootdir[0] = ':';
  4828. }
  4829. }
  4830. if (uci.geometry[0]) {
  4831. parse_geo(uci.geometry, &uci, NULL, false, true);
  4832. }
  4833. #ifdef FILESYS
  4834. add_filesys_config (p, nr, &uci);
  4835. #endif
  4836. xfree (str);
  4837. return 1;
  4838. invalid_fs:
  4839. cfgfile_warning(_T("Invalid filesystem/hardfile/cd specification.\n"));
  4840. return 1;
  4841. }
  4842. static int cfgfile_parse_filesys (struct uae_prefs *p, const TCHAR *option, TCHAR *value)
  4843. {
  4844. int i;
  4845. for (i = 0; i < MAX_FILESYSTEM_UNITS; i++) {
  4846. TCHAR tmp[100];
  4847. _stprintf (tmp, _T("uaehf%d"), i);
  4848. if (!_tcscmp (option, tmp)) {
  4849. for (;;) {
  4850. int type = -1;
  4851. int unit = -1;
  4852. TCHAR *tmpp = _tcschr (value, ',');
  4853. if (tmpp == NULL)
  4854. return 1;
  4855. *tmpp++ = 0;
  4856. if (_tcsicmp (value, _T("hdf")) == 0) {
  4857. type = 1;
  4858. cfgfile_parse_partial_newfilesys (p, -1, type, tmpp, unit, true);
  4859. return 1;
  4860. } else if (_tcsnicmp (value, _T("cd"), 2) == 0 && (value[2] == 0 || value[3] == 0)) {
  4861. unit = 0;
  4862. if (value[2] > 0)
  4863. unit = value[2] - '0';
  4864. if (unit >= 0 && unit <= MAX_TOTAL_SCSI_DEVICES) {
  4865. type = 2;
  4866. }
  4867. } else if (_tcsnicmp (value, _T("tape"), 4) == 0 && (value[4] == 0 || value[5] == 0)) {
  4868. unit = 0;
  4869. if (value[4] > 0)
  4870. unit = value[4] - '0';
  4871. if (unit >= 0 && unit <= MAX_TOTAL_SCSI_DEVICES) {
  4872. type = 3;
  4873. }
  4874. } else if (_tcsicmp (value, _T("dir")) != 0) {
  4875. type = 0;
  4876. return 1; /* ignore for now */
  4877. }
  4878. if (type >= 0)
  4879. cfgfile_parse_newfilesys (p, -1, type, tmpp, unit, true);
  4880. return 1;
  4881. }
  4882. return 1;
  4883. } else if (!_tcsncmp (option, tmp, _tcslen (tmp)) && option[_tcslen (tmp)] == '_') {
  4884. struct uaedev_config_info *uci = &currprefs.mountconfig[i].ci;
  4885. if (uci->devname) {
  4886. const TCHAR *s = &option[_tcslen (tmp) + 1];
  4887. if (!_tcscmp (s, _T("bootpri"))) {
  4888. getintval (&value, &uci->bootpri, 0);
  4889. } else if (!_tcscmp (s, _T("read-only"))) {
  4890. cfgfile_yesno (NULL, value, NULL, &uci->readonly);
  4891. } else if (!_tcscmp (s, _T("volumename"))) {
  4892. _tcscpy (uci->volname, value);
  4893. } else if (!_tcscmp (s, _T("devicename"))) {
  4894. _tcscpy (uci->devname, value);
  4895. } else if (!_tcscmp (s, _T("root"))) {
  4896. _tcscpy (uci->rootdir, value);
  4897. } else if (!_tcscmp (s, _T("filesys"))) {
  4898. _tcscpy (uci->filesys, value);
  4899. } else if (!_tcscmp (s, _T("geometry"))) {
  4900. _tcscpy (uci->geometry, value);
  4901. } else if (!_tcscmp (s, _T("controller"))) {
  4902. get_filesys_controller (value, &uci->controller_type, &uci->controller_type_unit, &uci->controller_unit);
  4903. }
  4904. }
  4905. }
  4906. }
  4907. if (_tcscmp (option, _T("filesystem")) == 0
  4908. || _tcscmp (option, _T("hardfile")) == 0)
  4909. {
  4910. struct uaedev_config_info uci;
  4911. TCHAR *tmpp = _tcschr (value, ',');
  4912. TCHAR *str;
  4913. bool hdf;
  4914. uci_set_defaults (&uci, false);
  4915. if (config_newfilesystem)
  4916. return 1;
  4917. if (tmpp == 0)
  4918. goto invalid_fs;
  4919. *tmpp++ = '\0';
  4920. if (_tcscmp (value, _T("1")) == 0 || strcasecmp (value, _T("ro")) == 0
  4921. || strcasecmp (value, _T("readonly")) == 0
  4922. || strcasecmp (value, _T("read-only")) == 0)
  4923. uci.readonly = true;
  4924. else if (_tcscmp (value, _T("0")) == 0 || strcasecmp (value, _T("rw")) == 0
  4925. || strcasecmp (value, _T("readwrite")) == 0
  4926. || strcasecmp (value, _T("read-write")) == 0)
  4927. uci.readonly = false;
  4928. else
  4929. goto invalid_fs;
  4930. value = tmpp;
  4931. if (_tcscmp (option, _T("filesystem")) == 0) {
  4932. hdf = false;
  4933. tmpp = _tcschr (value, ':');
  4934. if (tmpp == 0)
  4935. goto invalid_fs;
  4936. *tmpp++ = '\0';
  4937. _tcscpy (uci.volname, value);
  4938. _tcscpy (uci.rootdir, tmpp);
  4939. } else {
  4940. hdf = true;
  4941. if (! getintval (&value, &uci.sectors, ',')
  4942. || ! getintval (&value, &uci.surfaces, ',')
  4943. || ! getintval (&value, &uci.reserved, ',')
  4944. || ! getintval (&value, &uci.blocksize, ','))
  4945. goto invalid_fs;
  4946. _tcscpy (uci.rootdir, value);
  4947. }
  4948. str = cfgfile_subst_path_load (UNEXPANDED, &p->path_hardfile, uci.rootdir, true);
  4949. if (uci.geometry[0])
  4950. parse_geo(uci.geometry, &uci, NULL, false, false);
  4951. #ifdef FILESYS
  4952. uci.type = hdf ? UAEDEV_HDF : UAEDEV_DIR;
  4953. add_filesys_config (p, -1, &uci);
  4954. #endif
  4955. xfree (str);
  4956. return 1;
  4957. invalid_fs:
  4958. cfgfile_warning(_T("Invalid filesystem/hardfile specification.\n"));
  4959. return 1;
  4960. }
  4961. if (_tcscmp (option, _T("filesystem2")) == 0)
  4962. return cfgfile_parse_newfilesys (p, -1, 0, value, -1, false);
  4963. if (_tcscmp (option, _T("hardfile2")) == 0)
  4964. return cfgfile_parse_newfilesys (p, -1, 1, value, -1, false);
  4965. if (_tcscmp (option, _T("filesystem_extra")) == 0) {
  4966. int idx = 0;
  4967. TCHAR *s = value;
  4968. _tcscat(s, _T(","));
  4969. struct uaedev_config_info *ci = NULL;
  4970. for (;;) {
  4971. TCHAR *tmpp = _tcschr (s, ',');
  4972. if (tmpp == NULL)
  4973. return 1;
  4974. *tmpp++ = 0;
  4975. if (idx == 0) {
  4976. for (i = 0; i < p->mountitems; i++) {
  4977. if (p->mountconfig[i].ci.devname && !_tcscmp (p->mountconfig[i].ci.devname, s)) {
  4978. ci = &p->mountconfig[i].ci;
  4979. break;
  4980. }
  4981. }
  4982. if (!ci || ci->type != UAEDEV_DIR)
  4983. return 1;
  4984. } else {
  4985. bool b = true;
  4986. TCHAR *tmpp2 = _tcschr(s, '=');
  4987. if (tmpp2) {
  4988. *tmpp2++ = 0;
  4989. if (!strcasecmp(tmpp2, _T("false")))
  4990. b = false;
  4991. }
  4992. if (!strcasecmp(s, _T("inject_icons"))) {
  4993. ci->inject_icons = b;
  4994. }
  4995. }
  4996. idx++;
  4997. s = tmpp;
  4998. }
  4999. }
  5000. return 0;
  5001. }
  5002. static bool cfgfile_read_board_rom(struct uae_prefs *p, const TCHAR *option, const TCHAR *value, struct multipath *mp)
  5003. {
  5004. TCHAR buf[256], buf2[MAX_DPATH], buf3[MAX_DPATH];
  5005. bool dummy;
  5006. int val;
  5007. const struct expansionromtype *ert;
  5008. for (int i = 0; expansionroms[i].name; i++) {
  5009. struct boardromconfig *brc;
  5010. int idx;
  5011. ert = &expansionroms[i];
  5012. for (int j = 0; j < MAX_DUPLICATE_EXPANSION_BOARDS; j++) {
  5013. TCHAR name[256];
  5014. if (j == 0)
  5015. _tcscpy(name, ert->name);
  5016. else
  5017. _stprintf(name, _T("%s-%d"), ert->name, j + 1);
  5018. _stprintf(buf, _T("scsi_%s"), name);
  5019. if (cfgfile_yesno(option, value, buf, &dummy)) {
  5020. return true;
  5021. }
  5022. _stprintf(buf, _T("%s_rom_file"), name);
  5023. if (cfgfile_path(option, value, buf, buf2, MAX_DPATH / sizeof (TCHAR), mp)) {
  5024. if (buf2[0]) {
  5025. if (ert->deviceflags & EXPANSIONTYPE_NET) {
  5026. // make sure network settings are available before parsing net "rom" entries
  5027. ethernet_updateselection();
  5028. }
  5029. brc = get_device_rom_new(p, ert->romtype, j, &idx);
  5030. _tcscpy(brc->roms[idx].romfile, buf2);
  5031. }
  5032. return true;
  5033. }
  5034. _stprintf(buf, _T("%s_rom_file_id"), name);
  5035. buf2[0] = 0;
  5036. if (cfgfile_rom (option, value, buf, buf2, MAX_DPATH / sizeof (TCHAR))) {
  5037. if (buf2[0]) {
  5038. brc = get_device_rom_new(p, ert->romtype, j, &idx);
  5039. _tcscpy(brc->roms[idx].romfile, buf2);
  5040. }
  5041. return true;
  5042. }
  5043. _stprintf(buf, _T("%s_rom"), name);
  5044. if (cfgfile_string (option, value, buf, buf2, sizeof buf2 / sizeof (TCHAR))) {
  5045. if (buf2[0]) {
  5046. decode_rom_ident (buf3, sizeof(buf3) / sizeof (TCHAR), buf2, ert->romtype);
  5047. if (buf3[0]) {
  5048. brc = get_device_rom_new(p, ert->romtype, j, &idx);
  5049. _tcscpy(brc->roms[idx].romident, buf3);
  5050. }
  5051. }
  5052. return true;
  5053. }
  5054. _stprintf(buf, _T("%s_rom_options"), name);
  5055. if (cfgfile_string (option, value, buf, buf2, sizeof buf2 / sizeof (TCHAR))) {
  5056. brc = get_device_rom(p, ert->romtype, j, &idx);
  5057. if (brc) {
  5058. TCHAR *p;
  5059. if (cfgfile_option_bool(buf2, _T("autoboot_disabled")) == 1) {
  5060. brc->roms[idx].autoboot_disabled = true;
  5061. }
  5062. if (cfgfile_option_bool(buf2, _T("dma24bit")) == 1) {
  5063. brc->roms[idx].dma24bit = true;
  5064. }
  5065. if (cfgfile_option_bool(buf2, _T("inserted")) == 1) {
  5066. brc->roms[idx].inserted= true;
  5067. }
  5068. p = cfgfile_option_get(buf2, _T("order"));
  5069. if (p) {
  5070. brc->device_order = _tstol(p);
  5071. }
  5072. xfree(p);
  5073. if (ert->settings) {
  5074. brc->roms[idx].device_settings = cfgfile_read_rom_settings(ert->settings, buf2, brc->roms[idx].configtext);
  5075. }
  5076. if (ert->id_jumper) {
  5077. p = cfgfile_option_get(buf2, _T("id"));
  5078. if (p) {
  5079. brc->roms[idx].device_id = _tstol(p);
  5080. xfree(p);
  5081. }
  5082. }
  5083. if (ert->subtypes) {
  5084. const struct expansionsubromtype *srt = ert->subtypes;
  5085. TCHAR tmp[MAX_DPATH];
  5086. p = tmp;
  5087. *p = 0;
  5088. while (srt->name) {
  5089. _tcscpy(p, srt->configname);
  5090. p += _tcslen(p) + 1;
  5091. p[0] = 0;
  5092. srt++;
  5093. }
  5094. int v = cfgfile_option_select(buf2, _T("subtype"), tmp);
  5095. if (v >= 0)
  5096. brc->roms[idx].subtype = v;
  5097. }
  5098. p = cfgfile_option_get(buf2, _T("mid"));
  5099. if (p) {
  5100. brc->roms[idx].manufacturer = _tstol(p);
  5101. xfree(p);
  5102. }
  5103. p = cfgfile_option_get(buf2, _T("pid"));
  5104. if (p) {
  5105. brc->roms[idx].product = _tstol(p);
  5106. xfree(p);
  5107. }
  5108. p = cfgfile_option_get(buf2, _T("data"));
  5109. if (p && _tcslen(p) >= 3 * 16 - 1) {
  5110. for (int i = 0; i < sizeof brc->roms[idx].autoconfig; i++) {
  5111. TCHAR *s2 = &p[i * 3];
  5112. if (i + 1 < sizeof brc->roms[idx].autoconfig && s2[2] != '.')
  5113. break;
  5114. TCHAR *endptr;
  5115. p[2] = 0;
  5116. brc->roms[idx].autoconfig[i] = (uae_u8)_tcstol(s2, &endptr, 16);
  5117. }
  5118. }
  5119. xfree(p);
  5120. }
  5121. return true;
  5122. }
  5123. }
  5124. _stprintf(buf, _T("%s_mem_size"), ert->name);
  5125. if (cfgfile_intval (option, value, buf, &val, 0x40000)) {
  5126. if (val) {
  5127. brc = get_device_rom_new(p, ert->romtype, 0, &idx);
  5128. brc->roms[idx].board_ram_size = val;
  5129. }
  5130. return true;
  5131. }
  5132. }
  5133. return false;
  5134. }
  5135. static void addbcromtype(struct uae_prefs *p, int romtype, bool add, const TCHAR *romfile, int devnum)
  5136. {
  5137. if (!add) {
  5138. clear_device_rom(p, romtype, devnum, true);
  5139. } else {
  5140. struct boardromconfig *brc = get_device_rom_new(p, romtype, devnum, NULL);
  5141. if (brc && !brc->roms[0].romfile[0]) {
  5142. _tcscpy(brc->roms[0].romfile, romfile ? romfile : _T(":ENABLED"));
  5143. }
  5144. }
  5145. }
  5146. static void addbcromtypenet(struct uae_prefs *p, int romtype, const TCHAR *netname, int devnum)
  5147. {
  5148. int is = is_device_rom(p, romtype, devnum);
  5149. if (netname == NULL || netname[0] == 0) {
  5150. if (is < 0)
  5151. clear_device_rom(p, romtype, devnum, true);
  5152. } else {
  5153. if (is < 0) {
  5154. struct boardromconfig *brc = get_device_rom_new(p, romtype, devnum, NULL);
  5155. if (brc) {
  5156. if (!brc->roms[0].romfile[0]) {
  5157. _tcscpy(brc->roms[0].romfile, _T(":ENABLED"));
  5158. }
  5159. ethernet_updateselection();
  5160. if (!brc->roms[0].device_settings)
  5161. brc->roms[0].device_settings = ethernet_getselection(netname);
  5162. }
  5163. }
  5164. }
  5165. }
  5166. static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCHAR *value)
  5167. {
  5168. int tmpval, dummyint, i;
  5169. uae_u32 utmpval;
  5170. bool dummybool;
  5171. TCHAR tmpbuf[CONFIG_BLEN];
  5172. if (cfgfile_yesno(option, value, _T("cpu_compatible"), &p->cpu_compatible)) {
  5173. return 1;
  5174. }
  5175. if (cfgfile_yesno (option, value, _T("cpu_cycle_exact"), &p->cpu_cycle_exact)) {
  5176. /* we don't want cycle-exact in 68020/40+JIT modes */
  5177. if (p->cpu_model >= 68020 && p->cachesize > 0)
  5178. p->cpu_cycle_exact = p->cpu_memory_cycle_exact = p->blitter_cycle_exact = 0;
  5179. p->cpu_memory_cycle_exact = p->cpu_cycle_exact;
  5180. // pre-4.4.0 didn't support cpu multiplier in prefetch mode without cycle-exact
  5181. // set pre-4.4.0 defaults first
  5182. if (!p->cpu_cycle_exact && p->cpu_compatible && !p->cpu_clock_multiplier) {
  5183. if (p->cpu_model < 68020) {
  5184. p->cpu_clock_multiplier = 2 * 256;
  5185. } else if (p->cpu_model == 68020) {
  5186. p->cpu_clock_multiplier = 4 * 256;
  5187. } else {
  5188. p->cpu_clock_multiplier = 8 * 256;
  5189. }
  5190. }
  5191. return 1;
  5192. }
  5193. if (cfgfile_yesno (option, value, _T("blitter_cycle_exact"), &p->blitter_cycle_exact)) {
  5194. if (p->cpu_model >= 68020 && p->cachesize > 0)
  5195. p->cpu_cycle_exact = p->cpu_memory_cycle_exact = p->blitter_cycle_exact = 0;
  5196. return 1;
  5197. }
  5198. if (cfgfile_yesno (option, value, _T("cpu_memory_cycle_exact"), &p->cpu_memory_cycle_exact)) {
  5199. if (!p->cpu_memory_cycle_exact)
  5200. p->blitter_cycle_exact = p->cpu_cycle_exact = false;
  5201. return 1;
  5202. }
  5203. if (cfgfile_strval (option, value, _T("cycle_exact"), &tmpval, cycleexact, 0)) {
  5204. if (tmpval > 0) {
  5205. p->blitter_cycle_exact = true;
  5206. p->cpu_cycle_exact = tmpval > 1;
  5207. p->cpu_memory_cycle_exact = true;
  5208. } else {
  5209. p->blitter_cycle_exact = false;
  5210. p->cpu_cycle_exact = false;
  5211. p->cpu_memory_cycle_exact = false;
  5212. }
  5213. if (p->cpu_model >= 68020 && p->cachesize > 0)
  5214. p->cpu_cycle_exact = p->cpu_memory_cycle_exact = p->blitter_cycle_exact = false;
  5215. // if old version and CE and fastest possible: set to approximate
  5216. if (p->cpu_cycle_exact && p->config_version < ((2 << 16) | (8 << 8) | (2 << 0)) && p->m68k_speed < 0)
  5217. p->m68k_speed = 0;
  5218. return 1;
  5219. }
  5220. if (cfgfile_string (option, value, _T("cpu_multiplier"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) {
  5221. p->cpu_clock_multiplier = (int)(_tstof (tmpbuf) * 256.0);
  5222. return 1;
  5223. }
  5224. if (cfgfile_string(option, value, _T("a2065"), p->a2065name, sizeof p->a2065name / sizeof(TCHAR))) {
  5225. if (p->a2065name[0])
  5226. addbcromtype(p, ROMTYPE_A2065, true, NULL, 0);
  5227. return 1;
  5228. }
  5229. if (cfgfile_string(option, value, _T("ne2000_pci"), p->ne2000pciname, sizeof p->ne2000pciname / sizeof(TCHAR)))
  5230. return 1;
  5231. if (cfgfile_string(option, value, _T("ne2000_pcmcia"), p->ne2000pcmcianame, sizeof p->ne2000pcmcianame / sizeof(TCHAR)))
  5232. return 1;
  5233. if (cfgfile_string(option, value, _T("jit_blacklist"), p->jitblacklist, sizeof p->jitblacklist / sizeof(TCHAR)))
  5234. return 1;
  5235. if (cfgfile_yesno(option, value, _T("immediate_blits"), &p->immediate_blits)
  5236. || cfgfile_yesno(option, value, _T("fpu_no_unimplemented"), &p->fpu_no_unimplemented)
  5237. || cfgfile_yesno(option, value, _T("cpu_no_unimplemented"), &p->int_no_unimplemented)
  5238. || cfgfile_yesno(option, value, _T("cd32cd"), &p->cs_cd32cd)
  5239. || cfgfile_yesno(option, value, _T("cd32c2p"), &p->cs_cd32c2p)
  5240. || cfgfile_yesno(option, value, _T("cd32nvram"), &p->cs_cd32nvram)
  5241. || cfgfile_yesno(option, value, _T("cdtvcd"), &p->cs_cdtvcd)
  5242. || cfgfile_yesno(option, value, _T("cdtv-cr"), &p->cs_cdtvcr)
  5243. || cfgfile_yesno(option, value, _T("cdtvram"), &p->cs_cdtvram)
  5244. || cfgfile_yesno(option, value, _T("a1000ram"), &p->cs_a1000ram)
  5245. || cfgfile_yesno(option, value, _T("cia_overlay"), &p->cs_ciaoverlay)
  5246. || cfgfile_yesno(option, value, _T("bogomem_fast"), &p->cs_slowmemisfast)
  5247. || cfgfile_yesno(option, value, _T("ksmirror_e0"), &p->cs_ksmirror_e0)
  5248. || cfgfile_yesno(option, value, _T("ksmirror_a8"), &p->cs_ksmirror_a8)
  5249. || cfgfile_yesno(option, value, _T("resetwarning"), &p->cs_resetwarning)
  5250. || cfgfile_yesno(option, value, _T("cia_todbug"), &p->cs_ciatodbug)
  5251. || cfgfile_yesno(option, value, _T("denise_noehb"), &p->cs_denisenoehb)
  5252. || cfgfile_yesno(option, value, _T("ics_agnus"), &p->cs_dipagnus)
  5253. || cfgfile_yesno(option, value, _T("z3_autoconfig"), &p->cs_z3autoconfig)
  5254. || cfgfile_yesno(option, value, _T("color_burst"), &p->cs_color_burst)
  5255. || cfgfile_yesno(option, value, _T("toshiba_gary"), &p->cs_toshibagary)
  5256. || cfgfile_yesno(option, value, _T("rom_is_slow"), &p->cs_romisslow)
  5257. || cfgfile_yesno(option, value, _T("1mchipjumper"), &p->cs_1mchipjumper)
  5258. || cfgfile_yesno(option, value, _T("agnus_bltbusybug"), &p->cs_agnusbltbusybug)
  5259. || cfgfile_yesno(option, value, _T("bkpt_halt"), &p->cs_bkpthang)
  5260. || cfgfile_yesno(option, value, _T("gfxcard_hardware_vblank"), &p->rtg_hardwareinterrupt)
  5261. || cfgfile_yesno(option, value, _T("gfxcard_hardware_sprite"), &p->rtg_hardwaresprite)
  5262. || cfgfile_yesno(option, value, _T("gfxcard_multithread"), &p->rtg_multithread)
  5263. || cfgfile_yesno(option, value, _T("synchronize_clock"), &p->tod_hack)
  5264. || cfgfile_yesno(option, value, _T("keyboard_connected"), &p->keyboard_connected)
  5265. || cfgfile_coords(option, value, _T("lightpen_offset"), &p->lightpen_offset[0], &p->lightpen_offset[1])
  5266. || cfgfile_yesno(option, value, _T("lightpen_crosshair"), &p->lightpen_crosshair)
  5267. || cfgfile_yesno (option, value, _T("kickshifter"), &p->kickshifter)
  5268. || cfgfile_yesno (option, value, _T("ks_write_enabled"), &p->rom_readwrite)
  5269. || cfgfile_yesno (option, value, _T("ntsc"), &p->ntscmode)
  5270. || cfgfile_yesno (option, value, _T("sana2"), &p->sana2)
  5271. || cfgfile_yesno(option, value, _T("genlock"), &p->genlock)
  5272. || cfgfile_yesno(option, value, _T("genlock_alpha"), &p->genlock_alpha)
  5273. || cfgfile_yesno(option, value, _T("genlock_aspect"), &p->genlock_aspect)
  5274. || cfgfile_yesno(option, value, _T("cpu_data_cache"), &p->cpu_data_cache)
  5275. || cfgfile_yesno(option, value, _T("cpu_threaded"), &p->cpu_thread)
  5276. || cfgfile_yesno(option, value, _T("cpu_24bit_addressing"), &p->address_space_24)
  5277. || cfgfile_yesno(option, value, _T("cpu_reset_pause"), &p->reset_delay)
  5278. || cfgfile_yesno(option, value, _T("cpu_halt_auto_reset"), &p->crash_auto_reset)
  5279. || cfgfile_yesno(option, value, _T("parallel_on_demand"), &p->parallel_demand)
  5280. || cfgfile_yesno (option, value, _T("parallel_postscript_emulation"), &p->parallel_postscript_emulation)
  5281. || cfgfile_yesno (option, value, _T("parallel_postscript_detection"), &p->parallel_postscript_detection)
  5282. || cfgfile_yesno (option, value, _T("serial_on_demand"), &p->serial_demand)
  5283. || cfgfile_yesno (option, value, _T("serial_hardware_ctsrts"), &p->serial_hwctsrts)
  5284. || cfgfile_yesno (option, value, _T("serial_direct"), &p->serial_direct)
  5285. || cfgfile_yesno (option, value, _T("fpu_strict"), &p->fpu_strict)
  5286. || cfgfile_yesno (option, value, _T("comp_nf"), &p->compnf)
  5287. || cfgfile_yesno (option, value, _T("comp_constjump"), &p->comp_constjump)
  5288. || cfgfile_yesno(option, value, _T("comp_catchfault"), &p->comp_catchfault)
  5289. #ifdef USE_JIT_FPU
  5290. || cfgfile_yesno (option, value, _T("compfpu"), &p->compfpu)
  5291. #endif
  5292. || cfgfile_yesno (option, value, _T("rtg_nocustom"), &p->picasso96_nocustom)
  5293. || cfgfile_yesno (option, value, _T("floppy_write_protect"), &p->floppy_read_only)
  5294. || cfgfile_yesno(option, value, _T("harddrive_write_protect"), &p->harddrive_read_only)
  5295. || cfgfile_yesno(option, value, _T("uae_hide_autoconfig"), &p->uae_hide_autoconfig)
  5296. || cfgfile_yesno(option, value, _T("board_custom_order"), &p->autoconfig_custom_sort)
  5297. || cfgfile_yesno (option, value, _T("uaeserial"), &p->uaeserial))
  5298. return 1;
  5299. if (cfgfile_intval(option, value, _T("cachesize"), &p->cachesize, 1)
  5300. || cfgfile_intval(option, value, _T("cd32nvram_size"), &p->cs_cd32nvram_size, 1024)
  5301. || cfgfile_intval(option, value, _T("chipset_hacks"), &p->cs_hacks, 1)
  5302. || cfgfile_intval(option, value, _T("serial_stopbits"), &p->serial_stopbits, 1)
  5303. || cfgfile_intval(option, value, _T("cpu060_revision"), &p->cpu060_revision, 1)
  5304. || cfgfile_intval(option, value, _T("fpu_revision"), &p->fpu_revision, 1)
  5305. || cfgfile_intval(option, value, _T("fatgary"), &p->cs_fatgaryrev, 1)
  5306. || cfgfile_intval(option, value, _T("ramsey"), &p->cs_ramseyrev, 1)
  5307. || cfgfile_doubleval(option, value, _T("chipset_refreshrate"), &p->chipset_refreshrate)
  5308. || cfgfile_intval(option, value, _T("cpuboardmem1_size"), &p->cpuboardmem1.size, 0x100000)
  5309. || cfgfile_intval(option, value, _T("cpuboardmem2_size"), &p->cpuboardmem2.size, 0x100000)
  5310. || cfgfile_intval(option, value, _T("debugmem_size"), &p->debugmem_size, 0x100000)
  5311. || cfgfile_intval(option, value, _T("mem25bit_size"), &p->mem25bit.size, 0x100000)
  5312. || cfgfile_intval(option, value, _T("a3000mem_size"), &p->mbresmem_low.size, 0x100000)
  5313. || cfgfile_intval(option, value, _T("mbresmem_size"), &p->mbresmem_high.size, 0x100000)
  5314. || cfgfile_intval(option, value, _T("megachipmem_size"), &p->z3chipmem.size, 0x100000)
  5315. || cfgfile_intval(option, value, _T("z3mem_start"), &p->z3autoconfig_start, 1)
  5316. || cfgfile_intval(option, value, _T("debugmem_start"), &p->debugmem_start, 1)
  5317. || cfgfile_intval(option, value, _T("bogomem_size"), &p->bogomem.size, 0x40000)
  5318. || cfgfile_intval(option, value, _T("rtg_modes"), &p->picasso96_modeflags, 1)
  5319. || cfgfile_intval(option, value, _T("floppy_speed"), &p->floppy_speed, 1)
  5320. || cfgfile_intval(option, value, _T("cd_speed"), &p->cd_speed, 1)
  5321. || cfgfile_intval(option, value, _T("floppy_write_length"), &p->floppy_write_length, 1)
  5322. || cfgfile_intval(option, value, _T("floppy_random_bits_min"), &p->floppy_random_bits_min, 1)
  5323. || cfgfile_intval(option, value, _T("floppy_random_bits_max"), &p->floppy_random_bits_max, 1)
  5324. || cfgfile_intval(option, value, _T("nr_floppies"), &p->nr_floppies, 1)
  5325. || cfgfile_intval(option, value, _T("floppy0type"), &p->floppyslots[0].dfxtype, 1)
  5326. || cfgfile_intval(option, value, _T("floppy1type"), &p->floppyslots[1].dfxtype, 1)
  5327. || cfgfile_intval(option, value, _T("floppy2type"), &p->floppyslots[2].dfxtype, 1)
  5328. || cfgfile_intval(option, value, _T("floppy3type"), &p->floppyslots[3].dfxtype, 1)
  5329. || cfgfile_intval(option, value, _T("floppy0subtype"), &p->floppyslots[0].dfxsubtype, 1)
  5330. || cfgfile_intval(option, value, _T("floppy1subtype"), &p->floppyslots[1].dfxsubtype, 1)
  5331. || cfgfile_intval(option, value, _T("floppy2subtype"), &p->floppyslots[2].dfxsubtype, 1)
  5332. || cfgfile_intval(option, value, _T("floppy3subtype"), &p->floppyslots[3].dfxsubtype, 1)
  5333. || cfgfile_intval(option, value, _T("maprom"), &p->maprom, 1)
  5334. || cfgfile_intval(option, value, _T("parallel_autoflush"), &p->parallel_autoflush_time, 1)
  5335. || cfgfile_intval(option, value, _T("uae_hide"), &p->uae_hide, 1)
  5336. || cfgfile_intval(option, value, _T("cpu_frequency"), &p->cpu_frequency, 1)
  5337. || cfgfile_intval(option, value, _T("kickstart_ext_rom_file2addr"), &p->romextfile2addr, 1)
  5338. || cfgfile_intval(option, value, _T("monitoremu_monitor"), &p->monitoremu_mon, 1)
  5339. || cfgfile_intval(option, value, _T("genlock_scale"), &p->genlock_scale, 1)
  5340. || cfgfile_intval(option, value, _T("genlock_mix"), &p->genlock_mix, 1)
  5341. || cfgfile_intval(option, value, _T("keyboard_handshake"), &p->cs_kbhandshake, 1)
  5342. || cfgfile_intval(option, value, _T("chipset_rtc_adjust"), &p->cs_rtc_adjust, 1))
  5343. return 1;
  5344. if (cfgfile_strval (option, value, _T("comp_trustbyte"), &p->comptrustbyte, compmode, 0)
  5345. || cfgfile_strval (option, value, _T("rtc"), &p->cs_rtc, rtctype, 0)
  5346. || cfgfile_strval (option, value, _T("ciaatod"), &p->cs_ciaatod, ciaatodmode, 0)
  5347. || cfgfile_strval (option, value, _T("scsi"), &p->scsi, scsimode, 0)
  5348. || cfgfile_strval (option, value, _T("comp_trustword"), &p->comptrustword, compmode, 0)
  5349. || cfgfile_strval (option, value, _T("comp_trustlong"), &p->comptrustlong, compmode, 0)
  5350. || cfgfile_strval (option, value, _T("comp_trustnaddr"), &p->comptrustnaddr, compmode, 0)
  5351. || cfgfile_strval (option, value, _T("collision_level"), &p->collision_level, collmode, 0)
  5352. || cfgfile_strval (option, value, _T("parallel_matrix_emulation"), &p->parallel_matrix_emulation, epsonprinter, 0)
  5353. || cfgfile_strval(option, value, _T("monitoremu"), &p->monitoremu, specialmonitorconfignames, 0)
  5354. || cfgfile_strval(option, value, _T("genlockmode"), &p->genlock_image, genlockmodes, 0)
  5355. || cfgfile_strval (option, value, _T("waiting_blits"), &p->waiting_blits, waitblits, 0)
  5356. || cfgfile_strval (option, value, _T("floppy_auto_extended_adf"), &p->floppy_auto_ext2, autoext2, 0)
  5357. || cfgfile_strval (option, value, _T("z3mapping"), &p->z3_mapping_mode, z3mapping, 0)
  5358. || cfgfile_strval (option, value, _T("scsidev_mode"), &p->uaescsidevmode, uaescsidevmodes, 0)
  5359. || cfgfile_strval(option, value, _T("boot_rom_uae"), &p->boot_rom, uaebootrom, 0)
  5360. || cfgfile_strval (option, value, _T("serial_translate"), &p->serial_crlf, serialcrlf, 0)
  5361. || cfgfile_strval(option, value, _T("unmapped_address_space"), &p->cs_unmapped_space, unmapped, 0)
  5362. || cfgfile_strval(option, value, _T("ciaa_type"), &p->cs_ciatype[0], ciatype, 0)
  5363. || cfgfile_strval(option, value, _T("ciab_type"), &p->cs_ciatype[1], ciatype, 0)
  5364. || cfgfile_strboolval (option, value, _T("comp_flushmode"), &p->comp_hardflush, flushmode, 0))
  5365. return 1;
  5366. if (cfgfile_strval(option, value, _T("uaeboard"), &p->uaeboard, uaeboard_off, 1)) {
  5367. p->uaeboard_nodiag = true;
  5368. return 1;
  5369. }
  5370. if (cfgfile_strval(option, value, _T("uaeboard"), &p->uaeboard, uaeboard, 0)) {
  5371. p->uaeboard_nodiag = false;
  5372. return 1;
  5373. }
  5374. if (cfgfile_path (option, value, _T("kickstart_rom_file"), p->romfile, sizeof p->romfile / sizeof (TCHAR), &p->path_rom)
  5375. || cfgfile_path (option, value, _T("kickstart_ext_rom_file"), p->romextfile, sizeof p->romextfile / sizeof (TCHAR), &p->path_rom)
  5376. || cfgfile_path (option, value, _T("kickstart_ext_rom_file2"), p->romextfile2, sizeof p->romextfile2 / sizeof (TCHAR), &p->path_rom)
  5377. || cfgfile_rom(option, value, _T("kickstart_rom_file_id"), p->romfile, sizeof p->romfile / sizeof(TCHAR))
  5378. || cfgfile_rom (option, value, _T("kickstart_ext_rom_file_id"), p->romextfile, sizeof p->romextfile / sizeof (TCHAR))
  5379. || cfgfile_string(option, value, _T("flash_file"), p->flashfile, sizeof p->flashfile / sizeof (TCHAR))
  5380. || cfgfile_path (option, value, _T("cart_file"), p->cartfile, sizeof p->cartfile / sizeof (TCHAR), &p->path_rom)
  5381. || cfgfile_string(option, value, _T("rtc_file"), p->rtcfile, sizeof p->rtcfile / sizeof (TCHAR))
  5382. || cfgfile_path(option, value, _T("picassoiv_rom_file"), p->picassoivromfile, sizeof p->picassoivromfile / sizeof(TCHAR), &p->path_rom)
  5383. || cfgfile_string(option, value, _T("genlock_image"), p->genlock_image_file, sizeof p->genlock_image_file / sizeof(TCHAR))
  5384. || cfgfile_string(option, value, _T("genlock_video"), p->genlock_video_file, sizeof p->genlock_video_file / sizeof(TCHAR))
  5385. || cfgfile_string(option, value, _T ("pci_devices"), p->pci_devices, sizeof p->pci_devices / sizeof(TCHAR))
  5386. || cfgfile_string (option, value, _T("ghostscript_parameters"), p->ghostscript_parameters, sizeof p->ghostscript_parameters / sizeof (TCHAR)))
  5387. return 1;
  5388. if (cfgfile_yesno(option, value, _T("fpu_softfloat"), &dummybool)) {
  5389. if (dummybool)
  5390. p->fpu_mode = 1;
  5391. return 1;
  5392. }
  5393. #ifdef MSVC_LONG_DOUBLE
  5394. if (cfgfile_yesno(option, value, _T("fpu_msvc_long_double"), &dummybool)) {
  5395. if (dummybool)
  5396. p->fpu_mode = -1;
  5397. else if (p->fpu_mode < 0)
  5398. p->fpu_mode = 0;
  5399. return 1;
  5400. }
  5401. #endif
  5402. if (cfgfile_string(option, value, _T("uaeboard_options"), tmpbuf, sizeof tmpbuf / sizeof(TCHAR))) {
  5403. TCHAR *s = cfgfile_option_get(value, _T("order"));
  5404. if (s)
  5405. p->uaeboard_order = _tstol(s);
  5406. xfree(s);
  5407. return 1;
  5408. }
  5409. if (cfgfile_readromboard(option, value, &p->romboards[0])) {
  5410. return 1;
  5411. }
  5412. if (cfgfile_readramboard(option, value, _T("chipmem"), &p->chipmem)) {
  5413. return 1;
  5414. }
  5415. if (cfgfile_readramboard(option, value, _T("bogomem"), &p->bogomem)) {
  5416. return 1;
  5417. }
  5418. if (cfgfile_readramboard(option, value, _T("fastmem"), &p->fastmem[0])) {
  5419. return 1;
  5420. }
  5421. if (cfgfile_readramboard(option, value, _T("mem25bit"), &p->mem25bit)) {
  5422. return 1;
  5423. }
  5424. if (cfgfile_readramboard(option, value, _T("a3000mem"), &p->mbresmem_low)) {
  5425. return 1;
  5426. }
  5427. if (cfgfile_readramboard(option, value, _T("mbresmem"), &p->mbresmem_high)) {
  5428. return 1;
  5429. }
  5430. if (cfgfile_readramboard(option, value, _T("z3mem"), &p->z3fastmem[0])) {
  5431. return 1;
  5432. }
  5433. if (cfgfile_readramboard(option, value, _T("megachipmem"), &p->z3chipmem)) {
  5434. return 1;
  5435. }
  5436. if (cfgfile_intval(option, value, _T("cdtvramcard"), &utmpval, 1)) {
  5437. if (utmpval)
  5438. addbcromtype(p, ROMTYPE_CDTVSRAM, true, NULL, 0);
  5439. return 1;
  5440. }
  5441. if (cfgfile_yesno(option, value, _T("scsi_cdtv"), &tmpval)) {
  5442. if (tmpval)
  5443. addbcromtype(p, ROMTYPE_CDTVSCSI, true, NULL, 0);
  5444. return 1;
  5445. }
  5446. if (cfgfile_yesno(option, value, _T("pcmcia"), &p->cs_pcmcia)) {
  5447. if (p->cs_pcmcia)
  5448. addbcromtype(p, ROMTYPE_MB_PCMCIA, true, NULL, 0);
  5449. return 1;
  5450. }
  5451. if (cfgfile_strval(option, value, _T("ide"), &p->cs_ide, idemode, 0)) {
  5452. if (p->cs_ide)
  5453. addbcromtype(p, ROMTYPE_MB_IDE, true, NULL, 0);
  5454. return 1;
  5455. }
  5456. if (cfgfile_yesno(option, value, _T("scsi_a3000"), &dummybool)) {
  5457. if (dummybool) {
  5458. addbcromtype(p, ROMTYPE_SCSI_A3000, true, NULL, 0);
  5459. p->cs_mbdmac = 1;
  5460. }
  5461. return 1;
  5462. }
  5463. if (cfgfile_yesno(option, value, _T("scsi_a4000t"), &dummybool)) {
  5464. if (dummybool) {
  5465. addbcromtype(p, ROMTYPE_SCSI_A4000T, true, NULL, 0);
  5466. p->cs_mbdmac = 2;
  5467. }
  5468. return 1;
  5469. }
  5470. if (cfgfile_yesno(option, value, _T("cd32fmv"), &p->cs_cd32fmv)) {
  5471. if (p->cs_cd32fmv) {
  5472. addbcromtype(p, ROMTYPE_CD32CART, true, p->cartfile, 0);
  5473. }
  5474. return 1;
  5475. }
  5476. if (cfgfile_intval(option, value, _T("catweasel"), &p->catweasel, 1)) {
  5477. if (p->catweasel) {
  5478. addbcromtype(p, ROMTYPE_CATWEASEL, true, NULL, 0);
  5479. }
  5480. return 1;
  5481. }
  5482. if (cfgfile_yesno(option, value, _T("toccata"), &dummybool))
  5483. {
  5484. if (dummybool) {
  5485. addbcromtype(p, ROMTYPE_TOCCATA, true, NULL, 0);
  5486. }
  5487. return 1;
  5488. }
  5489. if (cfgfile_yesno(option, value, _T("es1370_pci"), &dummybool))
  5490. {
  5491. if (dummybool) {
  5492. addbcromtype(p, ROMTYPE_ES1370, true, NULL, 0);
  5493. }
  5494. return 1;
  5495. }
  5496. if (cfgfile_yesno(option, value, _T("fm801_pci"), &dummybool))
  5497. {
  5498. if (dummybool) {
  5499. addbcromtype(p, ROMTYPE_FM801, true, NULL, 0);
  5500. }
  5501. return 1;
  5502. }
  5503. if (cfgfile_yesno(option, value, _T("toccata_mixer"), &dummybool))
  5504. {
  5505. if (dummybool) {
  5506. addbcromtype(p, ROMTYPE_TOCCATA, true, NULL, 0);
  5507. }
  5508. return 1;
  5509. }
  5510. for (int i = 0; i < MAX_RTG_BOARDS; i++) {
  5511. struct rtgboardconfig *rbc = &p->rtgboards[i];
  5512. TCHAR tmp[100];
  5513. if (i > 0)
  5514. _stprintf(tmp, _T("gfxcard%d_size"), i + 1);
  5515. else
  5516. _tcscpy(tmp, _T("gfxcard_size"));
  5517. if (cfgfile_intval(option, value, tmp, &rbc->rtgmem_size, 0x100000))
  5518. return 1;
  5519. if (i > 0)
  5520. _stprintf(tmp, _T("gfxcard%d_options"), i + 1);
  5521. else
  5522. _tcscpy(tmp, _T("gfxcard_options"));
  5523. if (!_tcsicmp(option, tmp)) {
  5524. TCHAR *s = cfgfile_option_get(value, _T("order"));
  5525. if (s) {
  5526. rbc->device_order = _tstol(s);
  5527. xfree(s);
  5528. }
  5529. s = cfgfile_option_get(value, _T("monitor"));
  5530. if (s) {
  5531. rbc->monitor_id = _tstol(s);
  5532. xfree(s);
  5533. }
  5534. return 1;
  5535. }
  5536. if (i > 0)
  5537. _stprintf(tmp, _T("gfxcard%d_type"), i + 1);
  5538. else
  5539. _tcscpy(tmp, _T("gfxcard_type"));
  5540. if (cfgfile_string(option, value, tmp, tmpbuf, sizeof tmpbuf / sizeof(TCHAR))) {
  5541. rbc->rtgmem_type = 0;
  5542. rbc->rtg_index = i;
  5543. int j = 0;
  5544. for (;;) {
  5545. const TCHAR *t = gfxboard_get_configname(j);
  5546. if (!t) {
  5547. break;
  5548. }
  5549. if (!_tcsicmp(t, tmpbuf)) {
  5550. rbc->rtgmem_type = j;
  5551. break;
  5552. }
  5553. j++;
  5554. }
  5555. return 1;
  5556. }
  5557. }
  5558. if (cfgfile_string(option, value, _T("cpuboard_type"), tmpbuf, sizeof tmpbuf / sizeof(TCHAR))) {
  5559. p->cpuboard_type = 0;
  5560. p->cpuboard_subtype = 0;
  5561. for (i = 0; cpuboards[i].name && !p->cpuboard_type; i++) {
  5562. const struct cpuboardtype *cbt = &cpuboards[i];
  5563. if (cbt->subtypes) {
  5564. for (int j = 0; cbt->subtypes[j].name; j++) {
  5565. if (!_tcsicmp(cbt->subtypes[j].configname, tmpbuf)) {
  5566. p->cpuboard_type = i;
  5567. p->cpuboard_subtype = j;
  5568. }
  5569. }
  5570. }
  5571. }
  5572. return 1;
  5573. }
  5574. if (cfgfile_string(option, value, _T("cpuboard_settings"), tmpbuf, sizeof tmpbuf / sizeof(TCHAR))) {
  5575. p->cpuboard_settings = 0;
  5576. const struct cpuboardsubtype *cbst = &cpuboards[p->cpuboard_type].subtypes[p->cpuboard_subtype];
  5577. if (cbst->settings) {
  5578. p->cpuboard_settings = cfgfile_read_rom_settings(cbst->settings, tmpbuf, NULL);
  5579. }
  5580. return 1;
  5581. }
  5582. if (cfgfile_strval (option, value, _T("chipset_compatible"), &p->cs_compatible, cscompa, 0)) {
  5583. built_in_chipset_prefs (p);
  5584. return 1;
  5585. }
  5586. if (cfgfile_strval (option, value, _T("cart_internal"), &p->cart_internal, cartsmode, 0)) {
  5587. if (p->cart_internal) {
  5588. struct romdata *rd = getromdatabyid (63);
  5589. if (rd)
  5590. _stprintf (p->cartfile, _T(":%s"), rd->configname);
  5591. }
  5592. return 1;
  5593. }
  5594. if (cfgfile_string (option, value, _T("kickstart_rom"), p->romident, sizeof p->romident / sizeof (TCHAR))) {
  5595. decode_rom_ident (p->romfile, sizeof p->romfile / sizeof (TCHAR), p->romident, ROMTYPE_ALL_KICK);
  5596. return 1;
  5597. }
  5598. if (cfgfile_string (option, value, _T("kickstart_ext_rom"), p->romextident, sizeof p->romextident / sizeof (TCHAR))) {
  5599. decode_rom_ident (p->romextfile, sizeof p->romextfile / sizeof (TCHAR), p->romextident, ROMTYPE_ALL_EXT);
  5600. return 1;
  5601. }
  5602. if (cfgfile_string (option, value, _T("cart"), p->cartident, sizeof p->cartident / sizeof (TCHAR))) {
  5603. decode_rom_ident (p->cartfile, sizeof p->cartfile / sizeof (TCHAR), p->cartident, ROMTYPE_ALL_CART);
  5604. return 1;
  5605. }
  5606. if (cfgfile_read_board_rom(p, option, value, &p->path_rom))
  5607. return 1;
  5608. for (i = 0; i < 4; i++) {
  5609. _stprintf (tmpbuf, _T("floppy%d"), i);
  5610. if (cfgfile_string(option, value, tmpbuf, p->floppyslots[i].df, sizeof p->floppyslots[i].df / sizeof(TCHAR))) {
  5611. if (!_tcscmp(p->floppyslots[i].df, _T(".")))
  5612. p->floppyslots[i].df[0] = 0;
  5613. return 1;
  5614. }
  5615. _stprintf(tmpbuf, _T("floppy%dsubtypeid"), i);
  5616. if (cfgfile_string_escape(option, value, tmpbuf, p->floppyslots[i].dfxsubtypeid, sizeof p->floppyslots[i].dfxsubtypeid / sizeof(TCHAR))) {
  5617. return 1;
  5618. }
  5619. }
  5620. if (cfgfile_intval (option, value, _T("chipmem_size"), &dummyint, 1)) {
  5621. if (dummyint < 0)
  5622. p->chipmem.size = 0x20000; /* 128k, prototype support */
  5623. else if (dummyint == 0)
  5624. p->chipmem.size = 0x40000; /* 256k */
  5625. else
  5626. p->chipmem.size = dummyint * 0x80000;
  5627. return 1;
  5628. }
  5629. if (cfgfile_string (option, value, _T("addmem1"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) {
  5630. parse_addmem (p, tmpbuf, 0);
  5631. return 1;
  5632. }
  5633. if (cfgfile_string (option, value, _T("addmem2"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) {
  5634. parse_addmem (p, tmpbuf, 1);
  5635. return 1;
  5636. }
  5637. if (cfgfile_strval (option, value, _T("chipset"), &tmpval, csmode, 0)) {
  5638. set_chipset_mask (p, tmpval);
  5639. return 1;
  5640. }
  5641. if (cfgfile_yesno(option, value, _T("chipset_subpixel"), &p->chipset_hr)) {
  5642. return 1;
  5643. }
  5644. if (cfgfile_string (option, value, _T("mmu_model"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) {
  5645. TCHAR *s =_tcsstr(tmpbuf, _T("ec"));
  5646. if (s) {
  5647. p->mmu_ec = true;
  5648. p->mmu_model = 68000 + _tstol(s + 2);
  5649. } else {
  5650. p->mmu_ec = false;
  5651. p->mmu_model = _tstol(tmpbuf);
  5652. }
  5653. return 1;
  5654. }
  5655. if (cfgfile_string (option, value, _T("fpu_model"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) {
  5656. p->fpu_model = _tstol (tmpbuf);
  5657. return 1;
  5658. }
  5659. if (cfgfile_string (option, value, _T("cpu_model"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) {
  5660. p->cpu_model = _tstol (tmpbuf);
  5661. p->fpu_model = 0;
  5662. return 1;
  5663. }
  5664. if (cfgfile_strval(option, value, _T("ppc_implementation"), &p->ppc_implementation, ppc_implementations, 0))
  5665. return 1;
  5666. if (cfgfile_string(option, value, _T("ppc_model"), tmpbuf, sizeof tmpbuf / sizeof(TCHAR))) {
  5667. p->ppc_mode = 0;
  5668. p->ppc_model[0] = 0;
  5669. if (!_tcsicmp(tmpbuf, _T("automatic"))) {
  5670. p->ppc_mode = 1;
  5671. } else if (!_tcsicmp(tmpbuf, _T("manual"))) {
  5672. p->ppc_mode = 2;
  5673. } else {
  5674. if (tmpbuf[0] && _tcslen(tmpbuf) < sizeof(p->ppc_model) / sizeof(TCHAR)) {
  5675. _tcscpy(p->ppc_model, tmpbuf);
  5676. p->ppc_mode = 2;
  5677. }
  5678. }
  5679. return 1;
  5680. }
  5681. if (cfgfile_strval(option, value, _T("ppc_cpu_idle"), &p->ppc_cpu_idle, ppc_cpu_idle, 0))
  5682. return 1;
  5683. /* old-style CPU configuration */
  5684. if (cfgfile_string (option, value, _T("cpu_type"), tmpbuf, sizeof tmpbuf / sizeof (TCHAR))) {
  5685. // 68000/010 32-bit addressing was not available until 2.8.2
  5686. bool force24bit = p->config_version <= ((2 << 16) | (8 << 8) | (1 << 0));
  5687. p->fpu_model = 0;
  5688. p->address_space_24 = 0;
  5689. p->cpu_model = 680000;
  5690. if (!_tcscmp (tmpbuf, _T("68000"))) {
  5691. p->cpu_model = 68000;
  5692. if (force24bit)
  5693. p->address_space_24 = 1;
  5694. } else if (!_tcscmp (tmpbuf, _T("68010"))) {
  5695. p->cpu_model = 68010;
  5696. if (force24bit)
  5697. p->address_space_24 = 1;
  5698. } else if (!_tcscmp (tmpbuf, _T("68ec020"))) {
  5699. p->cpu_model = 68020;
  5700. } else if (!_tcscmp (tmpbuf, _T("68020"))) {
  5701. p->cpu_model = 68020;
  5702. } else if (!_tcscmp (tmpbuf, _T("68ec020/68881"))) {
  5703. p->cpu_model = 68020;
  5704. p->fpu_model = 68881;
  5705. p->address_space_24 = 1;
  5706. } else if (!_tcscmp (tmpbuf, _T("68020/68881"))) {
  5707. p->cpu_model = 68020;
  5708. p->fpu_model = 68881;
  5709. } else if (!_tcscmp (tmpbuf, _T("68040"))) {
  5710. p->cpu_model = 68040;
  5711. p->fpu_model = 68040;
  5712. } else if (!_tcscmp (tmpbuf, _T("68060"))) {
  5713. p->cpu_model = 68060;
  5714. p->fpu_model = 68060;
  5715. }
  5716. return 1;
  5717. }
  5718. /* Broken earlier versions used to write this out as a string. */
  5719. if (cfgfile_strval (option, value, _T("finegraincpu_speed"), &p->m68k_speed, speedmode, 1)) {
  5720. p->m68k_speed--;
  5721. return 1;
  5722. }
  5723. if (cfgfile_strval (option, value, _T("cpu_speed"), &p->m68k_speed, speedmode, 1)) {
  5724. p->m68k_speed--;
  5725. return 1;
  5726. }
  5727. if (cfgfile_intval (option, value, _T("cpu_speed"), &p->m68k_speed, 1)) {
  5728. p->m68k_speed *= CYCLE_UNIT;
  5729. return 1;
  5730. }
  5731. if (cfgfile_doubleval(option, value, _T("cpu_throttle"), &p->m68k_speed_throttle)) {
  5732. return 1;
  5733. }
  5734. if (cfgfile_doubleval(option, value, _T("cpu_x86_throttle"), &p->x86_speed_throttle)) {
  5735. return 1;
  5736. }
  5737. if (cfgfile_intval (option, value, _T("finegrain_cpu_speed"), &p->m68k_speed, 1)) {
  5738. if (OFFICIAL_CYCLE_UNIT > CYCLE_UNIT) {
  5739. int factor = OFFICIAL_CYCLE_UNIT / CYCLE_UNIT;
  5740. p->m68k_speed = (p->m68k_speed + factor - 1) / factor;
  5741. }
  5742. if (strcasecmp (value, _T("max")) == 0)
  5743. p->m68k_speed = -1;
  5744. return 1;
  5745. }
  5746. if (cfgfile_doubleval(option, value, _T("blitter_throttle"), &p->blitter_speed_throttle)) {
  5747. return 1;
  5748. }
  5749. if (cfgfile_intval (option, value, _T("dongle"), &p->dongle, 1)) {
  5750. if (p->dongle == 0)
  5751. cfgfile_strval (option, value, _T("dongle"), &p->dongle, dongles, 0);
  5752. return 1;
  5753. }
  5754. if (strcasecmp (option, _T("quickstart")) == 0) {
  5755. int model = 0;
  5756. TCHAR *tmpp = _tcschr (value, ',');
  5757. if (tmpp) {
  5758. *tmpp++ = 0;
  5759. TCHAR *tmpp2 = _tcschr (value, ',');
  5760. if (tmpp2)
  5761. *tmpp2 = 0;
  5762. cfgfile_strval (option, value, option, &model, qsmodes, 0);
  5763. if (model >= 0) {
  5764. int config = _tstol (tmpp);
  5765. built_in_prefs (p, model, config, 0, 0);
  5766. }
  5767. }
  5768. return 1;
  5769. }
  5770. if (cfgfile_parse_filesys (p, option, value))
  5771. return 1;
  5772. return 0;
  5773. }
  5774. static void romtype_restricted(struct uae_prefs *p, const int *list)
  5775. {
  5776. for (int i = 0; list[i]; i++) {
  5777. int romtype = list[i];
  5778. if (is_board_enabled(p, romtype, 0)) {
  5779. i++;
  5780. while (list[i]) {
  5781. romtype = list[i];
  5782. if (is_board_enabled(p, romtype, 0)) {
  5783. write_log(_T("ROMTYPE %08x removed\n"), romtype);
  5784. addbcromtype(p, romtype, false, NULL, 0);
  5785. }
  5786. i++;
  5787. }
  5788. return;
  5789. }
  5790. }
  5791. }
  5792. void cfgfile_compatibility_rtg(struct uae_prefs *p)
  5793. {
  5794. int uaegfx = -1;
  5795. // only one uaegfx
  5796. for (int i = 0; i < MAX_RTG_BOARDS; i++) {
  5797. struct rtgboardconfig *rbc = &p->rtgboards[i];
  5798. if (rbc->rtgmem_size && rbc->rtgmem_type < GFXBOARD_HARDWARE) {
  5799. if (uaegfx >= 0) {
  5800. rbc->rtgmem_size = 0;
  5801. rbc->rtgmem_type = 0;
  5802. } else {
  5803. uaegfx = i;
  5804. }
  5805. }
  5806. }
  5807. // uaegfx must be first
  5808. if (uaegfx > 0) {
  5809. struct rtgboardconfig *rbc = &p->rtgboards[uaegfx];
  5810. struct rtgboardconfig *rbc2 = &p->rtgboards[0];
  5811. int size = rbc->rtgmem_size;
  5812. int type = rbc->rtgmem_type;
  5813. rbc->rtgmem_size = rbc2->rtgmem_size;
  5814. rbc->rtgmem_type = rbc2->rtgmem_type;
  5815. rbc2->rtgmem_size = size;
  5816. rbc2->rtgmem_type = type;
  5817. }
  5818. // allow only one a2410 and vga
  5819. int a2410 = -1;
  5820. int vga = -1;
  5821. for (int i = 0; i < MAX_RTG_BOARDS; i++) {
  5822. struct rtgboardconfig *rbc = &p->rtgboards[i];
  5823. if (rbc->rtgmem_type == GFXBOARD_ID_A2410) {
  5824. if (a2410 >= 0) {
  5825. rbc->rtgmem_size = 0;
  5826. rbc->rtgmem_type = 0;
  5827. } else {
  5828. a2410 = i;
  5829. }
  5830. }
  5831. if (rbc->rtgmem_type == GFXBOARD_ID_VGA) {
  5832. if (vga >= 0) {
  5833. rbc->rtgmem_size = 0;
  5834. rbc->rtgmem_type = 0;
  5835. } else {
  5836. vga = i;
  5837. }
  5838. }
  5839. }
  5840. // empty slots last
  5841. bool reorder = true;
  5842. while (reorder) {
  5843. reorder = false;
  5844. for (int i = 0; i < MAX_RTG_BOARDS; i++) {
  5845. struct rtgboardconfig *rbc = &p->rtgboards[i];
  5846. if (i > 0 && rbc->rtgmem_size && p->rtgboards[i - 1].rtgmem_size == 0) {
  5847. struct rtgboardconfig *rbc2 = &p->rtgboards[i - 1];
  5848. rbc2->rtgmem_size = rbc->rtgmem_size;
  5849. rbc2->rtgmem_type = rbc->rtgmem_type;
  5850. rbc2->device_order = rbc->device_order;
  5851. rbc->rtgmem_size = 0;
  5852. rbc->rtgmem_type = 0;
  5853. rbc->device_order = 0;
  5854. reorder = true;
  5855. break;
  5856. }
  5857. }
  5858. }
  5859. int rtgs[MAX_RTG_BOARDS] = { 0 };
  5860. for (int i = 0; i < MAX_RTG_BOARDS; i++) {
  5861. if (p->rtgboards[i].rtgmem_size && !rtgs[i]) {
  5862. uae_u32 romtype = gfxboard_get_romtype(&p->rtgboards[i]);
  5863. if (romtype) {
  5864. int devnum = 0;
  5865. for (int j = i; j < MAX_RTG_BOARDS; j++) {
  5866. rtgs[j] = 1;
  5867. if (gfxboard_get_romtype(&p->rtgboards[j]) == romtype) {
  5868. const TCHAR *romname = NULL;
  5869. if (romtype == ROMTYPE_PICASSOIV) {
  5870. romname = p->picassoivromfile;
  5871. } else if (romtype == ROMTYPE_x86_VGA) {
  5872. romname = _T("");
  5873. }
  5874. addbcromtype(p, romtype, true, romname, devnum);
  5875. devnum++;
  5876. }
  5877. }
  5878. while (devnum < MAX_DUPLICATE_EXPANSION_BOARDS) {
  5879. addbcromtype(p, romtype, false, NULL, devnum);
  5880. devnum++;
  5881. }
  5882. }
  5883. }
  5884. }
  5885. for (int i = 0; i < MAX_RTG_BOARDS; i++) {
  5886. if (!rtgs[i]) {
  5887. uae_u32 romtype = gfxboard_get_romtype(&p->rtgboards[i]);
  5888. if (romtype) {
  5889. for (int devnum = 0; devnum < MAX_DUPLICATE_EXPANSION_BOARDS; devnum++) {
  5890. addbcromtype(p, romtype, false, NULL, devnum);
  5891. }
  5892. }
  5893. }
  5894. }
  5895. }
  5896. void cfgfile_compatibility_romtype(struct uae_prefs *p)
  5897. {
  5898. addbcromtype(p, ROMTYPE_MB_PCMCIA, p->cs_pcmcia, NULL, 0);
  5899. addbcromtype(p, ROMTYPE_MB_IDE, p->cs_ide != 0, NULL, 0);
  5900. if (p->cs_mbdmac == 1) {
  5901. addbcromtype(p, ROMTYPE_SCSI_A4000T, false, NULL, 0);
  5902. addbcromtype(p, ROMTYPE_SCSI_A3000, true, NULL, 0);
  5903. } else if (p->cs_mbdmac == 2) {
  5904. addbcromtype(p, ROMTYPE_SCSI_A3000, false, NULL, 0);
  5905. addbcromtype(p, ROMTYPE_SCSI_A4000T, true, NULL, 0);
  5906. } else {
  5907. addbcromtype(p, ROMTYPE_SCSI_A3000, false, NULL, 0);
  5908. addbcromtype(p, ROMTYPE_SCSI_A4000T, false, NULL, 0);
  5909. }
  5910. addbcromtype(p, ROMTYPE_CDTVDMAC, p->cs_cdtvcd && !p->cs_cdtvcr, NULL, 0);
  5911. addbcromtype(p, ROMTYPE_CDTVCR, p->cs_cdtvcr, NULL, 0);
  5912. addbcromtype(p, ROMTYPE_CD32CART, p->cs_cd32fmv, p->cartfile,0);
  5913. if (p->config_version < ((3 << 16) | (4 << 8) | (0 << 0))) {
  5914. // 3.3.0 or older
  5915. addbcromtypenet(p, ROMTYPE_A2065, p->a2065name, 0);
  5916. addbcromtypenet(p, ROMTYPE_NE2KPCMCIA, p->ne2000pcmcianame, 0);
  5917. addbcromtypenet(p, ROMTYPE_NE2KPCI, p->ne2000pciname, 0);
  5918. }
  5919. static const int restricted_net[] = {
  5920. ROMTYPE_A2065, ROMTYPE_NE2KPCMCIA, ROMTYPE_NE2KPCI, ROMTYPE_NE2KISA,
  5921. ROMTYPE_ARIADNE2, ROMTYPE_XSURF, ROMTYPE_XSURF100Z2, ROMTYPE_XSURF100Z3,
  5922. ROMTYPE_HYDRA, ROMTYPE_LANROVER,
  5923. 0 };
  5924. static const int restricted_x86[] = { ROMTYPE_A1060, ROMTYPE_A2088, ROMTYPE_A2088T, ROMTYPE_A2286, ROMTYPE_A2386, 0 };
  5925. static const int restricted_pci[] = { ROMTYPE_GREX, ROMTYPE_MEDIATOR, ROMTYPE_PROMETHEUS, 0 };
  5926. romtype_restricted(p, restricted_net);
  5927. romtype_restricted(p, restricted_x86);
  5928. romtype_restricted(p, restricted_pci);
  5929. }
  5930. static int getconfigstoreline (const TCHAR *option, TCHAR *value);
  5931. static void calcformula (struct uae_prefs *prefs, TCHAR *in)
  5932. {
  5933. TCHAR out[MAX_DPATH], configvalue[CONFIG_BLEN];
  5934. TCHAR *p = out;
  5935. double val;
  5936. int cnt1, cnt2;
  5937. static bool updatestore;
  5938. if (_tcslen (in) < 2 || in[0] != '[' || in[_tcslen (in) - 1] != ']')
  5939. return;
  5940. if (!configstore || updatestore)
  5941. cfgfile_createconfigstore (prefs);
  5942. updatestore = false;
  5943. if (!configstore)
  5944. return;
  5945. cnt1 = cnt2 = 0;
  5946. for (int i = 1; i < _tcslen (in) - 1; i++) {
  5947. TCHAR c = _totupper (in[i]);
  5948. if (c >= 'A' && c <='Z') {
  5949. TCHAR *start = &in[i];
  5950. while (_istalnum (c) || c == '_' || c == '.') {
  5951. i++;
  5952. c = in[i];
  5953. }
  5954. TCHAR store = in[i];
  5955. in[i] = 0;
  5956. //write_log (_T("'%s'\n"), start);
  5957. if (!getconfigstoreline (start, configvalue))
  5958. return;
  5959. _tcscpy (p, configvalue);
  5960. p += _tcslen (p);
  5961. in[i] = store;
  5962. i--;
  5963. cnt1++;
  5964. } else {
  5965. cnt2++;
  5966. *p ++= c;
  5967. }
  5968. }
  5969. *p = 0;
  5970. if (cnt1 == 0 && cnt2 == 0)
  5971. return;
  5972. /* single config entry only? */
  5973. if (cnt1 == 1 && cnt2 == 0) {
  5974. _tcscpy (in, out);
  5975. updatestore = true;
  5976. return;
  5977. }
  5978. if (calc (out, &val)) {
  5979. if (val - (int)val != 0.0f)
  5980. _stprintf (in, _T("%f"), val);
  5981. else
  5982. _stprintf (in, _T("%d"), (int)val);
  5983. updatestore = true;
  5984. return;
  5985. }
  5986. }
  5987. int cfgfile_parse_option (struct uae_prefs *p, const TCHAR *option, TCHAR *value, int type)
  5988. {
  5989. calcformula (p, value);
  5990. if (!_tcscmp (option, _T("debug"))) {
  5991. write_log (_T("CONFIG DEBUG: '%s'\n"), value);
  5992. return 1;
  5993. }
  5994. if (!_tcscmp (option, _T("config_hardware")))
  5995. return 1;
  5996. if (!_tcscmp (option, _T("config_host")))
  5997. return 1;
  5998. if (cfgfile_path (option, value, _T("config_all_path"), p->config_all_path, sizeof p->config_all_path / sizeof(TCHAR)))
  5999. return 1;
  6000. if (cfgfile_path (option, value, _T("config_hardware_path"), p->config_hardware_path, sizeof p->config_hardware_path / sizeof (TCHAR)))
  6001. return 1;
  6002. if (cfgfile_path (option, value, _T("config_host_path"), p->config_host_path, sizeof p->config_host_path / sizeof(TCHAR)))
  6003. return 1;
  6004. if (type == 0 || (type & CONFIG_TYPE_HARDWARE)) {
  6005. if (cfgfile_parse_hardware (p, option, value))
  6006. return 1;
  6007. }
  6008. if (type == 0 || (type & CONFIG_TYPE_HOST)) {
  6009. // cfgfile_parse_host may modify the option (convert to lowercase).
  6010. TCHAR* writable_option = my_strdup(option);
  6011. if (cfgfile_parse_host (p, writable_option, value)) {
  6012. free(writable_option);
  6013. return 1;
  6014. }
  6015. free(writable_option);
  6016. }
  6017. if (type > 0 && (type & (CONFIG_TYPE_HARDWARE | CONFIG_TYPE_HOST)) != (CONFIG_TYPE_HARDWARE | CONFIG_TYPE_HOST))
  6018. return 1;
  6019. return 0;
  6020. }
  6021. static int isutf8ext (TCHAR *s)
  6022. {
  6023. if (_tcslen (s) > _tcslen (UTF8NAME) && !_tcscmp (s + _tcslen (s) - _tcslen (UTF8NAME), UTF8NAME)) {
  6024. s[_tcslen (s) - _tcslen (UTF8NAME)] = 0;
  6025. return 1;
  6026. }
  6027. return 0;
  6028. }
  6029. static int cfgfile_separate_linea (const TCHAR *filename, char *line, TCHAR *line1b, TCHAR *line2b)
  6030. {
  6031. char *line1, *line2;
  6032. int i;
  6033. line1 = line;
  6034. line1 += strspn (line1, "\t \r\n");
  6035. if (*line1 == ';')
  6036. return 0;
  6037. line2 = strchr (line, '=');
  6038. if (! line2) {
  6039. TCHAR *s = au (line1);
  6040. cfgfile_warning(_T("CFGFILE: '%s', linea was incomplete with only %s\n"), filename, s);
  6041. xfree (s);
  6042. return 0;
  6043. }
  6044. *line2++ = '\0';
  6045. /* Get rid of whitespace. */
  6046. i = strlen (line2);
  6047. while (i > 0 && (line2[i - 1] == '\t' || line2[i - 1] == ' '
  6048. || line2[i - 1] == '\r' || line2[i - 1] == '\n'))
  6049. line2[--i] = '\0';
  6050. line2 += strspn (line2, "\t \r\n");
  6051. i = strlen (line);
  6052. while (i > 0 && (line[i - 1] == '\t' || line[i - 1] == ' '
  6053. || line[i - 1] == '\r' || line[i - 1] == '\n'))
  6054. line[--i] = '\0';
  6055. line += strspn (line, "\t \r\n");
  6056. au_copy (line1b, MAX_DPATH, line);
  6057. if (isutf8ext (line1b)) {
  6058. if (line2[0]) {
  6059. TCHAR *s = utf8u (line2);
  6060. _tcscpy (line2b, s);
  6061. xfree (s);
  6062. }
  6063. } else {
  6064. au_copy (line2b, MAX_DPATH, line2);
  6065. }
  6066. return 1;
  6067. }
  6068. static int cfgfile_separate_line (TCHAR *line, TCHAR *line1b, TCHAR *line2b)
  6069. {
  6070. TCHAR *line1, *line2;
  6071. int i;
  6072. line1 = line;
  6073. line1 += _tcsspn (line1, _T("\t \r\n"));
  6074. if (*line1 == ';')
  6075. return 0;
  6076. line2 = _tcschr (line, '=');
  6077. if (! line2) {
  6078. cfgfile_warning(_T("CFGFILE: line was incomplete with only %s\n"), line1);
  6079. return 0;
  6080. }
  6081. *line2++ = '\0';
  6082. /* Get rid of whitespace. */
  6083. i = _tcslen (line2);
  6084. while (i > 0 && (line2[i - 1] == '\t' || line2[i - 1] == ' '
  6085. || line2[i - 1] == '\r' || line2[i - 1] == '\n'))
  6086. line2[--i] = '\0';
  6087. line2 += _tcsspn (line2, _T("\t \r\n"));
  6088. _tcscpy (line2b, line2);
  6089. i = _tcslen (line);
  6090. while (i > 0 && (line[i - 1] == '\t' || line[i - 1] == ' '
  6091. || line[i - 1] == '\r' || line[i - 1] == '\n'))
  6092. line[--i] = '\0';
  6093. line += _tcsspn (line, _T("\t \r\n"));
  6094. _tcscpy (line1b, line);
  6095. if (line2b[0] == '"' || line2b[0] == '\"') {
  6096. TCHAR c = line2b[0];
  6097. int i = 0;
  6098. memmove (line2b, line2b + 1, (_tcslen (line2b) + 1) * sizeof (TCHAR));
  6099. while (line2b[i] != 0 && line2b[i] != c)
  6100. i++;
  6101. line2b[i] = 0;
  6102. }
  6103. if (isutf8ext (line1b))
  6104. return 0;
  6105. return 1;
  6106. }
  6107. static int isobsolete (TCHAR *s)
  6108. {
  6109. int i = 0;
  6110. while (obsolete[i]) {
  6111. if (!strcasecmp (s, obsolete[i])) {
  6112. cfgfile_warning_obsolete(_T("obsolete config entry '%s'\n"), s);
  6113. return 1;
  6114. }
  6115. i++;
  6116. }
  6117. if (_tcslen (s) > 2 && !_tcsncmp (s, _T("w."), 2))
  6118. return 1;
  6119. if (_tcslen (s) >= 10 && !_tcsncmp (s, _T("gfx_opengl"), 10)) {
  6120. cfgfile_warning_obsolete(_T("obsolete config entry '%s\n"), s);
  6121. return 1;
  6122. }
  6123. if (_tcslen (s) >= 6 && !_tcsncmp (s, _T("gfx_3d"), 6)) {
  6124. cfgfile_warning_obsolete(_T("obsolete config entry '%s\n"), s);
  6125. return 1;
  6126. }
  6127. return 0;
  6128. }
  6129. static void cfgfile_parse_separated_line (struct uae_prefs *p, TCHAR *line1b, TCHAR *line2b, int type)
  6130. {
  6131. TCHAR line3b[CONFIG_BLEN], line4b[CONFIG_BLEN];
  6132. struct strlist *sl;
  6133. int ret;
  6134. _tcscpy (line3b, line1b);
  6135. _tcscpy (line4b, line2b);
  6136. ret = cfgfile_parse_option (p, line1b, line2b, type);
  6137. if (!isobsolete (line3b)) {
  6138. for (sl = p->all_lines; sl; sl = sl->next) {
  6139. if (sl->option && !strcasecmp (line1b, sl->option)) break;
  6140. }
  6141. if (!sl) {
  6142. struct strlist *u = xcalloc (struct strlist, 1);
  6143. u->option = my_strdup (line3b);
  6144. u->value = my_strdup (line4b);
  6145. u->next = p->all_lines;
  6146. p->all_lines = u;
  6147. if (!ret) {
  6148. u->unknown = 1;
  6149. cfgfile_warning(_T("unknown config entry: '%s=%s'\n"), u->option, u->value);
  6150. }
  6151. }
  6152. }
  6153. }
  6154. void cfgfile_parse_lines (struct uae_prefs *p, const TCHAR *lines, int type)
  6155. {
  6156. TCHAR *buf = my_strdup (lines);
  6157. TCHAR *t = buf;
  6158. for (;;) {
  6159. if (_tcslen (t) == 0)
  6160. break;
  6161. TCHAR *t2 = _tcschr (t, '\n');
  6162. if (t2)
  6163. *t2 = 0;
  6164. cfgfile_parse_line (p, t, type);
  6165. if (!t2)
  6166. break;
  6167. t = t2 + 1;
  6168. }
  6169. xfree (buf);
  6170. }
  6171. void cfgfile_parse_line (struct uae_prefs *p, TCHAR *line, int type)
  6172. {
  6173. TCHAR line1b[CONFIG_BLEN], line2b[CONFIG_BLEN];
  6174. if (!cfgfile_separate_line (line, line1b, line2b))
  6175. return;
  6176. cfgfile_parse_separated_line (p, line1b, line2b, type);
  6177. }
  6178. static void subst (TCHAR *p, TCHAR *f, int n)
  6179. {
  6180. if (_tcslen(p) == 0 || _tcslen(f) == 0)
  6181. return;
  6182. TCHAR *str = cfgfile_subst_path (UNEXPANDED, p, f);
  6183. _tcsncpy (f, str, n - 1);
  6184. f[n - 1] = '\0';
  6185. free (str);
  6186. }
  6187. const TCHAR *cfgfile_getconfigdata(int *len)
  6188. {
  6189. *len = -1;
  6190. if (!configstore)
  6191. return NULL;
  6192. return (TCHAR*)zfile_get_data_pointer(configstore, len);
  6193. }
  6194. static int getconfigstoreline (const TCHAR *option, TCHAR *value)
  6195. {
  6196. TCHAR tmp[CONFIG_BLEN * 2], tmp2[CONFIG_BLEN * 2];
  6197. if (!configstore)
  6198. return 0;
  6199. zfile_fseek (configstore, 0, SEEK_SET);
  6200. for (;;) {
  6201. if (!zfile_fgets (tmp, sizeof tmp / sizeof (TCHAR), configstore))
  6202. return 0;
  6203. if (!cfgfile_separate_line (tmp, tmp2, value))
  6204. continue;
  6205. if (!_tcsicmp (option, tmp2))
  6206. return 1;
  6207. }
  6208. }
  6209. bool cfgfile_createconfigstore(struct uae_prefs *p)
  6210. {
  6211. uae_u8 zeros[4] = { 0 };
  6212. zfile_fclose (configstore);
  6213. configstore = zfile_fopen_empty (NULL, _T("configstore"), 50000);
  6214. if (!configstore)
  6215. return false;
  6216. zfile_fseek (configstore, 0, SEEK_SET);
  6217. uaeconfig++;
  6218. cfgfile_save_options (configstore, p, 0);
  6219. uaeconfig--;
  6220. zfile_fwrite (zeros, 1, sizeof zeros, configstore);
  6221. zfile_truncate(configstore, zfile_ftell(configstore));
  6222. zfile_fseek (configstore, 0, SEEK_SET);
  6223. return true;
  6224. }
  6225. static char *cfg_fgets (char *line, int max, struct zfile *fh)
  6226. {
  6227. #ifdef SINGLEFILE
  6228. extern TCHAR singlefile_config[];
  6229. static TCHAR *sfile_ptr;
  6230. TCHAR *p;
  6231. #endif
  6232. if (fh)
  6233. return zfile_fgetsa (line, max, fh);
  6234. #ifdef SINGLEFILE
  6235. if (sfile_ptr == 0) {
  6236. sfile_ptr = singlefile_config;
  6237. if (*sfile_ptr) {
  6238. write_log (_T("singlefile config found\n"));
  6239. while (*sfile_ptr++);
  6240. }
  6241. }
  6242. if (*sfile_ptr == 0) {
  6243. sfile_ptr = singlefile_config;
  6244. return 0;
  6245. }
  6246. p = sfile_ptr;
  6247. while (*p != 13 && *p != 10 && *p != 0) p++;
  6248. memset (line, 0, max);
  6249. memcpy (line, sfile_ptr, (p - sfile_ptr) * sizeof (TCHAR));
  6250. sfile_ptr = p + 1;
  6251. if (*sfile_ptr == 13)
  6252. sfile_ptr++;
  6253. if (*sfile_ptr == 10)
  6254. sfile_ptr++;
  6255. return line;
  6256. #endif
  6257. return 0;
  6258. }
  6259. static int cfgfile_load_2 (struct uae_prefs *p, const TCHAR *filename, bool real, int *type)
  6260. {
  6261. int i;
  6262. struct zfile *fh;
  6263. char linea[CONFIG_BLEN];
  6264. TCHAR line[CONFIG_BLEN], line1b[CONFIG_BLEN], line2b[CONFIG_BLEN];
  6265. struct strlist *sl;
  6266. bool type1 = false, type2 = false;
  6267. int askedtype = 0;
  6268. if (type) {
  6269. askedtype = *type;
  6270. *type = 0;
  6271. }
  6272. if (real) {
  6273. p->config_version = 0;
  6274. config_newfilesystem = 0;
  6275. //reset_inputdevice_config (p);
  6276. }
  6277. fh = zfile_fopen (filename, _T("r"), ZFD_NORMAL);
  6278. #ifndef SINGLEFILE
  6279. if (! fh)
  6280. return 0;
  6281. #endif
  6282. while (cfg_fgets (linea, sizeof (linea), fh) != 0) {
  6283. trimwsa (linea);
  6284. if (strlen (linea) > 0) {
  6285. if (linea[0] == '#' || linea[0] == ';') {
  6286. struct strlist *u = xcalloc (struct strlist, 1);
  6287. u->option = NULL;
  6288. TCHAR *com = au (linea);
  6289. u->value = my_strdup (com);
  6290. xfree (com);
  6291. u->unknown = 1;
  6292. u->next = p->all_lines;
  6293. p->all_lines = u;
  6294. continue;
  6295. }
  6296. if (!cfgfile_separate_linea (filename, linea, line1b, line2b))
  6297. continue;
  6298. type1 = type2 = 0;
  6299. if (cfgfile_yesno (line1b, line2b, _T("config_hardware"), &type1) ||
  6300. cfgfile_yesno (line1b, line2b, _T("config_host"), &type2)) {
  6301. if (type1 && type)
  6302. *type |= CONFIG_TYPE_HARDWARE;
  6303. if (type2 && type)
  6304. *type |= CONFIG_TYPE_HOST;
  6305. continue;
  6306. }
  6307. if (real) {
  6308. cfgfile_parse_separated_line (p, line1b, line2b, askedtype);
  6309. } else {
  6310. // metadata
  6311. cfgfile_string(line1b, line2b, _T("config_description"), p->description, sizeof p->description / sizeof(TCHAR));
  6312. cfgfile_string(line1b, line2b, _T("config_category"), p->category, sizeof p->category / sizeof(TCHAR));
  6313. cfgfile_string(line1b, line2b, _T("config_tags"), p->tags, sizeof p->tags / sizeof(TCHAR));
  6314. cfgfile_path (line1b, line2b, _T("config_hardware_path"), p->config_hardware_path, sizeof p->config_hardware_path / sizeof (TCHAR));
  6315. cfgfile_path (line1b, line2b, _T("config_host_path"), p->config_host_path, sizeof p->config_host_path / sizeof(TCHAR));
  6316. cfgfile_path (line1b, line2b, _T("config_all_path"), p->config_all_path, sizeof p->config_all_path / sizeof(TCHAR));
  6317. cfgfile_string (line1b, line2b, _T("config_window_title"), p->config_window_title, sizeof p->config_window_title / sizeof (TCHAR));
  6318. // boxart checks
  6319. cfgfile_string(line1b, line2b, _T("floppy0"), p->floppyslots[0].df, sizeof p->floppyslots[0].df / sizeof(TCHAR));
  6320. cfgfile_resolve_path_load(p->floppyslots[0].df, MAX_DPATH, PATH_FLOPPY);
  6321. TCHAR tmp[MAX_DPATH];
  6322. if (!p->mountitems && (cfgfile_string(line1b, line2b, _T("hardfile2"), tmp, sizeof tmp / sizeof(TCHAR)) || cfgfile_string(line1b, line2b, _T("filesystem2"), tmp, sizeof tmp / sizeof(TCHAR)))) {
  6323. const TCHAR *s = _tcschr(tmp, ':');
  6324. if (s) {
  6325. bool isvsys = false;
  6326. if (!_tcscmp(line1b, _T("filesystem2"))) {
  6327. s++;
  6328. s = _tcschr(s, ':');
  6329. isvsys = true;
  6330. }
  6331. if (s) {
  6332. s++;
  6333. bool quoted = false;
  6334. if (s[0] == '"') {
  6335. s++;
  6336. quoted = true;
  6337. }
  6338. const TCHAR *se = _tcschr(s, quoted ? '"' : ',');
  6339. if (se) {
  6340. tmp[se - tmp] = 0;
  6341. _tcscpy(p->mountconfig[0].ci.rootdir, s);
  6342. cfgfile_resolve_path_load(p->mountconfig[0].ci.rootdir, MAX_DPATH, isvsys ? PATH_DIR : PATH_HDF);
  6343. p->mountitems = 1;
  6344. }
  6345. }
  6346. }
  6347. }
  6348. if (!p->cdslots[0].inuse && cfgfile_path(line1b, line2b, _T("cdimage0"), tmp, sizeof tmp / sizeof(TCHAR))) {
  6349. TCHAR *s = tmp;
  6350. if (s[0] == '"') {
  6351. s++;
  6352. const TCHAR *se = _tcschr(s, '"');
  6353. if (se)
  6354. tmp[se - tmp] = 0;
  6355. } else {
  6356. const TCHAR *se = _tcschr(s, ',');
  6357. if (se)
  6358. tmp[se - tmp] = 0;
  6359. }
  6360. _tcscpy(p->cdslots[0].name, s);
  6361. cfgfile_resolve_path_load(p->cdslots[0].name, MAX_DPATH, PATH_CD);
  6362. p->cdslots[0].inuse = 1;
  6363. }
  6364. }
  6365. }
  6366. }
  6367. if (type && *type == 0)
  6368. *type = CONFIG_TYPE_HARDWARE | CONFIG_TYPE_HOST;
  6369. zfile_fclose (fh);
  6370. if (!real)
  6371. return 1;
  6372. for (sl = temp_lines; sl; sl = sl->next) {
  6373. _stprintf (line, _T("%s=%s"), sl->option, sl->value);
  6374. cfgfile_parse_line (p, line, 0);
  6375. }
  6376. subst (p->path_rom.path[0], p->romfile, sizeof p->romfile / sizeof (TCHAR));
  6377. subst (p->path_rom.path[0], p->romextfile, sizeof p->romextfile / sizeof (TCHAR));
  6378. subst (p->path_rom.path[0], p->romextfile2, sizeof p->romextfile2 / sizeof (TCHAR));
  6379. for (i = 0; i < MAX_EXPANSION_BOARDS; i++) {
  6380. for (int j = 0; j < MAX_BOARD_ROMS; j++) {
  6381. subst(p->path_rom.path[0], p->expansionboard[i].roms[j].romfile, MAX_DPATH / sizeof(TCHAR));
  6382. }
  6383. }
  6384. return 1;
  6385. }
  6386. int cfgfile_load (struct uae_prefs *p, const TCHAR *filename, int *type, int ignorelink, int userconfig)
  6387. {
  6388. int v;
  6389. TCHAR tmp[MAX_DPATH];
  6390. int type2;
  6391. static int recursive;
  6392. if (recursive > 1)
  6393. return 0;
  6394. recursive++;
  6395. write_log (_T("load config '%s':%d\n"), filename, type ? *type : -1);
  6396. v = cfgfile_load_2 (p, filename, 1, type);
  6397. if (!v) {
  6398. cfgfile_warning(_T("cfgfile_load_2 failed\n"));
  6399. goto end;
  6400. }
  6401. if (userconfig)
  6402. target_addtorecent (filename, 0);
  6403. if (!ignorelink) {
  6404. if (p->config_all_path[0]) {
  6405. fetch_configurationpath(tmp, sizeof(tmp) / sizeof(TCHAR));
  6406. _tcsncat(tmp, p->config_all_path, sizeof(tmp) / sizeof(TCHAR) - _tcslen(tmp) - 1);
  6407. type2 = CONFIG_TYPE_HOST | CONFIG_TYPE_HARDWARE;
  6408. cfgfile_load(p, tmp, &type2, 1, 0);
  6409. }
  6410. if (p->config_hardware_path[0]) {
  6411. fetch_configurationpath (tmp, sizeof (tmp) / sizeof (TCHAR));
  6412. _tcsncat (tmp, p->config_hardware_path, sizeof (tmp) / sizeof (TCHAR) - _tcslen(tmp) - 1);
  6413. type2 = CONFIG_TYPE_HARDWARE;
  6414. cfgfile_load (p, tmp, &type2, 1, 0);
  6415. }
  6416. if (p->config_host_path[0]) {
  6417. fetch_configurationpath (tmp, sizeof (tmp) / sizeof (TCHAR));
  6418. _tcsncat (tmp, p->config_host_path, sizeof (tmp) / sizeof (TCHAR) - _tcslen(tmp) - 1);
  6419. type2 = CONFIG_TYPE_HOST;
  6420. cfgfile_load (p, tmp, &type2, 1, 0);
  6421. }
  6422. }
  6423. end:
  6424. recursive--;
  6425. for (int i = 1; i < MAX_AMIGADISPLAYS; i++) {
  6426. memcpy(&p->gfx_monitor[i], &p->gfx_monitor[0], sizeof(struct monconfig));
  6427. }
  6428. fixup_prefs (p, userconfig != 0);
  6429. return v;
  6430. }
  6431. void cfgfile_backup (const TCHAR *path)
  6432. {
  6433. TCHAR dpath[MAX_DPATH];
  6434. fetch_configurationpath (dpath, sizeof (dpath) / sizeof (TCHAR));
  6435. _tcscat (dpath, _T("configuration.backup"));
  6436. bool hidden = my_isfilehidden (dpath);
  6437. my_unlink (dpath, true);
  6438. my_rename (path, dpath);
  6439. if (hidden)
  6440. my_setfilehidden (dpath, hidden);
  6441. }
  6442. int cfgfile_save (struct uae_prefs *p, const TCHAR *filename, int type)
  6443. {
  6444. struct zfile *fh;
  6445. cfgfile_backup (filename);
  6446. fh = zfile_fopen (filename, unicode_config ? _T("w, ccs=UTF-8") : _T("w"), ZFD_NORMAL);
  6447. if (! fh)
  6448. return 0;
  6449. if (!type)
  6450. type = CONFIG_TYPE_HARDWARE | CONFIG_TYPE_HOST;
  6451. cfgfile_save_options (fh, p, type);
  6452. zfile_fclose (fh);
  6453. return 1;
  6454. }
  6455. struct uae_prefs *cfgfile_open(const TCHAR *filename, int *type)
  6456. {
  6457. struct uae_prefs *p = xcalloc(struct uae_prefs, 1);
  6458. if (cfgfile_load_2(p, filename, false, type))
  6459. return p;
  6460. xfree(p);
  6461. return NULL;
  6462. }
  6463. void cfgfile_close(struct uae_prefs *p)
  6464. {
  6465. xfree(p);
  6466. }
  6467. int cfgfile_get_description (struct uae_prefs *p, const TCHAR *filename, TCHAR *description, TCHAR *category, TCHAR *tags, TCHAR *hostlink, TCHAR *hardwarelink, int *type)
  6468. {
  6469. bool alloc = false;
  6470. if (!p) {
  6471. p = xmalloc(struct uae_prefs, 1);
  6472. alloc = true;
  6473. }
  6474. if (!p) {
  6475. alloc = true;
  6476. p = cfgfile_open(filename, type);
  6477. }
  6478. if (!p)
  6479. return 0;
  6480. if (description)
  6481. _tcscpy(description, p->description);
  6482. if (category)
  6483. _tcscpy(category, p->category);
  6484. if (tags)
  6485. _tcscpy(tags, p->tags);
  6486. if (hostlink)
  6487. _tcscpy (hostlink, p->config_host_path);
  6488. if (hardwarelink)
  6489. _tcscpy (hardwarelink, p->config_hardware_path);
  6490. if (alloc) {
  6491. cfgfile_close(p);
  6492. }
  6493. return 1;
  6494. }
  6495. bool cfgfile_detect_art_path(const TCHAR *path, TCHAR *outpath)
  6496. {
  6497. TCHAR tmp[MAX_DPATH];
  6498. const TCHAR *p;
  6499. if (!path[0])
  6500. return false;
  6501. #if 0
  6502. if (path[0] == '\\')
  6503. return false;
  6504. #endif
  6505. write_log(_T("Possible boxart path: '%s'\n"), path);
  6506. _tcscpy(tmp, path);
  6507. p = _tcsrchr(tmp, '\\');
  6508. if (!p)
  6509. p = _tcsrchr(tmp, '/');
  6510. if (!p)
  6511. return false;
  6512. tmp[p - tmp] = 0;
  6513. _tcscat(tmp, FSDB_DIR_SEPARATOR_S);
  6514. _tcscat(tmp, _T("___Title.png"));
  6515. if (!zfile_exists(tmp))
  6516. return false;
  6517. tmp[p - tmp + 1] = 0;
  6518. _tcscpy(outpath, tmp);
  6519. write_log(_T("Detected!\n"));
  6520. return true;
  6521. }
  6522. bool cfgfile_detect_art(struct uae_prefs *p, TCHAR *path)
  6523. {
  6524. if (cfgfile_detect_art_path(p->floppyslots[0].df, path))
  6525. return true;
  6526. if (p->mountitems > 0 && cfgfile_detect_art_path(p->mountconfig[0].ci.rootdir, path))
  6527. return true;
  6528. if (p->cdslots[0].inuse && cfgfile_detect_art_path(p->cdslots[0].name, path))
  6529. return true;
  6530. return false;
  6531. }
  6532. void cfgfile_show_usage (void)
  6533. {
  6534. int i;
  6535. write_log (_T("UAE Configuration Help:\n") \
  6536. _T("=======================\n"));
  6537. for (i = 0; i < sizeof opttable / sizeof *opttable; i++)
  6538. write_log (_T("%s: %s\n"), opttable[i].config_label, opttable[i].config_help);
  6539. }
  6540. /* This implements the old commandline option parsing. I've re-added this
  6541. because the new way of doing things is painful for me (it requires me
  6542. to type a couple hundred characters when invoking UAE). The following
  6543. is far less annoying to use. */
  6544. static void parse_gfx_specs (struct uae_prefs *p, const TCHAR *spec)
  6545. {
  6546. TCHAR *x0 = my_strdup (spec);
  6547. TCHAR *x1, *x2;
  6548. x1 = _tcschr (x0, ':');
  6549. if (x1 == 0)
  6550. goto argh;
  6551. x2 = _tcschr (x1+1, ':');
  6552. if (x2 == 0)
  6553. goto argh;
  6554. *x1++ = 0; *x2++ = 0;
  6555. p->gfx_monitor[0].gfx_size_win.width = p->gfx_monitor[0].gfx_size_fs.width = _tstoi (x0);
  6556. p->gfx_monitor[0].gfx_size_win.height = p->gfx_monitor[0].gfx_size_fs.height = _tstoi (x1);
  6557. p->gfx_resolution = _tcschr (x2, 'l') != 0 ? 1 : 0;
  6558. p->gfx_xcenter = _tcschr (x2, 'x') != 0 ? 1 : _tcschr (x2, 'X') != 0 ? 2 : 0;
  6559. p->gfx_ycenter = _tcschr (x2, 'y') != 0 ? 1 : _tcschr (x2, 'Y') != 0 ? 2 : 0;
  6560. p->gfx_vresolution = _tcschr (x2, 'd') != 0 ? VRES_DOUBLE : VRES_NONDOUBLE;
  6561. p->gfx_pscanlines = _tcschr (x2, 'D') != 0;
  6562. if (p->gfx_pscanlines)
  6563. p->gfx_vresolution = VRES_DOUBLE;
  6564. p->gfx_apmode[0].gfx_fullscreen = _tcschr (x2, 'a') != 0;
  6565. p->gfx_apmode[1].gfx_fullscreen = _tcschr (x2, 'p') != 0;
  6566. free (x0);
  6567. return;
  6568. argh:
  6569. write_log (_T("Bad display mode specification.\n"));
  6570. write_log (_T("The format to use is: \"width:height:modifiers\"\n"));
  6571. write_log (_T("Type \"uae -h\" for detailed help.\n"));
  6572. free (x0);
  6573. }
  6574. static void parse_sound_spec (struct uae_prefs *p, const TCHAR *spec)
  6575. {
  6576. TCHAR *x0 = my_strdup (spec);
  6577. TCHAR *x1, *x2 = NULL, *x3 = NULL, *x4 = NULL, *x5 = NULL;
  6578. x1 = _tcschr (x0, ':');
  6579. if (x1 != NULL) {
  6580. *x1++ = '\0';
  6581. x2 = _tcschr (x1 + 1, ':');
  6582. if (x2 != NULL) {
  6583. *x2++ = '\0';
  6584. x3 = _tcschr (x2 + 1, ':');
  6585. if (x3 != NULL) {
  6586. *x3++ = '\0';
  6587. x4 = _tcschr (x3 + 1, ':');
  6588. if (x4 != NULL) {
  6589. *x4++ = '\0';
  6590. x5 = _tcschr (x4 + 1, ':');
  6591. }
  6592. }
  6593. }
  6594. }
  6595. p->produce_sound = _tstoi (x0);
  6596. if (x1) {
  6597. p->sound_stereo_separation = 0;
  6598. if (*x1 == 'S') {
  6599. p->sound_stereo = SND_STEREO;
  6600. p->sound_stereo_separation = 7;
  6601. } else if (*x1 == 's')
  6602. p->sound_stereo = SND_STEREO;
  6603. else
  6604. p->sound_stereo = SND_MONO;
  6605. }
  6606. if (x3)
  6607. p->sound_freq = _tstoi (x3);
  6608. if (x4)
  6609. p->sound_maxbsiz = _tstoi (x4);
  6610. free (x0);
  6611. }
  6612. static void parse_joy_spec (struct uae_prefs *p, const TCHAR *spec)
  6613. {
  6614. int v0 = 2, v1 = 0;
  6615. if (_tcslen(spec) != 2)
  6616. goto bad;
  6617. switch (spec[0]) {
  6618. case '0': v0 = JSEM_JOYS; break;
  6619. case '1': v0 = JSEM_JOYS + 1; break;
  6620. case 'M': case 'm': v0 = JSEM_MICE; break;
  6621. case 'A': case 'a': v0 = JSEM_KBDLAYOUT; break;
  6622. case 'B': case 'b': v0 = JSEM_KBDLAYOUT + 1; break;
  6623. case 'C': case 'c': v0 = JSEM_KBDLAYOUT + 2; break;
  6624. default: goto bad;
  6625. }
  6626. switch (spec[1]) {
  6627. case '0': v1 = JSEM_JOYS; break;
  6628. case '1': v1 = JSEM_JOYS + 1; break;
  6629. case 'M': case 'm': v1 = JSEM_MICE; break;
  6630. case 'A': case 'a': v1 = JSEM_KBDLAYOUT; break;
  6631. case 'B': case 'b': v1 = JSEM_KBDLAYOUT + 1; break;
  6632. case 'C': case 'c': v1 = JSEM_KBDLAYOUT + 2; break;
  6633. default: goto bad;
  6634. }
  6635. if (v0 == v1)
  6636. goto bad;
  6637. /* Let's scare Pascal programmers */
  6638. if (0)
  6639. bad:
  6640. write_log (_T("Bad joystick mode specification. Use -J xy, where x and y\n")
  6641. _T("can be 0 for joystick 0, 1 for joystick 1, M for mouse, and\n")
  6642. _T("a, b or c for different keyboard settings.\n"));
  6643. p->jports[0].id = v0;
  6644. p->jports[1].id = v1;
  6645. }
  6646. static void parse_filesys_spec (struct uae_prefs *p, bool readonly, const TCHAR *spec)
  6647. {
  6648. struct uaedev_config_info uci;
  6649. TCHAR buf[256];
  6650. TCHAR *s2;
  6651. uci_set_defaults (&uci, false);
  6652. _tcsncpy (buf, spec, 255); buf[255] = 0;
  6653. s2 = _tcschr (buf, ':');
  6654. if (s2) {
  6655. *s2++ = '\0';
  6656. #ifdef __DOS__
  6657. {
  6658. TCHAR *tmp;
  6659. while ((tmp = _tcschr (s2, '\\')))
  6660. *tmp = '/';
  6661. }
  6662. #endif
  6663. #ifdef FILESYS
  6664. _tcscpy (uci.volname, buf);
  6665. _tcscpy (uci.rootdir, s2);
  6666. uci.readonly = readonly;
  6667. uci.type = UAEDEV_DIR;
  6668. add_filesys_config (p, -1, &uci);
  6669. #endif
  6670. } else {
  6671. write_log (_T("Usage: [-m | -M] VOLNAME:mount_point\n"));
  6672. }
  6673. }
  6674. static void parse_hardfile_spec (struct uae_prefs *p, const TCHAR *spec)
  6675. {
  6676. struct uaedev_config_info uci;
  6677. TCHAR *x0 = my_strdup (spec);
  6678. TCHAR *x1, *x2, *x3, *x4;
  6679. uci_set_defaults (&uci, false);
  6680. x1 = _tcschr (x0, ':');
  6681. if (x1 == NULL)
  6682. goto argh;
  6683. *x1++ = '\0';
  6684. x2 = _tcschr (x1 + 1, ':');
  6685. if (x2 == NULL)
  6686. goto argh;
  6687. *x2++ = '\0';
  6688. x3 = _tcschr (x2 + 1, ':');
  6689. if (x3 == NULL)
  6690. goto argh;
  6691. *x3++ = '\0';
  6692. x4 = _tcschr (x3 + 1, ':');
  6693. if (x4 == NULL)
  6694. goto argh;
  6695. *x4++ = '\0';
  6696. #ifdef FILESYS
  6697. _tcscpy (uci.rootdir, x4);
  6698. //add_filesys_config (p, -1, NULL, NULL, x4, 0, 0, _tstoi (x0), _tstoi (x1), _tstoi (x2), _tstoi (x3), 0, 0, 0, 0, 0, 0, 0);
  6699. #endif
  6700. free (x0);
  6701. return;
  6702. argh:
  6703. free (x0);
  6704. cfgfile_warning(_T("Bad hardfile parameter specified\n"));
  6705. return;
  6706. }
  6707. static void parse_cpu_specs (struct uae_prefs *p, const TCHAR *spec)
  6708. {
  6709. if (*spec < '0' || *spec > '4') {
  6710. cfgfile_warning(_T("CPU parameter string must begin with '0', '1', '2', '3' or '4'.\n"));
  6711. return;
  6712. }
  6713. p->cpu_model = (*spec++) * 10 + 68000;
  6714. p->address_space_24 = p->cpu_model < 68020;
  6715. p->cpu_compatible = 0;
  6716. while (*spec != '\0') {
  6717. switch (*spec) {
  6718. case 'a':
  6719. if (p->cpu_model < 68020)
  6720. cfgfile_warning(_T("In 68000/68010 emulation, the address space is always 24 bit.\n"));
  6721. else if (p->cpu_model >= 68040)
  6722. cfgfile_warning(_T("In 68040/060 emulation, the address space is always 32 bit.\n"));
  6723. else
  6724. p->address_space_24 = 1;
  6725. break;
  6726. case 'c':
  6727. if (p->cpu_model != 68000)
  6728. cfgfile_warning(_T("The more compatible CPU emulation is only available for 68000\n")
  6729. _T("emulation, not for 68010 upwards.\n"));
  6730. else
  6731. p->cpu_compatible = 1;
  6732. break;
  6733. default:
  6734. cfgfile_warning(_T("Bad CPU parameter specified.\n"));
  6735. break;
  6736. }
  6737. spec++;
  6738. }
  6739. }
  6740. static void cmdpath (TCHAR *dst, const TCHAR *src, int maxsz)
  6741. {
  6742. TCHAR *s = target_expand_environment (src, NULL, 0);
  6743. _tcsncpy (dst, s, maxsz);
  6744. dst[maxsz] = 0;
  6745. xfree (s);
  6746. }
  6747. /* Returns the number of args used up (0 or 1). */
  6748. int parse_cmdline_option (struct uae_prefs *p, TCHAR c, const TCHAR *arg)
  6749. {
  6750. struct strlist *u = xcalloc (struct strlist, 1);
  6751. const TCHAR arg_required[] = _T("0123rKpImMWSRJwnvCZUFbclOdH");
  6752. if (_tcschr (arg_required, c) && ! arg) {
  6753. write_log (_T("Missing argument for option `-%c'!\n"), c);
  6754. return 0;
  6755. }
  6756. u->option = xmalloc (TCHAR, 2);
  6757. u->option[0] = c;
  6758. u->option[1] = 0;
  6759. u->value = my_strdup (arg);
  6760. u->next = p->all_lines;
  6761. p->all_lines = u;
  6762. switch (c) {
  6763. case 'h': usage (); exit (0);
  6764. case '0': cmdpath (p->floppyslots[0].df, arg, 255); break;
  6765. case '1': cmdpath (p->floppyslots[1].df, arg, 255); break;
  6766. case '2': cmdpath (p->floppyslots[2].df, arg, 255); break;
  6767. case '3': cmdpath (p->floppyslots[3].df, arg, 255); break;
  6768. case 'r': cmdpath (p->romfile, arg, 255); break;
  6769. case 'K': cmdpath (p->romextfile, arg, 255); break;
  6770. case 'p': _tcsncpy (p->prtname, arg, 255); p->prtname[255] = 0; break;
  6771. /* case 'I': _tcsncpy (p->sername, arg, 255); p->sername[255] = 0; currprefs.use_serial = 1; break; */
  6772. case 'm': case 'M': parse_filesys_spec (p, c == 'M', arg); break;
  6773. case 'W': parse_hardfile_spec (p, arg); break;
  6774. case 'S': parse_sound_spec (p, arg); break;
  6775. case 'R': p->gfx_framerate = _tstoi (arg); break;
  6776. case 'i': p->illegal_mem = 1; break;
  6777. case 'J': parse_joy_spec (p, arg); break;
  6778. case 'w': p->m68k_speed = _tstoi (arg); break;
  6779. /* case 'g': p->use_gfxlib = 1; break; */
  6780. case 'G': p->start_gui = 0; break;
  6781. case 'D': p->start_debugger = 1; break;
  6782. case 'n':
  6783. if (_tcschr (arg, 'i') != 0)
  6784. p->immediate_blits = 1;
  6785. break;
  6786. case 'v':
  6787. set_chipset_mask (p, _tstoi (arg));
  6788. break;
  6789. case 'C':
  6790. parse_cpu_specs (p, arg);
  6791. break;
  6792. case 'Z':
  6793. p->z3fastmem[0].size = _tstoi (arg) * 0x100000;
  6794. break;
  6795. case 'U':
  6796. p->rtgboards[0].rtgmem_size = _tstoi (arg) * 0x100000;
  6797. break;
  6798. case 'F':
  6799. p->fastmem[0].size = _tstoi (arg) * 0x100000;
  6800. break;
  6801. case 'b':
  6802. p->bogomem.size = _tstoi (arg) * 0x40000;
  6803. break;
  6804. case 'c':
  6805. p->chipmem.size = _tstoi (arg) * 0x80000;
  6806. break;
  6807. case 'l':
  6808. if (0 == strcasecmp(arg, _T("de")))
  6809. p->keyboard_lang = KBD_LANG_DE;
  6810. else if (0 == strcasecmp(arg, _T("dk")))
  6811. p->keyboard_lang = KBD_LANG_DK;
  6812. else if (0 == strcasecmp(arg, _T("us")))
  6813. p->keyboard_lang = KBD_LANG_US;
  6814. else if (0 == strcasecmp(arg, _T("se")))
  6815. p->keyboard_lang = KBD_LANG_SE;
  6816. else if (0 == strcasecmp(arg, _T("fr")))
  6817. p->keyboard_lang = KBD_LANG_FR;
  6818. else if (0 == strcasecmp(arg, _T("it")))
  6819. p->keyboard_lang = KBD_LANG_IT;
  6820. else if (0 == strcasecmp(arg, _T("es")))
  6821. p->keyboard_lang = KBD_LANG_ES;
  6822. break;
  6823. case 'O': parse_gfx_specs (p, arg); break;
  6824. case 'd':
  6825. if (_tcschr (arg, 'S') != NULL || _tcschr (arg, 's')) {
  6826. write_log (_T(" Serial on demand.\n"));
  6827. p->serial_demand = 1;
  6828. }
  6829. if (_tcschr (arg, 'P') != NULL || _tcschr (arg, 'p')) {
  6830. write_log (_T(" Parallel on demand.\n"));
  6831. p->parallel_demand = 1;
  6832. }
  6833. break;
  6834. case 'H':
  6835. p->color_mode = _tstoi (arg);
  6836. if (p->color_mode < 0) {
  6837. write_log (_T("Bad color mode selected. Using default.\n"));
  6838. p->color_mode = 0;
  6839. }
  6840. break;
  6841. default:
  6842. write_log (_T("Unknown option `-%c'!\n"), c);
  6843. break;
  6844. }
  6845. return !! _tcschr (arg_required, c);
  6846. }
  6847. void cfgfile_addcfgparam (TCHAR *line)
  6848. {
  6849. struct strlist *u;
  6850. TCHAR line1b[CONFIG_BLEN], line2b[CONFIG_BLEN];
  6851. if (!line) {
  6852. struct strlist **ps = &temp_lines;
  6853. while (*ps) {
  6854. struct strlist *s = *ps;
  6855. *ps = s->next;
  6856. xfree (s->value);
  6857. xfree (s->option);
  6858. xfree (s);
  6859. }
  6860. temp_lines = 0;
  6861. return;
  6862. }
  6863. if (!cfgfile_separate_line (line, line1b, line2b))
  6864. return;
  6865. if (!_tcsnicmp(line1b, _T("input."), 6)) {
  6866. line1b[5] = '_';
  6867. }
  6868. u = xcalloc (struct strlist, 1);
  6869. if (u) {
  6870. u->option = my_strdup(line1b);
  6871. u->value = my_strdup(line2b);
  6872. u->next = temp_lines;
  6873. temp_lines = u;
  6874. }
  6875. }
  6876. #if 0
  6877. static int cfgfile_handle_custom_event (TCHAR *custom, int mode)
  6878. {
  6879. TCHAR option[CONFIG_BLEN], value[CONFIG_BLEN];
  6880. TCHAR option2[CONFIG_BLEN], value2[CONFIG_BLEN];
  6881. TCHAR *tmp, *p, *nextp;
  6882. struct zfile *configstore = NULL;
  6883. int cnt = 0, cnt_ok = 0;
  6884. if (!mode) {
  6885. TCHAR zero = 0;
  6886. configstore = zfile_fopen_empty ("configstore", 50000);
  6887. cfgfile_save_options (configstore, &currprefs, 0);
  6888. cfg_write (&zero, configstore);
  6889. }
  6890. nextp = NULL;
  6891. tmp = p = xcalloc (TCHAR, _tcslen (custom) + 2);
  6892. _tcscpy (tmp, custom);
  6893. while (p && *p) {
  6894. if (*p == '\"') {
  6895. TCHAR *p2;
  6896. p++;
  6897. p2 = p;
  6898. while (*p2 != '\"' && *p2 != 0)
  6899. p2++;
  6900. if (*p2 == '\"') {
  6901. *p2++ = 0;
  6902. nextp = p2 + 1;
  6903. if (*nextp == ' ')
  6904. nextp++;
  6905. }
  6906. }
  6907. if (cfgfile_separate_line (p, option, value)) {
  6908. cnt++;
  6909. if (mode) {
  6910. cfgfile_parse_option (&changed_prefs, option, value, 0);
  6911. } else {
  6912. zfile_fseek (configstore, 0, SEEK_SET);
  6913. for (;;) {
  6914. if (!getconfigstoreline (configstore, option2, value2))
  6915. break;
  6916. if (!_tcscmpi (option, option2) && !_tcscmpi (value, value2)) {
  6917. cnt_ok++;
  6918. break;
  6919. }
  6920. }
  6921. }
  6922. }
  6923. p = nextp;
  6924. }
  6925. xfree (tmp);
  6926. zfile_fclose (configstore);
  6927. if (cnt > 0 && cnt == cnt_ok)
  6928. return 1;
  6929. return 0;
  6930. }
  6931. #endif
  6932. int cmdlineparser (const TCHAR *s, TCHAR *outp[], int max)
  6933. {
  6934. int j, cnt = 0;
  6935. int slash = 0;
  6936. int quote = 0;
  6937. TCHAR tmp1[MAX_DPATH];
  6938. const TCHAR *prev;
  6939. int doout;
  6940. doout = 0;
  6941. prev = s;
  6942. j = 0;
  6943. outp[0] = 0;
  6944. tmp1[0] = 0;
  6945. while (cnt < max) {
  6946. TCHAR c = *s++;
  6947. if (!c)
  6948. break;
  6949. if (c < 32)
  6950. continue;
  6951. if (c == '\\')
  6952. slash = 1;
  6953. if (!slash && c == '"') {
  6954. if (quote) {
  6955. quote = 0;
  6956. doout = 1;
  6957. } else {
  6958. quote = 1;
  6959. j = -1;
  6960. }
  6961. }
  6962. if (!quote && c == ' ')
  6963. doout = 1;
  6964. if (!doout) {
  6965. if (j >= 0) {
  6966. tmp1[j] = c;
  6967. tmp1[j + 1] = 0;
  6968. }
  6969. j++;
  6970. }
  6971. if (doout) {
  6972. if (_tcslen (tmp1) > 0) {
  6973. outp[cnt++] = my_strdup (tmp1);
  6974. outp[cnt] = 0;
  6975. }
  6976. tmp1[0] = 0;
  6977. doout = 0;
  6978. j = 0;
  6979. }
  6980. slash = 0;
  6981. }
  6982. if (j > 0 && cnt < max) {
  6983. outp[cnt++] = my_strdup (tmp1);
  6984. outp[cnt] = 0;
  6985. }
  6986. return cnt;
  6987. }
  6988. #define UAELIB_MAX_PARSE 100
  6989. static bool cfgfile_parse_uaelib_option (struct uae_prefs *p, TCHAR *option, TCHAR *value, int type)
  6990. {
  6991. return false;
  6992. }
  6993. int cfgfile_searchconfig(const TCHAR *in, int index, TCHAR *out, int outsize)
  6994. {
  6995. TCHAR tmp[CONFIG_BLEN];
  6996. int j = 0;
  6997. int inlen = _tcslen (in);
  6998. int joker = 0;
  6999. uae_u32 err = 0;
  7000. bool configsearchfound = false;
  7001. int index2 = index;
  7002. if (in[inlen - 1] == '*') {
  7003. joker = 1;
  7004. inlen--;
  7005. }
  7006. *out = 0;
  7007. if (!configstore)
  7008. cfgfile_createconfigstore(&currprefs);
  7009. if (!configstore)
  7010. return 20;
  7011. if (index < 0) {
  7012. index = 0;
  7013. zfile_fseek(configstore, 0, SEEK_SET);
  7014. } else {
  7015. // if seek position==0: configstore was reset, always start from the beginning.
  7016. if (zfile_ftell(configstore) > 0)
  7017. index = 0;
  7018. }
  7019. tmp[0] = 0;
  7020. for (;;) {
  7021. uae_u8 b = 0;
  7022. if (zfile_fread (&b, 1, 1, configstore) != 1) {
  7023. err = 10;
  7024. if (configsearchfound || index2 > 0)
  7025. err = 0;
  7026. goto end;
  7027. }
  7028. if (j >= sizeof (tmp) / sizeof (TCHAR) - 1)
  7029. j = sizeof (tmp) / sizeof (TCHAR) - 1;
  7030. if (b == 0) {
  7031. err = 10;
  7032. if (configsearchfound || index2 > 0)
  7033. err = 0;
  7034. goto end;
  7035. }
  7036. if (b == '\n') {
  7037. if (!_tcsncmp (tmp, in, inlen) && ((inlen > 0 && _tcslen (tmp) > inlen && tmp[inlen] == '=') || (joker))) {
  7038. if (index <= 0) {
  7039. TCHAR *p;
  7040. if (joker)
  7041. p = tmp - 1;
  7042. else
  7043. p = _tcschr(tmp, '=');
  7044. if (p) {
  7045. for (int i = 0; out && i < outsize - 1; i++) {
  7046. TCHAR b = *++p;
  7047. out[i] = b;
  7048. out[i + 1] = 0;
  7049. if (!b)
  7050. break;
  7051. }
  7052. }
  7053. err = 0xffffffff;
  7054. configsearchfound = true;
  7055. goto end;
  7056. } else {
  7057. index--;
  7058. }
  7059. }
  7060. j = 0;
  7061. } else {
  7062. tmp[j++] = b;
  7063. tmp[j] = 0;
  7064. }
  7065. }
  7066. end:
  7067. return err;
  7068. }
  7069. static void shellexec_cb(uae_u32 id, uae_u32 status, uae_u32 flags, const char *outbuf, void *userdata)
  7070. {
  7071. if (flags & 1) {
  7072. write_log("Return status code: %d\n", status);
  7073. }
  7074. if (flags & 2) {
  7075. if (outbuf) {
  7076. write_log("%s\n", outbuf);
  7077. }
  7078. }
  7079. }
  7080. static int execcmdline(struct uae_prefs *prefs, int argv, TCHAR **argc, TCHAR *out, int outsize, bool confonly)
  7081. {
  7082. int ret = 0;
  7083. bool changed = false;
  7084. for (int i = 0; i < argv; i++) {
  7085. if (i + 2 <= argv) {
  7086. if (!confonly) {
  7087. if (!_tcsicmp(argc[i], _T("shellexec"))) {
  7088. TCHAR *cmd = argc[i + 1];
  7089. uae_u32 flags = 0;
  7090. i++;
  7091. while (argv > i + 1) {
  7092. TCHAR *next = argc[i + 1];
  7093. if (!_tcsicmp(next, _T("out"))) {
  7094. flags |= 2;
  7095. }
  7096. if (!_tcsicmp(next, _T("res"))) {
  7097. flags |= 1;
  7098. }
  7099. }
  7100. filesys_shellexecute2(cmd, NULL, NULL, 0, 0, 0, flags, NULL, 0, shellexec_cb, NULL);
  7101. } else if (!_tcsicmp(argc[i], _T("dbg"))) {
  7102. debug_parser(argc[i + 1], out, outsize);
  7103. } else if (!inputdevice_uaelib(argc[i], argc[i + 1])) {
  7104. if (!cfgfile_parse_uaelib_option(prefs, argc[i], argc[i + 1], 0)) {
  7105. if (!cfgfile_parse_option(prefs, argc[i], argc[i + 1], 0)) {
  7106. ret = 5;
  7107. break;
  7108. }
  7109. }
  7110. changed = true;
  7111. }
  7112. } else {
  7113. if (!cfgfile_parse_option(prefs, argc[i], argc[i + 1], 0)) {
  7114. ret = 5;
  7115. break;
  7116. }
  7117. changed = true;
  7118. }
  7119. i++;
  7120. }
  7121. }
  7122. if (changed) {
  7123. inputdevice_fix_prefs(prefs, false);
  7124. set_config_changed();
  7125. set_special(SPCFLAG_MODE_CHANGE);
  7126. }
  7127. return 0;
  7128. }
  7129. uae_u32 cfgfile_modify (uae_u32 index, const TCHAR *parms, uae_u32 size, TCHAR *out, uae_u32 outsize)
  7130. {
  7131. TCHAR *p;
  7132. TCHAR *argc[UAELIB_MAX_PARSE];
  7133. int argv, i;
  7134. uae_u32 err;
  7135. static TCHAR *configsearch;
  7136. if (out)
  7137. *out = 0;
  7138. err = 0;
  7139. argv = 0;
  7140. p = 0;
  7141. if (index != 0xffffffff) {
  7142. if (!configstore) {
  7143. err = 20;
  7144. goto end;
  7145. }
  7146. if (configsearch) {
  7147. err = cfgfile_searchconfig(configsearch, index, out, outsize);
  7148. goto end;
  7149. }
  7150. err = 0xffffffff;
  7151. for (i = 0; out && i < outsize - 1; i++) {
  7152. uae_u8 b = 0;
  7153. if (zfile_fread (&b, 1, 1, configstore) != 1)
  7154. err = 0;
  7155. if (b == 0)
  7156. err = 0;
  7157. if (b == '\n')
  7158. b = 0;
  7159. out[i] = b;
  7160. out[i + 1] = 0;
  7161. if (!b)
  7162. break;
  7163. }
  7164. goto end;
  7165. }
  7166. if (size > 10000)
  7167. return 10;
  7168. argv = cmdlineparser (parms, argc, UAELIB_MAX_PARSE);
  7169. if (argv <= 1 && index == 0xffffffff) {
  7170. cfgfile_createconfigstore (&currprefs);
  7171. xfree (configsearch);
  7172. configsearch = NULL;
  7173. if (!configstore) {
  7174. err = 20;
  7175. goto end;
  7176. }
  7177. if (argv > 0 && _tcslen (argc[0]) > 0)
  7178. configsearch = my_strdup (argc[0]);
  7179. err = 0xffffffff;
  7180. goto end;
  7181. }
  7182. err = execcmdline(&changed_prefs, argv, argc, out, outsize, false);
  7183. end:
  7184. for (i = 0; i < argv; i++)
  7185. xfree (argc[i]);
  7186. xfree (p);
  7187. return err;
  7188. }
  7189. uae_u32 cfgfile_uaelib_modify(TrapContext *ctx, uae_u32 index, uae_u32 parms, uae_u32 size, uae_u32 out, uae_u32 outsize)
  7190. {
  7191. uae_char *p, *parms_p = NULL, *parms_out = NULL;
  7192. int i, ret;
  7193. TCHAR *out_p = NULL, *parms_in = NULL;
  7194. if (outsize >= 32768)
  7195. return 0;
  7196. if (out && outsize > 0) {
  7197. if (!trap_valid_address(ctx, out, 1))
  7198. return 0;
  7199. trap_put_byte(ctx, out, 0);
  7200. }
  7201. if (size == 0) {
  7202. for (;;) {
  7203. if (!trap_valid_address(ctx, parms + size, 1))
  7204. return 0;
  7205. if (trap_get_byte(ctx, parms + size) == 0)
  7206. break;
  7207. size++;
  7208. if (size >= 32768)
  7209. return 0;
  7210. }
  7211. }
  7212. parms_p = xmalloc (uae_char, size + 1);
  7213. if (!parms_p) {
  7214. ret = 10;
  7215. goto end;
  7216. }
  7217. if (out) {
  7218. out_p = xmalloc (TCHAR, outsize + 1);
  7219. if (!out_p) {
  7220. ret = 10;
  7221. goto end;
  7222. }
  7223. out_p[0] = 0;
  7224. }
  7225. p = parms_p;
  7226. for (i = 0; i < size; i++) {
  7227. p[i] = trap_get_byte(ctx, parms + i);
  7228. if (p[i] == 10 || p[i] == 13 || p[i] == 0)
  7229. break;
  7230. }
  7231. p[i] = 0;
  7232. parms_in = au (parms_p);
  7233. ret = cfgfile_modify (index, parms_in, size, out_p, outsize);
  7234. xfree (parms_in);
  7235. if (out && outsize > 0) {
  7236. parms_out = ua (out_p);
  7237. if (!trap_valid_address(ctx, out, strlen(parms_out) + 1 > outsize ? outsize : strlen(parms_out) + 1))
  7238. return 0;
  7239. trap_put_string(ctx, parms_out, out, outsize - 1);
  7240. }
  7241. xfree (parms_out);
  7242. end:
  7243. xfree (out_p);
  7244. xfree (parms_p);
  7245. return ret;
  7246. }
  7247. static const TCHAR *cfgfile_read_config_value (const TCHAR *option)
  7248. {
  7249. struct strlist *sl;
  7250. for (sl = currprefs.all_lines; sl; sl = sl->next) {
  7251. if (sl->option && !strcasecmp (sl->option, option))
  7252. return sl->value;
  7253. }
  7254. return NULL;
  7255. }
  7256. uae_u32 cfgfile_uaelib(TrapContext *ctx, int mode, uae_u32 name, uae_u32 dst, uae_u32 maxlen)
  7257. {
  7258. TCHAR *str;
  7259. uae_char tmpa[CONFIG_BLEN];
  7260. if (mode || maxlen > CONFIG_BLEN)
  7261. return 0;
  7262. if (!trap_valid_string(ctx, name, CONFIG_BLEN))
  7263. return 0;
  7264. if (!trap_valid_address(ctx, dst, maxlen))
  7265. return 0;
  7266. trap_get_string(ctx, tmpa, name, sizeof tmpa);
  7267. str = au(tmpa);
  7268. if (str[0] == 0) {
  7269. xfree(str);
  7270. return 0;
  7271. }
  7272. const TCHAR *value = cfgfile_read_config_value(str);
  7273. xfree(str);
  7274. if (value) {
  7275. char *s = ua(value);
  7276. trap_put_string(ctx, s, dst, maxlen);
  7277. xfree (s);
  7278. return dst;
  7279. }
  7280. return 0;
  7281. }
  7282. uae_u8 *restore_configuration (uae_u8 *src)
  7283. {
  7284. struct uae_prefs *p = &currprefs;
  7285. TCHAR *sp = au ((char*)src);
  7286. TCHAR *s = sp;
  7287. for (;;) {
  7288. TCHAR option[MAX_DPATH];
  7289. TCHAR value[MAX_DPATH];
  7290. TCHAR tmp[MAX_DPATH];
  7291. TCHAR *ss = s;
  7292. while (*s && *s != 10 && *s != 13)
  7293. s++;
  7294. if (*s == 0) {
  7295. xfree(sp);
  7296. return src += strlen((char*)src) + 1;
  7297. }
  7298. *s++ = 0;
  7299. while (*s == 10 || *s == 13)
  7300. s++;
  7301. if (cfgfile_separate_line(ss, option, value)) {
  7302. if (!_tcsncmp(option, _T("diskimage"), 9)) {
  7303. for (int i = 0; i < MAX_SPARE_DRIVES; i++) {
  7304. _stprintf(tmp, _T("diskimage%d"), i);
  7305. if (!_tcscmp(option, tmp)) {
  7306. cfgfile_string(option, value, tmp, p->dfxlist[i], sizeof p->dfxlist[i] / sizeof(TCHAR));
  7307. break;
  7308. }
  7309. }
  7310. }
  7311. }
  7312. }
  7313. }
  7314. uae_u8 *save_configuration (int *len, bool fullconfig)
  7315. {
  7316. int tmpsize = 100000;
  7317. uae_u8 *dstbak, *dst, *p;
  7318. int index = -1;
  7319. dstbak = dst = xcalloc (uae_u8, tmpsize);
  7320. p = dst;
  7321. for (;;) {
  7322. TCHAR tmpout[1000];
  7323. int ret;
  7324. tmpout[0] = 0;
  7325. ret = cfgfile_modify (index, _T("*"), 1, tmpout, sizeof (tmpout) / sizeof (TCHAR));
  7326. index++;
  7327. if (_tcslen (tmpout) > 0) {
  7328. char *out;
  7329. if (!fullconfig && !_tcsncmp (tmpout, _T("input."), 6))
  7330. continue;
  7331. //write_log (_T("'%s'\n"), tmpout);
  7332. out = uutf8 (tmpout);
  7333. strcpy ((char*)p, out);
  7334. xfree (out);
  7335. strcat ((char*)p, "\n");
  7336. p += strlen ((char*)p);
  7337. if (p - dstbak >= tmpsize - sizeof (tmpout))
  7338. break;
  7339. }
  7340. if (ret >= 0)
  7341. break;
  7342. }
  7343. *len = p - dstbak + 1;
  7344. return dstbak;
  7345. }
  7346. #ifdef UAE_MINI
  7347. static void default_prefs_mini (struct uae_prefs *p, int type)
  7348. {
  7349. _tcscpy (p->description, _T("UAE default A500 configuration"));
  7350. p->nr_floppies = 1;
  7351. p->floppyslots[0].dfxtype = DRV_35_DD;
  7352. p->floppyslots[1].dfxtype = DRV_NONE;
  7353. p->cpu_model = 68000;
  7354. p->address_space_24 = 1;
  7355. p->chipmem.size = 0x00080000;
  7356. p->bogomem.size = 0x00080000;
  7357. }
  7358. #endif
  7359. #include "sounddep/sound.h"
  7360. static void copy_inputdevice_settings(struct uae_input_device *src, struct uae_input_device *dst)
  7361. {
  7362. for (int l = 0; l < MAX_INPUT_DEVICE_EVENTS; l++) {
  7363. for (int i = 0; i < MAX_INPUT_SUB_EVENT_ALL; i++) {
  7364. if (src->custom[l][i]) {
  7365. dst->custom[l][i] = my_strdup(src->custom[l][i]);
  7366. } else {
  7367. dst->custom[l][i] = NULL;
  7368. }
  7369. }
  7370. }
  7371. }
  7372. static void copy_inputdevice_settings_free(struct uae_input_device *src, struct uae_input_device *dst)
  7373. {
  7374. for (int l = 0; l < MAX_INPUT_DEVICE_EVENTS; l++) {
  7375. for (int i = 0; i < MAX_INPUT_SUB_EVENT_ALL; i++) {
  7376. if (dst->custom[l][i] == NULL && src->custom[l][i] == NULL)
  7377. continue;
  7378. // same string in both src and dest: separate them (fixme: this shouldn't happen!)
  7379. if (dst->custom[l][i] == src->custom[l][i]) {
  7380. dst->custom[l][i] = NULL;
  7381. } else {
  7382. if (dst->custom[l][i]) {
  7383. xfree(dst->custom[l][i]);
  7384. dst->custom[l][i] = NULL;
  7385. }
  7386. }
  7387. }
  7388. }
  7389. }
  7390. void copy_prefs(struct uae_prefs *src, struct uae_prefs *dst)
  7391. {
  7392. for (int slot = 0; slot < MAX_INPUT_SETTINGS; slot++) {
  7393. for (int m = 0; m < MAX_INPUT_DEVICES; m++) {
  7394. copy_inputdevice_settings_free(&src->joystick_settings[slot][m], &dst->joystick_settings[slot][m]);
  7395. copy_inputdevice_settings_free(&src->mouse_settings[slot][m], &dst->mouse_settings[slot][m]);
  7396. copy_inputdevice_settings_free(&src->keyboard_settings[slot][m], &dst->keyboard_settings[slot][m]);
  7397. }
  7398. }
  7399. memcpy(dst, src, sizeof(struct uae_prefs));
  7400. for (int slot = 0; slot < MAX_INPUT_SETTINGS; slot++) {
  7401. for (int m = 0; m < MAX_INPUT_DEVICES; m++) {
  7402. copy_inputdevice_settings(&src->joystick_settings[slot][m], &dst->joystick_settings[slot][m]);
  7403. copy_inputdevice_settings(&src->mouse_settings[slot][m], &dst->mouse_settings[slot][m]);
  7404. copy_inputdevice_settings(&src->keyboard_settings[slot][m], &dst->keyboard_settings[slot][m]);
  7405. }
  7406. }
  7407. }
  7408. void default_prefs (struct uae_prefs *p, bool reset, int type)
  7409. {
  7410. int i;
  7411. int roms[] = { 6, 7, 8, 9, 10, 14, 5, 4, 3, 2, 1, -1 };
  7412. TCHAR zero = 0;
  7413. struct zfile *f;
  7414. reset_inputdevice_config (p, reset);
  7415. memset (p, 0, sizeof (*p));
  7416. _tcscpy (p->description, _T("UAE default configuration"));
  7417. p->config_hardware_path[0] = 0;
  7418. p->config_host_path[0] = 0;
  7419. p->gfx_scandoubler = false;
  7420. p->start_gui = true;
  7421. p->start_debugger = false;
  7422. p->all_lines = 0;
  7423. /* Note to porters: please don't change any of these options! UAE is supposed
  7424. * to behave identically on all platforms if possible.
  7425. * (TW says: maybe it is time to update default config..) */
  7426. p->illegal_mem = 0;
  7427. p->use_serial = 0;
  7428. p->serial_demand = 0;
  7429. p->serial_hwctsrts = 1;
  7430. p->serial_stopbits = 0;
  7431. p->parallel_demand = 0;
  7432. p->parallel_matrix_emulation = 0;
  7433. p->parallel_postscript_emulation = 0;
  7434. p->parallel_postscript_detection = 0;
  7435. p->parallel_autoflush_time = 5;
  7436. p->ghostscript_parameters[0] = 0;
  7437. p->uae_hide = 0;
  7438. p->uae_hide_autoconfig = false;
  7439. p->z3_mapping_mode = Z3MAPPING_AUTO;
  7440. p->mountitems = 0;
  7441. for (i = 0; i < MOUNT_CONFIG_SIZE; i++) {
  7442. p->mountconfig[i].configoffset = -1;
  7443. p->mountconfig[i].unitnum = -1;
  7444. }
  7445. p->jports[0].id = -1;
  7446. p->jports[1].id = -1;
  7447. p->jports[2].id = -1;
  7448. p->jports[3].id = -1;
  7449. if (reset) {
  7450. inputdevice_joyport_config_store(p, _T("mouse"), 0, -1, -1, 0);
  7451. inputdevice_joyport_config_store(p, _T("kbd1"), 1, -1, -1, 0);
  7452. }
  7453. p->keyboard_lang = KBD_LANG_US;
  7454. p->keyboard_connected = true;
  7455. p->produce_sound = 3;
  7456. p->sound_stereo = SND_STEREO;
  7457. p->sound_stereo_separation = 7;
  7458. p->sound_mixed_stereo_delay = 0;
  7459. p->sound_freq = DEFAULT_SOUND_FREQ;
  7460. p->sound_maxbsiz = DEFAULT_SOUND_MAXB;
  7461. p->sound_interpol = 1;
  7462. p->sound_filter = FILTER_SOUND_EMUL;
  7463. p->sound_filter_type = 0;
  7464. p->sound_auto = 1;
  7465. p->sound_cdaudio = false;
  7466. p->sampler_stereo = false;
  7467. p->sampler_buffer = 0;
  7468. p->sampler_freq = 0;
  7469. p->comptrustbyte = 0;
  7470. p->comptrustword = 0;
  7471. p->comptrustlong = 0;
  7472. p->comptrustnaddr= 0;
  7473. p->compnf = 1;
  7474. p->comp_hardflush = 0;
  7475. p->comp_constjump = 1;
  7476. #ifdef USE_JIT_FPU
  7477. p->compfpu = 1;
  7478. #else
  7479. p->compfpu = 0;
  7480. #endif
  7481. p->comp_catchfault = true;
  7482. p->cachesize = 0;
  7483. p->gfx_framerate = 1;
  7484. p->gfx_autoframerate = 50;
  7485. p->gfx_monitor[0].gfx_size_fs.width = 800;
  7486. p->gfx_monitor[0].gfx_size_fs.height = 600;
  7487. p->gfx_monitor[0].gfx_size_win.width = 720;
  7488. p->gfx_monitor[0].gfx_size_win.height = 568;
  7489. for (i = 0; i < GFX_SIZE_EXTRA_NUM; i++) {
  7490. p->gfx_monitor[0].gfx_size_fs_xtra[i].width = 0;
  7491. p->gfx_monitor[0].gfx_size_fs_xtra[i].height = 0;
  7492. p->gfx_monitor[0].gfx_size_win_xtra[i].width = 0;
  7493. p->gfx_monitor[0].gfx_size_win_xtra[i].height = 0;
  7494. }
  7495. p->gfx_resolution = RES_HIRES;
  7496. p->gfx_vresolution = VRES_DOUBLE;
  7497. p->gfx_iscanlines = 1;
  7498. p->gfx_apmode[0].gfx_fullscreen = GFX_WINDOW;
  7499. p->gfx_apmode[1].gfx_fullscreen = GFX_WINDOW;
  7500. p->gfx_xcenter = 0; p->gfx_ycenter = 0;
  7501. p->gfx_xcenter_pos = -1;
  7502. p->gfx_ycenter_pos = -1;
  7503. p->gfx_xcenter_size = -1;
  7504. p->gfx_ycenter_size = -1;
  7505. p->gfx_max_horizontal = RES_HIRES;
  7506. p->gfx_max_vertical = VRES_DOUBLE;
  7507. p->gfx_autoresolution_minv = 0;
  7508. p->gfx_autoresolution_minh = 0;
  7509. p->color_mode = 2;
  7510. p->gfx_blackerthanblack = 0;
  7511. p->gfx_autoresolution_vga = true;
  7512. p->gfx_apmode[0].gfx_backbuffers = 2;
  7513. p->gfx_apmode[1].gfx_backbuffers = 1;
  7514. p->gfx_display_sections = 4;
  7515. p->gfx_variable_sync = 0;
  7516. p->gfx_windowed_resize = true;
  7517. p->gfx_overscanmode = 3;
  7518. p->immediate_blits = 0;
  7519. p->waiting_blits = 0;
  7520. p->collision_level = 2;
  7521. p->leds_on_screen = 0;
  7522. p->leds_on_screen_mask[0] = p->leds_on_screen_mask[1] = (1 << LED_MAX) - 1;
  7523. p->keyboard_leds_in_use = 0;
  7524. p->keyboard_leds[0] = p->keyboard_leds[1] = p->keyboard_leds[2] = 0;
  7525. p->scsi = 0;
  7526. p->uaeserial = 0;
  7527. p->cpu_idle = 0;
  7528. p->turbo_emulation = 0;
  7529. p->turbo_emulation_limit = 0;
  7530. p->headless = 0;
  7531. p->catweasel = 0;
  7532. p->tod_hack = 0;
  7533. p->maprom = 0;
  7534. p->boot_rom = 0;
  7535. p->filesys_no_uaefsdb = 0;
  7536. p->filesys_custom_uaefsdb = 1;
  7537. p->picasso96_nocustom = 1;
  7538. p->cart_internal = 1;
  7539. p->sana2 = 0;
  7540. p->clipboard_sharing = false;
  7541. p->native_code = false;
  7542. p->lightpen_crosshair = true;
  7543. p->cs_compatible = CP_GENERIC;
  7544. p->cs_rtc = 2;
  7545. p->cs_df0idhw = 1;
  7546. p->cs_a1000ram = 0;
  7547. p->cs_fatgaryrev = -1;
  7548. p->cs_ramseyrev = -1;
  7549. p->cs_agnusrev = -1;
  7550. p->cs_deniserev = -1;
  7551. p->cs_mbdmac = 0;
  7552. p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = p->cs_cd32fmv = false;
  7553. p->cs_cd32nvram_size = 1024;
  7554. p->cs_cdtvcd = p->cs_cdtvram = false;
  7555. p->cs_pcmcia = 0;
  7556. p->cs_ksmirror_e0 = 1;
  7557. p->cs_ksmirror_a8 = 0;
  7558. p->cs_ciaoverlay = 1;
  7559. p->cs_ciaatod = 0;
  7560. p->cs_df0idhw = 1;
  7561. p->cs_slowmemisfast = 0;
  7562. p->cs_resetwarning = 1;
  7563. p->cs_ciatodbug = false;
  7564. p->cs_unmapped_space = 0;
  7565. p->cs_color_burst = false;
  7566. p->cs_ciatype[0] = 0;
  7567. p->cs_ciatype[1] = 0;
  7568. for (int i = APMODE_NATIVE; i <= APMODE_RTG; i++) {
  7569. struct gfx_filterdata *f = &p->gf[i];
  7570. f->gfx_filter = 0;
  7571. f->gfx_filter_scanlineratio = (1 << 4) | 1;
  7572. f->gfx_filter_scanlineoffset = 1;
  7573. for (int j = 0; j <= 2 * MAX_FILTERSHADERS; j++) {
  7574. f->gfx_filtershader[i][0] = 0;
  7575. f->gfx_filtermask[i][0] = 0;
  7576. }
  7577. f->gfx_filter_horiz_zoom_mult = 1.0;
  7578. f->gfx_filter_vert_zoom_mult = 1.0;
  7579. f->gfx_filter_bilinear = 0;
  7580. f->gfx_filter_filtermodeh = 0;
  7581. f->gfx_filter_filtermodev = 0;
  7582. f->gfx_filter_keep_aspect = 0;
  7583. f->gfx_filter_autoscale = AUTOSCALE_STATIC_AUTO;
  7584. f->gfx_filter_keep_autoscale_aspect = false;
  7585. f->gfx_filteroverlay_overscan = 0;
  7586. f->gfx_filter_left_border = -1;
  7587. f->gfx_filter_top_border = -1;
  7588. }
  7589. p->rtg_horiz_zoom_mult = 1.0;
  7590. p->rtg_vert_zoom_mult = 1.0;
  7591. _tcscpy (p->floppyslots[0].df, _T("df0.adf"));
  7592. _tcscpy (p->floppyslots[1].df, _T("df1.adf"));
  7593. _tcscpy (p->floppyslots[2].df, _T("df2.adf"));
  7594. _tcscpy (p->floppyslots[3].df, _T("df3.adf"));
  7595. for (int i = 0; i < MAX_LUA_STATES; i++) {
  7596. p->luafiles[i][0] = 0;
  7597. }
  7598. configure_rom (p, roms, 0);
  7599. _tcscpy (p->romextfile, _T(""));
  7600. _tcscpy (p->romextfile2, _T(""));
  7601. p->romextfile2addr = 0;
  7602. _tcscpy (p->flashfile, _T(""));
  7603. _tcscpy (p->cartfile, _T(""));
  7604. _tcscpy (p->rtcfile, _T(""));
  7605. _tcscpy (p->path_rom.path[0], _T("./"));
  7606. _tcscpy (p->path_floppy.path[0], _T("./"));
  7607. _tcscpy (p->path_hardfile.path[0], _T("./"));
  7608. p->prtname[0] = 0;
  7609. p->sername[0] = 0;
  7610. p->cpu_thread = false;
  7611. p->fpu_model = 0;
  7612. p->cpu_model = 68000;
  7613. p->m68k_speed_throttle = 0;
  7614. p->cpu_clock_multiplier = 0;
  7615. p->cpu_frequency = 0;
  7616. p->mmu_model = 0;
  7617. p->cpu060_revision = 6;
  7618. p->fpu_revision = 0;
  7619. p->fpu_no_unimplemented = false;
  7620. p->int_no_unimplemented = false;
  7621. p->fpu_strict = 0;
  7622. p->fpu_mode = 0;
  7623. p->m68k_speed = 0;
  7624. p->cpu_compatible = 1;
  7625. p->address_space_24 = 1;
  7626. p->cpu_cycle_exact = 0;
  7627. p->cpu_memory_cycle_exact = 0;
  7628. p->blitter_cycle_exact = 0;
  7629. p->chipset_mask = CSMASK_ECS_AGNUS;
  7630. p->chipset_hr = false;
  7631. p->genlock = 0;
  7632. p->genlock_image = 0;
  7633. p->genlock_mix = 0;
  7634. p->ntscmode = 0;
  7635. p->filesys_limit = 0;
  7636. p->filesys_max_name = 107;
  7637. p->filesys_max_file_size = 0x7fffffff;
  7638. p->z3autoconfig_start = 0x10000000;
  7639. p->chipmem.size = 0x00080000;
  7640. p->bogomem.size = 0x00080000;
  7641. for (int i = 0; i < MAX_RTG_BOARDS; i++) {
  7642. p->rtgboards[i].rtg_index = i;
  7643. }
  7644. p->rtgboards[0].rtgmem_size = 0x00000000;
  7645. p->rtgboards[0].rtgmem_type = GFXBOARD_UAE_Z3;
  7646. p->custom_memory_addrs[0] = 0;
  7647. p->custom_memory_sizes[0] = 0;
  7648. p->custom_memory_addrs[1] = 0;
  7649. p->custom_memory_sizes[1] = 0;
  7650. p->nr_floppies = 2;
  7651. p->floppy_read_only = false;
  7652. p->floppyslots[0].dfxtype = DRV_35_DD;
  7653. p->floppyslots[1].dfxtype = DRV_35_DD;
  7654. p->floppyslots[2].dfxtype = DRV_NONE;
  7655. p->floppyslots[3].dfxtype = DRV_NONE;
  7656. p->floppy_speed = 100;
  7657. p->floppy_write_length = 0;
  7658. p->floppy_random_bits_min = 1;
  7659. p->floppy_random_bits_max = 3;
  7660. p->dfxclickvolume_disk[0] = 33;
  7661. p->dfxclickvolume_disk[1] = 33;
  7662. p->dfxclickvolume_disk[2] = 33;
  7663. p->dfxclickvolume_disk[3] = 33;
  7664. p->dfxclickvolume_empty[0] = 33;
  7665. p->dfxclickvolume_empty[1] = 33;
  7666. p->dfxclickvolume_empty[2] = 33;
  7667. p->dfxclickvolume_empty[3] = 33;
  7668. p->dfxclickchannelmask = 0xffff;
  7669. p->cd_speed = 100;
  7670. p->statecapturebuffersize = 100;
  7671. p->statecapturerate = 5 * 50;
  7672. p->inprec_autoplay = true;
  7673. #ifdef UAE_MINI
  7674. default_prefs_mini (p, 0);
  7675. #endif
  7676. p->input_tablet = TABLET_OFF;
  7677. p->tablet_library = false;
  7678. p->input_mouse_untrap = MOUSEUNTRAP_MIDDLEBUTTON;
  7679. p->input_magic_mouse_cursor = 0;
  7680. inputdevice_default_prefs (p);
  7681. blkdev_default_prefs (p);
  7682. p->cr_selected = -1;
  7683. struct chipset_refresh *cr;
  7684. for (int i = 0; i < MAX_CHIPSET_REFRESH_TOTAL; i++) {
  7685. cr = &p->cr[i];
  7686. cr->index = i;
  7687. cr->rate = -1;
  7688. }
  7689. cr = &p->cr[CHIPSET_REFRESH_PAL];
  7690. cr->index = CHIPSET_REFRESH_PAL;
  7691. cr->horiz = -1;
  7692. cr->vert = -1;
  7693. cr->lace = -1;
  7694. cr->vsync = - 1;
  7695. cr->framelength = -1;
  7696. cr->rate = 50.0;
  7697. cr->ntsc = 0;
  7698. cr->locked = false;
  7699. cr->inuse = true;
  7700. _tcscpy (cr->label, _T("PAL"));
  7701. cr = &p->cr[CHIPSET_REFRESH_NTSC];
  7702. cr->index = CHIPSET_REFRESH_NTSC;
  7703. cr->horiz = -1;
  7704. cr->vert = -1;
  7705. cr->lace = -1;
  7706. cr->vsync = - 1;
  7707. cr->framelength = -1;
  7708. cr->rate = 60.0;
  7709. cr->ntsc = 1;
  7710. cr->locked = false;
  7711. cr->inuse = true;
  7712. _tcscpy (cr->label, _T("NTSC"));
  7713. p->lightboost_strobo = false;
  7714. p->lightboost_strobo_ratio = 50;
  7715. savestate_state = 0;
  7716. target_default_options (p, type);
  7717. zfile_fclose (default_file);
  7718. default_file = NULL;
  7719. f = zfile_fopen_empty (NULL, _T("configstore"));
  7720. if (f) {
  7721. uaeconfig++;
  7722. cfgfile_save_options (f, p, 0);
  7723. uaeconfig--;
  7724. cfg_write (&zero, f);
  7725. default_file = f;
  7726. }
  7727. }
  7728. static void buildin_default_prefs_68020 (struct uae_prefs *p)
  7729. {
  7730. p->cpu_model = 68020;
  7731. p->address_space_24 = 1;
  7732. p->cpu_compatible = 1;
  7733. p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE | CSMASK_AGA;
  7734. p->chipmem.size = 0x200000;
  7735. p->bogomem.size = 0;
  7736. p->m68k_speed = -1;
  7737. }
  7738. static void buildin_default_host_prefs (struct uae_prefs *p)
  7739. {
  7740. #if 0
  7741. p->sound_filter = FILTER_SOUND_OFF;
  7742. p->sound_stereo = SND_STEREO;
  7743. p->sound_stereo_separation = 7;
  7744. p->sound_mixed_stereo = 0;
  7745. #endif
  7746. }
  7747. static void buildin_default_prefs (struct uae_prefs *p)
  7748. {
  7749. buildin_default_host_prefs (p);
  7750. p->floppyslots[0].dfxtype = DRV_35_DD;
  7751. if (p->nr_floppies != 1 && p->nr_floppies != 2)
  7752. p->nr_floppies = 2;
  7753. p->floppyslots[1].dfxtype = p->nr_floppies >= 2 ? DRV_35_DD : DRV_NONE;
  7754. p->floppyslots[2].dfxtype = DRV_NONE;
  7755. p->floppyslots[3].dfxtype = DRV_NONE;
  7756. p->floppy_speed = 100;
  7757. p->fpu_model = 0;
  7758. p->cpu_model = 68000;
  7759. p->cpu_clock_multiplier = 0;
  7760. p->cpu_frequency = 0;
  7761. p->cpu060_revision = 1;
  7762. p->fpu_revision = -1;
  7763. p->m68k_speed = 0;
  7764. p->cpu_compatible = 1;
  7765. p->address_space_24 = 1;
  7766. p->cpu_cycle_exact = 0;
  7767. p->cpu_memory_cycle_exact = 0;
  7768. p->blitter_cycle_exact = 0;
  7769. p->chipset_mask = CSMASK_ECS_AGNUS;
  7770. p->immediate_blits = 0;
  7771. p->waiting_blits = 0;
  7772. p->collision_level = 2;
  7773. if (p->produce_sound < 1)
  7774. p->produce_sound = 1;
  7775. p->scsi = 0;
  7776. p->uaeserial = 0;
  7777. p->cpu_idle = 0;
  7778. p->turbo_emulation = 0;
  7779. p->turbo_emulation_limit = 0;
  7780. p->catweasel = 0;
  7781. p->tod_hack = 0;
  7782. p->maprom = 0;
  7783. p->cachesize = 0;
  7784. p->socket_emu = 0;
  7785. p->clipboard_sharing = false;
  7786. p->ppc_mode = 0;
  7787. p->ppc_model[0] = 0;
  7788. p->cpuboard_type = 0;
  7789. p->cpuboard_subtype = 0;
  7790. p->chipmem.size = 0x00080000;
  7791. p->bogomem.size = 0x00080000;
  7792. p->z3chipmem.size = 0;
  7793. for (int i = 0; i < MAX_RAM_BOARDS; i++) {
  7794. memset(p->fastmem, 0, sizeof(struct ramboard));
  7795. memset(p->z3fastmem, 0, sizeof(struct ramboard));
  7796. }
  7797. for (int i = 0; i < MAX_RTG_BOARDS; i++) {
  7798. p->rtgboards[i].rtgmem_size = 0x00000000;
  7799. p->rtgboards[i].rtgmem_type = GFXBOARD_UAE_Z3;
  7800. }
  7801. for (int i = 0; i < MAX_EXPANSION_BOARDS; i++) {
  7802. memset(&p->expansionboard[i], 0, sizeof(struct boardromconfig));
  7803. }
  7804. p->cs_rtc = 0;
  7805. p->cs_a1000ram = false;
  7806. p->cs_fatgaryrev = -1;
  7807. p->cs_ramseyrev = -1;
  7808. p->cs_agnusrev = -1;
  7809. p->cs_deniserev = -1;
  7810. p->cs_mbdmac = 0;
  7811. p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = p->cs_cd32fmv = false;
  7812. p->cs_cdtvcd = p->cs_cdtvram = false;
  7813. p->cs_ide = 0;
  7814. p->cs_pcmcia = 0;
  7815. p->cs_ksmirror_e0 = 1;
  7816. p->cs_ksmirror_a8 = 0;
  7817. p->cs_ciaoverlay = 1;
  7818. p->cs_ciaatod = 0;
  7819. p->cs_df0idhw = 1;
  7820. p->cs_resetwarning = 0;
  7821. p->cs_ciatodbug = false;
  7822. p->cs_1mchipjumper = false;
  7823. _tcscpy (p->romextfile, _T(""));
  7824. _tcscpy (p->romextfile2, _T(""));
  7825. p->ne2000pciname[0] = 0;
  7826. p->ne2000pcmcianame[0] = 0;
  7827. p->a2065name[0] = 0;
  7828. p->prtname[0] = 0;
  7829. p->sername[0] = 0;
  7830. p->mountitems = 0;
  7831. p->debug_mem = false;
  7832. target_default_options (p, 1);
  7833. cfgfile_compatibility_romtype(p);
  7834. }
  7835. static void set_68020_compa (struct uae_prefs *p, int compa, int cd32)
  7836. {
  7837. switch (compa)
  7838. {
  7839. case 0:
  7840. p->m68k_speed = 0;
  7841. if ((p->cpu_model == 68020 || p->cpu_model == 68030) && p->cachesize == 0) {
  7842. p->cpu_cycle_exact = 1;
  7843. p->cpu_memory_cycle_exact = 1;
  7844. p->blitter_cycle_exact = 1;
  7845. if (p->cpu_model == 68020)
  7846. p->cpu_clock_multiplier = 4 << 8;
  7847. else
  7848. p->cpu_clock_multiplier = 5 << 8;
  7849. }
  7850. break;
  7851. case 1:
  7852. p->m68k_speed = 0;
  7853. if ((p->cpu_model == 68020 || p->cpu_model == 68030) && p->cachesize == 0) {
  7854. p->blitter_cycle_exact = 1;
  7855. p->cpu_memory_cycle_exact = 1;
  7856. if (p->cpu_model == 68020)
  7857. p->cpu_clock_multiplier = 4 << 8;
  7858. else
  7859. p->cpu_clock_multiplier = 5 << 8;
  7860. }
  7861. break;
  7862. case 2:
  7863. p->cpu_compatible = true;
  7864. p->m68k_speed = 0;
  7865. if (p->cpu_model == 68020)
  7866. p->cpu_clock_multiplier = 4 << 8;
  7867. else
  7868. p->cpu_clock_multiplier = 5 << 8;
  7869. break;
  7870. case 3:
  7871. p->cpu_compatible = 0;
  7872. p->m68k_speed = -1;
  7873. p->address_space_24 = 0;
  7874. break;
  7875. case 4:
  7876. p->cpu_compatible = 0;
  7877. p->address_space_24 = 0;
  7878. p->cachesize = MAX_JIT_CACHE;
  7879. break;
  7880. }
  7881. if (p->cpu_model >= 68030)
  7882. p->address_space_24 = 0;
  7883. }
  7884. /* 0: cycle-exact
  7885. * 1: more compatible
  7886. * 2: no more compatible, no 100% sound
  7887. * 3: no more compatible, waiting blits, no 100% sound
  7888. */
  7889. static void set_68000_compa (struct uae_prefs *p, int compa)
  7890. {
  7891. p->cpu_clock_multiplier = 2 << 8;
  7892. switch (compa)
  7893. {
  7894. case 0:
  7895. p->cpu_cycle_exact = p->cpu_memory_cycle_exact = p->blitter_cycle_exact = 1;
  7896. break;
  7897. case 1:
  7898. break;
  7899. case 2:
  7900. p->cpu_compatible = 0;
  7901. break;
  7902. case 3:
  7903. p->produce_sound = 2;
  7904. p->cpu_compatible = 0;
  7905. break;
  7906. }
  7907. }
  7908. static int bip_a3000 (struct uae_prefs *p, int config, int compa, int romcheck)
  7909. {
  7910. int roms[2];
  7911. if (config == 2)
  7912. roms[0] = 61;
  7913. else if (config == 1)
  7914. roms[0] = 71;
  7915. else
  7916. roms[0] = 59;
  7917. roms[1] = -1;
  7918. p->bogomem.size = 0;
  7919. p->chipmem.size = 0x200000;
  7920. p->cpu_model = 68030;
  7921. p->fpu_model = 68882;
  7922. p->fpu_no_unimplemented = true;
  7923. if (compa == 0)
  7924. p->mmu_model = 68030;
  7925. else
  7926. p->cachesize = MAX_JIT_CACHE;
  7927. p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
  7928. p->cpu_compatible = p->address_space_24 = 0;
  7929. p->m68k_speed = -1;
  7930. p->immediate_blits = 0;
  7931. p->produce_sound = 2;
  7932. p->floppyslots[0].dfxtype = DRV_35_HD;
  7933. p->floppy_speed = 0;
  7934. p->cpu_idle = 150;
  7935. p->cs_compatible = CP_A3000;
  7936. p->mbresmem_low.size = 8 * 1024 * 1024;
  7937. built_in_chipset_prefs (p);
  7938. p->cs_ciaatod = p->ntscmode ? 2 : 1;
  7939. return configure_rom (p, roms, romcheck);
  7940. }
  7941. static int bip_a4000 (struct uae_prefs *p, int config, int compa, int romcheck)
  7942. {
  7943. int roms[8];
  7944. roms[0] = 16;
  7945. roms[1] = 31;
  7946. roms[2] = 13;
  7947. roms[3] = 12;
  7948. roms[4] = -1;
  7949. p->bogomem.size = 0;
  7950. p->chipmem.size = 0x200000;
  7951. p->mbresmem_low.size = 8 * 1024 * 1024;
  7952. p->cpu_model = 68030;
  7953. p->fpu_model = 68882;
  7954. switch (config)
  7955. {
  7956. case 1:
  7957. p->cpu_model = 68040;
  7958. p->fpu_model = 68040;
  7959. break;
  7960. case 2:
  7961. p->cpu_model = 68060;
  7962. p->fpu_model = 68060;
  7963. p->ppc_mode = 1;
  7964. cpuboard_setboard(p, BOARD_CYBERSTORM, BOARD_CYBERSTORM_SUB_PPC);
  7965. p->cpuboardmem1.size = 128 * 1024 * 1024;
  7966. int roms_ppc[] = { 98, -1 };
  7967. configure_rom(p, roms_ppc, romcheck);
  7968. break;
  7969. }
  7970. p->chipset_mask = CSMASK_AGA | CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
  7971. p->cpu_compatible = p->address_space_24 = 0;
  7972. p->m68k_speed = -1;
  7973. p->immediate_blits = 0;
  7974. p->produce_sound = 2;
  7975. p->cachesize = MAX_JIT_CACHE;
  7976. p->floppyslots[0].dfxtype = DRV_35_HD;
  7977. p->floppyslots[1].dfxtype = DRV_35_HD;
  7978. p->floppy_speed = 0;
  7979. p->cpu_idle = 150;
  7980. p->cs_compatible = CP_A4000;
  7981. built_in_chipset_prefs (p);
  7982. p->cs_ciaatod = p->ntscmode ? 2 : 1;
  7983. return configure_rom (p, roms, romcheck);
  7984. }
  7985. static int bip_a4000t (struct uae_prefs *p, int config, int compa, int romcheck)
  7986. {
  7987. int roms[8];
  7988. roms[0] = 16;
  7989. roms[1] = 31;
  7990. roms[2] = 13;
  7991. roms[3] = -1;
  7992. p->bogomem.size = 0;
  7993. p->chipmem.size = 0x200000;
  7994. p->mbresmem_low.size = 8 * 1024 * 1024;
  7995. p->cpu_model = 68030;
  7996. p->fpu_model = 68882;
  7997. if (config > 0) {
  7998. p->cpu_model = 68040;
  7999. p->fpu_model = 68040;
  8000. }
  8001. p->chipset_mask = CSMASK_AGA | CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
  8002. p->cpu_compatible = p->address_space_24 = 0;
  8003. p->m68k_speed = -1;
  8004. p->immediate_blits = 0;
  8005. p->produce_sound = 2;
  8006. p->cachesize = MAX_JIT_CACHE;
  8007. p->floppyslots[0].dfxtype = DRV_35_HD;
  8008. p->floppyslots[1].dfxtype = DRV_35_HD;
  8009. p->floppy_speed = 0;
  8010. p->cpu_idle = 150;
  8011. p->cs_compatible = CP_A4000T;
  8012. built_in_chipset_prefs (p);
  8013. p->cs_ciaatod = p->ntscmode ? 2 : 1;
  8014. return configure_rom (p, roms, romcheck);
  8015. }
  8016. static void bip_velvet(struct uae_prefs *p, int config, int compa, int romcheck)
  8017. {
  8018. p->chipset_mask = 0;
  8019. p->bogomem.size = 0;
  8020. p->sound_filter = FILTER_SOUND_ON;
  8021. set_68000_compa (p, compa);
  8022. p->floppyslots[1].dfxtype = DRV_NONE;
  8023. p->cs_compatible = CP_VELVET;
  8024. p->cs_slowmemisfast = 1;
  8025. p->cs_dipagnus = 1;
  8026. p->cs_agnusbltbusybug = 1;
  8027. built_in_chipset_prefs (p);
  8028. p->cs_denisenoehb = 1;
  8029. p->cs_cia6526 = 1;
  8030. p->chipmem.size = 0x40000;
  8031. }
  8032. static int bip_a1000 (struct uae_prefs *p, int config, int compa, int romcheck)
  8033. {
  8034. int roms[2];
  8035. roms[0] = 24;
  8036. roms[1] = -1;
  8037. p->chipset_mask = 0;
  8038. p->bogomem.size = 0;
  8039. p->sound_filter = FILTER_SOUND_ON;
  8040. set_68000_compa (p, compa);
  8041. p->floppyslots[1].dfxtype = DRV_NONE;
  8042. p->cs_compatible = CP_A1000;
  8043. p->cs_slowmemisfast = 1;
  8044. p->cs_dipagnus = 1;
  8045. p->cs_agnusbltbusybug = 1;
  8046. built_in_chipset_prefs (p);
  8047. if (config > 0)
  8048. p->cs_denisenoehb = 1;
  8049. if (config > 1)
  8050. p->chipmem.size = 0x40000;
  8051. if (config > 2) {
  8052. roms[0] = 125;
  8053. roms[1] = -1;
  8054. bip_velvet(p, config, compa, romcheck);
  8055. }
  8056. return configure_rom (p, roms, romcheck);
  8057. }
  8058. static int bip_cdtvcr (struct uae_prefs *p, int config, int compa, int romcheck)
  8059. {
  8060. int roms[4];
  8061. p->bogomem.size = 0;
  8062. p->chipmem.size = 0x100000;
  8063. p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
  8064. p->cs_cdtvcd = p->cs_cdtvram = true;
  8065. p->cs_cdtvcr = true;
  8066. p->cs_rtc = 1;
  8067. p->nr_floppies = 0;
  8068. p->floppyslots[0].dfxtype = DRV_NONE;
  8069. if (config > 0)
  8070. p->floppyslots[0].dfxtype = DRV_35_DD;
  8071. p->floppyslots[1].dfxtype = DRV_NONE;
  8072. set_68000_compa (p, compa);
  8073. p->cs_compatible = CP_CDTVCR;
  8074. built_in_chipset_prefs (p);
  8075. fetch_datapath (p->flashfile, sizeof (p->flashfile) / sizeof (TCHAR));
  8076. _tcscat (p->flashfile, _T("cdtv-cr.nvr"));
  8077. roms[0] = 9;
  8078. roms[1] = 10;
  8079. roms[2] = -1;
  8080. if (!configure_rom (p, roms, romcheck))
  8081. return 0;
  8082. roms[0] = 108;
  8083. roms[1] = 107;
  8084. roms[2] = -1;
  8085. if (!configure_rom (p, roms, romcheck))
  8086. return 0;
  8087. return 1;
  8088. }
  8089. static int bip_cdtv (struct uae_prefs *p, int config, int compa, int romcheck)
  8090. {
  8091. int roms[4];
  8092. if (config >= 2)
  8093. return bip_cdtvcr(p, config - 2, compa, romcheck);
  8094. p->bogomem.size = 0;
  8095. p->chipmem.size = 0x100000;
  8096. p->chipset_mask = CSMASK_ECS_AGNUS;
  8097. p->cs_cdtvcd = p->cs_cdtvram = 1;
  8098. if (config > 0) {
  8099. addbcromtype(p, ROMTYPE_CDTVSRAM, true, NULL, 0);
  8100. }
  8101. p->cs_rtc = 1;
  8102. p->nr_floppies = 0;
  8103. p->floppyslots[0].dfxtype = DRV_NONE;
  8104. if (config > 0)
  8105. p->floppyslots[0].dfxtype = DRV_35_DD;
  8106. p->floppyslots[1].dfxtype = DRV_NONE;
  8107. set_68000_compa (p, compa);
  8108. p->cs_compatible = CP_CDTV;
  8109. built_in_chipset_prefs (p);
  8110. fetch_datapath (p->flashfile, sizeof (p->flashfile) / sizeof (TCHAR));
  8111. _tcscat (p->flashfile, _T("cdtv.nvr"));
  8112. roms[0] = 6;
  8113. roms[1] = 32;
  8114. roms[2] = -1;
  8115. if (!configure_rom (p, roms, romcheck))
  8116. return 0;
  8117. roms[0] = 20;
  8118. roms[1] = 21;
  8119. roms[2] = 22;
  8120. roms[3] = -1;
  8121. if (!configure_rom (p, roms, romcheck))
  8122. return 0;
  8123. return 1;
  8124. }
  8125. static int bip_cd32 (struct uae_prefs *p, int config, int compa, int romcheck)
  8126. {
  8127. int roms[3];
  8128. buildin_default_prefs_68020 (p);
  8129. p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = true;
  8130. p->nr_floppies = 0;
  8131. p->floppyslots[0].dfxtype = DRV_NONE;
  8132. p->floppyslots[1].dfxtype = DRV_NONE;
  8133. p->cs_unmapped_space = 1;
  8134. set_68020_compa (p, compa, 1);
  8135. p->cs_compatible = CP_CD32;
  8136. built_in_chipset_prefs (p);
  8137. fetch_datapath (p->flashfile, sizeof (p->flashfile) / sizeof (TCHAR));
  8138. _tcscat (p->flashfile, _T("cd32.nvr"));
  8139. roms[0] = 64;
  8140. roms[1] = -1;
  8141. if (!configure_rom (p, roms, 0)) {
  8142. roms[0] = 18;
  8143. roms[1] = -1;
  8144. if (!configure_rom (p, roms, romcheck))
  8145. return 0;
  8146. roms[0] = 19;
  8147. if (!configure_rom (p, roms, romcheck))
  8148. return 0;
  8149. }
  8150. if (config == 1) {
  8151. p->cs_cd32fmv = true;
  8152. roms[0] = 74;
  8153. roms[1] = 23;
  8154. roms[2] = -1;
  8155. if (!configure_rom (p, roms, romcheck))
  8156. return 0;
  8157. } else if (config > 1) {
  8158. addbcromtype(p, ROMTYPE_CUBO, true, NULL, 0);
  8159. }
  8160. return 1;
  8161. }
  8162. static int bip_a1200 (struct uae_prefs *p, int config, int compa, int romcheck)
  8163. {
  8164. int roms[4];
  8165. int roms_bliz[2];
  8166. buildin_default_prefs_68020 (p);
  8167. roms[0] = 11;
  8168. roms[1] = 15;
  8169. roms[2] = 31;
  8170. roms[3] = -1;
  8171. roms_bliz[0] = -1;
  8172. roms_bliz[1] = -1;
  8173. p->cs_rtc = 0;
  8174. p->cs_compatible = CP_A1200;
  8175. built_in_chipset_prefs (p);
  8176. switch (config)
  8177. {
  8178. case 1:
  8179. p->fastmem[0].size = 0x400000;
  8180. p->cs_rtc = 1;
  8181. break;
  8182. case 2:
  8183. cpuboard_setboard(p, BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1230IV);
  8184. p->cpuboardmem1.size = 32 * 1024 * 1024;
  8185. p->cpu_model = 68030;
  8186. p->cs_rtc = 1;
  8187. roms_bliz[0] = 89;
  8188. configure_rom(p, roms_bliz, romcheck);
  8189. break;
  8190. case 3:
  8191. cpuboard_setboard(p, BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1260);
  8192. p->cpuboardmem1.size = 32 * 1024 * 1024;
  8193. p->cpu_model = 68040;
  8194. p->fpu_model = 68040;
  8195. p->cs_rtc = 1;
  8196. roms_bliz[0] = 90;
  8197. configure_rom(p, roms_bliz, romcheck);
  8198. break;
  8199. case 4:
  8200. cpuboard_setboard(p, BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_1260);
  8201. p->cpuboardmem1.size = 32 * 1024 * 1024;
  8202. p->cpu_model = 68060;
  8203. p->fpu_model = 68060;
  8204. p->cs_rtc = 1;
  8205. roms_bliz[0] = 90;
  8206. configure_rom(p, roms_bliz, romcheck);
  8207. break;
  8208. case 5:
  8209. cpuboard_setboard(p, BOARD_BLIZZARD, BOARD_BLIZZARD_SUB_PPC);
  8210. p->cpuboardmem1.size = 256 * 1024 * 1024;
  8211. p->cpu_model = 68060;
  8212. p->fpu_model = 68060;
  8213. p->ppc_mode = 1;
  8214. p->cs_rtc = 1;
  8215. roms[0] = 15;
  8216. roms[1] = 11;
  8217. roms[2] = -1;
  8218. roms_bliz[0] = 100;
  8219. configure_rom(p, roms_bliz, romcheck);
  8220. break;
  8221. }
  8222. set_68020_compa (p, compa, 0);
  8223. return configure_rom (p, roms, romcheck);
  8224. }
  8225. static int bip_a600 (struct uae_prefs *p, int config, int compa, int romcheck)
  8226. {
  8227. int roms[4];
  8228. roms[0] = 10;
  8229. roms[1] = 9;
  8230. roms[2] = 8;
  8231. roms[3] = -1;
  8232. set_68000_compa (p, compa);
  8233. p->cs_compatible = CP_A600;
  8234. built_in_chipset_prefs (p);
  8235. p->bogomem.size = 0;
  8236. p->chipmem.size = 0x100000;
  8237. if (config > 0)
  8238. p->cs_rtc = 1;
  8239. if (config == 1)
  8240. p->chipmem.size = 0x200000;
  8241. if (config == 2)
  8242. p->fastmem[0].size = 0x400000;
  8243. p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
  8244. return configure_rom (p, roms, romcheck);
  8245. }
  8246. static int bip_a500p (struct uae_prefs *p, int config, int compa, int romcheck)
  8247. {
  8248. int roms[2];
  8249. roms[0] = 7;
  8250. roms[1] = -1;
  8251. set_68000_compa (p, compa);
  8252. p->cs_compatible = CP_A500P;
  8253. built_in_chipset_prefs (p);
  8254. p->bogomem.size = 0;
  8255. p->chipmem.size = 0x100000;
  8256. if (config > 0)
  8257. p->cs_rtc = 1;
  8258. if (config == 1)
  8259. p->chipmem.size = 0x200000;
  8260. if (config == 2)
  8261. p->fastmem[0].size = 0x400000;
  8262. p->chipset_mask = CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
  8263. return configure_rom (p, roms, romcheck);
  8264. }
  8265. static int bip_a500 (struct uae_prefs *p, int config, int compa, int romcheck)
  8266. {
  8267. int roms[3];
  8268. roms[0] = roms[1] = roms[2] = -1;
  8269. switch (config)
  8270. {
  8271. case 0: // KS 1.3, OCS Agnus, 0.5M Chip + 0.5M Slow
  8272. roms[0] = 6;
  8273. roms[1] = 32;
  8274. p->chipset_mask = 0;
  8275. break;
  8276. case 1: // KS 1.3, ECS Agnus, 0.5M Chip + 0.5M Slow
  8277. roms[0] = 6;
  8278. roms[1] = 32;
  8279. break;
  8280. case 2: // KS 1.3, ECS Agnus, 1.0M Chip
  8281. roms[0] = 6;
  8282. roms[1] = 32;
  8283. p->bogomem.size = 0;
  8284. p->chipmem.size = 0x100000;
  8285. break;
  8286. case 3: // KS 1.3, OCS Agnus, 0.5M Chip
  8287. roms[0] = 6;
  8288. roms[1] = 32;
  8289. p->bogomem.size = 0;
  8290. p->chipset_mask = 0;
  8291. p->cs_rtc = 0;
  8292. p->floppyslots[1].dfxtype = DRV_NONE;
  8293. break;
  8294. case 4: // KS 1.2, OCS Agnus, 0.5M Chip
  8295. roms[0] = 5;
  8296. roms[1] = 4;
  8297. p->bogomem.size = 0;
  8298. p->chipset_mask = 0;
  8299. p->cs_rtc = 0;
  8300. p->floppyslots[1].dfxtype = DRV_NONE;
  8301. break;
  8302. case 5: // KS 1.2, OCS Agnus, 0.5M Chip + 0.5M Slow
  8303. roms[0] = 5;
  8304. roms[1] = 4;
  8305. p->chipset_mask = 0;
  8306. break;
  8307. }
  8308. set_68000_compa (p, compa);
  8309. p->cs_compatible = CP_A500;
  8310. built_in_chipset_prefs (p);
  8311. return configure_rom (p, roms, romcheck);
  8312. }
  8313. static int bip_super (struct uae_prefs *p, int config, int compa, int romcheck)
  8314. {
  8315. int roms[7];
  8316. roms[0] = 16;
  8317. roms[1] = 31;
  8318. roms[2] = 15;
  8319. roms[3] = 14;
  8320. roms[4] = 12;
  8321. roms[5] = 11;
  8322. roms[6] = -1;
  8323. p->bogomem.size = 0;
  8324. p->chipmem.size = 0x400000;
  8325. p->z3fastmem[0].size = 8 * 1024 * 1024;
  8326. p->rtgboards[0].rtgmem_size = 16 * 1024 * 1024;
  8327. p->cpu_model = 68040;
  8328. p->fpu_model = 68040;
  8329. p->chipset_mask = CSMASK_AGA | CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
  8330. p->cpu_compatible = p->address_space_24 = 0;
  8331. p->m68k_speed = -1;
  8332. p->immediate_blits = 1;
  8333. p->produce_sound = 2;
  8334. p->cachesize = MAX_JIT_CACHE;
  8335. p->floppyslots[0].dfxtype = DRV_35_HD;
  8336. p->floppyslots[1].dfxtype = DRV_35_HD;
  8337. p->floppy_speed = 0;
  8338. p->cpu_idle = 150;
  8339. p->scsi = 1;
  8340. p->uaeserial = 1;
  8341. p->socket_emu = 1;
  8342. p->cart_internal = 0;
  8343. p->picasso96_nocustom = 1;
  8344. p->cs_compatible = 1;
  8345. p->cs_unmapped_space = 1;
  8346. built_in_chipset_prefs (p);
  8347. p->cs_ide = -1;
  8348. p->cs_ciaatod = p->ntscmode ? 2 : 1;
  8349. //_tcscat(p->flashfile, _T("battclock.nvr"));
  8350. return configure_rom (p, roms, romcheck);
  8351. }
  8352. static int bip_arcadia (struct uae_prefs *p, int config, int compa, int romcheck)
  8353. {
  8354. int roms[4], i;
  8355. struct romlist **rl;
  8356. p->bogomem.size = 0;
  8357. p->chipset_mask = 0;
  8358. p->cs_rtc = 0;
  8359. p->nr_floppies = 0;
  8360. p->floppyslots[0].dfxtype = DRV_NONE;
  8361. p->floppyslots[1].dfxtype = DRV_NONE;
  8362. set_68000_compa (p, compa);
  8363. p->cs_compatible = CP_A500;
  8364. built_in_chipset_prefs (p);
  8365. fetch_datapath (p->flashfile, sizeof (p->flashfile) / sizeof (TCHAR));
  8366. _tcscat (p->flashfile, _T("arcadia.nvr"));
  8367. roms[0] = 5;
  8368. roms[1] = 4;
  8369. roms[2] = -1;
  8370. if (!configure_rom (p, roms, romcheck))
  8371. return 0;
  8372. roms[0] = 51;
  8373. roms[1] = 49;
  8374. roms[2] = -1;
  8375. if (!configure_rom (p, roms, romcheck))
  8376. return 0;
  8377. rl = getarcadiaroms ();
  8378. for (i = 0; rl[i]; i++) {
  8379. if (config-- == 0) {
  8380. roms[0] = rl[i]->rd->id;
  8381. roms[1] = -1;
  8382. configure_rom (p, roms, 0);
  8383. break;
  8384. }
  8385. }
  8386. xfree (rl);
  8387. return 1;
  8388. }
  8389. static int bip_casablanca(struct uae_prefs *p, int config, int compa, int romcheck)
  8390. {
  8391. int roms[8];
  8392. roms[0] = 231;
  8393. roms[1] = -1;
  8394. p->bogomem.size = 0;
  8395. p->chipmem.size = 0x200000;
  8396. switch (config)
  8397. {
  8398. default:
  8399. case 1:
  8400. p->cpu_model = 68040;
  8401. p->fpu_model = 68040;
  8402. p->mmu_model = 68040;
  8403. break;
  8404. case 2:
  8405. p->cpu_model = 68060;
  8406. p->fpu_model = 68060;
  8407. p->mmu_model = 68040;
  8408. break;
  8409. }
  8410. p->chipset_mask = CSMASK_AGA | CSMASK_ECS_AGNUS | CSMASK_ECS_DENISE;
  8411. p->cpu_compatible = p->address_space_24 = 0;
  8412. p->m68k_speed = -1;
  8413. p->immediate_blits = 0;
  8414. p->produce_sound = 2;
  8415. p->floppyslots[0].dfxtype = DRV_NONE;
  8416. p->floppyslots[1].dfxtype = DRV_NONE;
  8417. p->cs_compatible = CP_CASABLANCA;
  8418. built_in_chipset_prefs(p);
  8419. return configure_rom(p, roms, romcheck);
  8420. }
  8421. int built_in_prefs (struct uae_prefs *p, int model, int config, int compa, int romcheck)
  8422. {
  8423. int v = 0;
  8424. buildin_default_prefs (p);
  8425. switch (model)
  8426. {
  8427. case 0:
  8428. v = bip_a500 (p, config, compa, romcheck);
  8429. break;
  8430. case 1:
  8431. v = bip_a500p (p, config, compa, romcheck);
  8432. break;
  8433. case 2:
  8434. v = bip_a600 (p, config, compa, romcheck);
  8435. break;
  8436. case 3:
  8437. v = bip_a1000 (p, config, compa, romcheck);
  8438. break;
  8439. case 4:
  8440. v = bip_a1200 (p, config, compa, romcheck);
  8441. break;
  8442. case 5:
  8443. v = bip_a3000 (p, config, compa, romcheck);
  8444. break;
  8445. case 6:
  8446. v = bip_a4000 (p, config, compa, romcheck);
  8447. break;
  8448. case 7:
  8449. v = bip_a4000t (p, config, compa, romcheck);
  8450. break;
  8451. case 8:
  8452. v = bip_cd32 (p, config, compa, romcheck);
  8453. break;
  8454. case 9:
  8455. v = bip_cdtv (p, config, compa, romcheck);
  8456. break;
  8457. case 10:
  8458. v = bip_arcadia(p, config, compa, romcheck);
  8459. break;
  8460. case 11:
  8461. v = bip_casablanca(p, config, compa, romcheck);
  8462. break;
  8463. case 12:
  8464. v = bip_super (p, config, compa, romcheck);
  8465. break;
  8466. }
  8467. if ((p->cpu_model >= 68020 || !p->cpu_cycle_exact || !p->cpu_memory_cycle_exact) && !p->immediate_blits)
  8468. p->waiting_blits = 1;
  8469. if (p->sound_filter_type == FILTER_SOUND_TYPE_A500 && (p->chipset_mask & CSMASK_AGA))
  8470. p->sound_filter_type = FILTER_SOUND_TYPE_A1200;
  8471. else if (p->sound_filter_type == FILTER_SOUND_TYPE_A1200 && !(p->chipset_mask & CSMASK_AGA))
  8472. p->sound_filter_type = FILTER_SOUND_TYPE_A500;
  8473. if (p->cpu_model >= 68040)
  8474. p->cs_bytecustomwritebug = true;
  8475. cfgfile_compatibility_romtype(p);
  8476. return v;
  8477. }
  8478. int built_in_chipset_prefs (struct uae_prefs *p)
  8479. {
  8480. if (!p->cs_compatible)
  8481. return 1;
  8482. p->cs_a1000ram = 0;
  8483. p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = 0;
  8484. p->cs_cdtvcd = p->cs_cdtvram = p->cs_cdtvcr = 0;
  8485. p->cs_fatgaryrev = -1;
  8486. p->cs_ide = 0;
  8487. p->cs_ramseyrev = -1;
  8488. p->cs_deniserev = -1;
  8489. p->cs_agnusrev = -1;
  8490. p->cs_denisenoehb = 0;
  8491. p->cs_dipagnus = 0;
  8492. p->cs_agnusbltbusybug = 0;
  8493. p->cs_bkpthang = 0;
  8494. p->cs_mbdmac = 0;
  8495. p->cs_pcmcia = 0;
  8496. p->cs_ksmirror_e0 = 1;
  8497. p->cs_ksmirror_a8 = 0;
  8498. p->cs_ciaoverlay = 1;
  8499. p->cs_ciaatod = 0;
  8500. p->cs_rtc = 0;
  8501. p->cs_rtc_adjust_mode = p->cs_rtc_adjust = 0;
  8502. p->cs_df0idhw = 1;
  8503. p->cs_resetwarning = 1;
  8504. p->cs_slowmemisfast = 0;
  8505. p->cs_ciatodbug = false;
  8506. p->cs_z3autoconfig = false;
  8507. p->cs_bytecustomwritebug = false;
  8508. p->cs_1mchipjumper = false;
  8509. p->cs_unmapped_space = 0;
  8510. p->cs_color_burst = false;
  8511. p->cs_romisslow = false;
  8512. p->cs_toshibagary = false;
  8513. p->cs_ciatype[0] = p->cs_ciatype[1] = 0;
  8514. switch (p->cs_compatible)
  8515. {
  8516. case CP_GENERIC: // generic
  8517. if (p->cpu_model >= 68020) {
  8518. // big box-like
  8519. p->cs_rtc = 2;
  8520. p->cs_fatgaryrev = 0;
  8521. p->cs_ide = -1;
  8522. p->cs_mbdmac = 0;
  8523. p->cs_ramseyrev = 0x0f;
  8524. p->cs_unmapped_space = 1;
  8525. } else if (p->cpu_compatible) {
  8526. // very A500-like
  8527. p->cs_df0idhw = 0;
  8528. p->cs_resetwarning = 0;
  8529. if (p->bogomem.size || p->chipmem.size > 0x80000 || p->fastmem[0].size)
  8530. p->cs_rtc = 1;
  8531. p->cs_ciatodbug = true;
  8532. } else {
  8533. // sort of A500-like
  8534. p->cs_ide = -1;
  8535. p->cs_rtc = 1;
  8536. }
  8537. break;
  8538. case CP_CDTV: // CDTV
  8539. p->cs_rtc = 1;
  8540. p->cs_cdtvcd = p->cs_cdtvram = 1;
  8541. p->cs_df0idhw = 1;
  8542. p->cs_ksmirror_e0 = 0;
  8543. break;
  8544. case CP_CDTVCR: // CDTV-CR
  8545. p->cs_rtc = 1;
  8546. p->cs_cdtvcd = p->cs_cdtvram = 1;
  8547. p->cs_cdtvcr = true;
  8548. p->cs_df0idhw = 1;
  8549. p->cs_ksmirror_e0 = 0;
  8550. p->cs_ide = IDE_A600A1200;
  8551. p->cs_pcmcia = 1;
  8552. p->cs_ksmirror_a8 = 1;
  8553. p->cs_ciaoverlay = 0;
  8554. p->cs_resetwarning = 0;
  8555. p->cs_ciatodbug = true;
  8556. break;
  8557. case CP_CD32: // CD32
  8558. p->cs_cd32c2p = p->cs_cd32cd = p->cs_cd32nvram = true;
  8559. p->cs_ksmirror_e0 = 0;
  8560. p->cs_ksmirror_a8 = 1;
  8561. p->cs_ciaoverlay = 0;
  8562. p->cs_resetwarning = 0;
  8563. p->cs_unmapped_space = 1;
  8564. break;
  8565. case CP_A500: // A500
  8566. p->cs_df0idhw = 0;
  8567. p->cs_resetwarning = 0;
  8568. if (p->bogomem.size || p->chipmem.size > 0x80000 || p->fastmem[0].size)
  8569. p->cs_rtc = 1;
  8570. p->cs_ciatodbug = true;
  8571. break;
  8572. case CP_A500P: // A500+
  8573. p->cs_rtc = 1;
  8574. p->cs_resetwarning = 0;
  8575. p->cs_ciatodbug = true;
  8576. break;
  8577. case CP_A600: // A600
  8578. p->cs_ide = IDE_A600A1200;
  8579. p->cs_pcmcia = 1;
  8580. p->cs_ksmirror_a8 = 1;
  8581. p->cs_ciaoverlay = 0;
  8582. p->cs_resetwarning = 0;
  8583. p->cs_ciatodbug = true;
  8584. p->cs_ciatype[0] = p->cs_ciatype[1] = 1;
  8585. break;
  8586. case CP_A1000: // A1000
  8587. p->cs_a1000ram = 1;
  8588. p->cs_ciaatod = p->ntscmode ? 2 : 1;
  8589. p->cs_ksmirror_e0 = 0;
  8590. p->cs_agnusbltbusybug = 1;
  8591. p->cs_dipagnus = 1;
  8592. p->cs_ciatodbug = true;
  8593. break;
  8594. case CP_VELVET: // A1000 Prototype
  8595. p->cs_ciaatod = p->ntscmode ? 2 : 1;
  8596. p->cs_ksmirror_e0 = 0;
  8597. p->cs_agnusbltbusybug = 1;
  8598. p->cs_dipagnus = 1;
  8599. p->cs_denisenoehb = 1;
  8600. break;
  8601. case CP_A1200: // A1200
  8602. p->cs_ide = IDE_A600A1200;
  8603. p->cs_pcmcia = 1;
  8604. p->cs_ksmirror_a8 = 1;
  8605. p->cs_ciaoverlay = 0;
  8606. if (p->fastmem[0].size || p->z3fastmem[0].size || p->cpuboard_type)
  8607. p->cs_rtc = 1;
  8608. break;
  8609. case CP_A2000: // A2000
  8610. p->cs_rtc = 1;
  8611. p->cs_ciaatod = p->ntscmode ? 2 : 1;
  8612. p->cs_ciatodbug = true;
  8613. p->cs_unmapped_space = 1;
  8614. break;
  8615. case CP_A3000: // A3000
  8616. p->cs_rtc = 2;
  8617. p->cs_fatgaryrev = 0;
  8618. p->cs_ramseyrev = 0x0d;
  8619. p->cs_mbdmac = 1;
  8620. p->cs_ksmirror_e0 = 0;
  8621. p->cs_ciaatod = p->ntscmode ? 2 : 1;
  8622. p->cs_z3autoconfig = true;
  8623. p->cs_unmapped_space = 1;
  8624. break;
  8625. case CP_A3000T: // A3000T
  8626. p->cs_rtc = 2;
  8627. p->cs_fatgaryrev = 0;
  8628. p->cs_ramseyrev = 0x0d;
  8629. p->cs_mbdmac = 1;
  8630. p->cs_ksmirror_e0 = 0;
  8631. p->cs_ciaatod = p->ntscmode ? 2 : 1;
  8632. p->cs_z3autoconfig = true;
  8633. p->cs_unmapped_space = 1;
  8634. break;
  8635. case CP_A4000: // A4000
  8636. p->cs_rtc = 2;
  8637. p->cs_fatgaryrev = 0;
  8638. p->cs_ramseyrev = 0x0f;
  8639. p->cs_ide = IDE_A4000;
  8640. p->cs_mbdmac = 0;
  8641. p->cs_ksmirror_a8 = 0;
  8642. p->cs_ksmirror_e0 = 0;
  8643. p->cs_z3autoconfig = true;
  8644. p->cs_unmapped_space = 1;
  8645. break;
  8646. case CP_A4000T: // A4000T
  8647. p->cs_rtc = 2;
  8648. p->cs_fatgaryrev = 0;
  8649. p->cs_ramseyrev = 0x0f;
  8650. p->cs_ide = IDE_A4000;
  8651. p->cs_mbdmac = 2;
  8652. p->cs_ksmirror_a8 = 0;
  8653. p->cs_ksmirror_e0 = 0;
  8654. p->cs_z3autoconfig = true;
  8655. p->cs_unmapped_space = 1;
  8656. break;
  8657. case CP_CASABLANCA:
  8658. break;
  8659. case CP_DRACO:
  8660. break;
  8661. }
  8662. if (p->cpu_model >= 68040)
  8663. p->cs_bytecustomwritebug = true;
  8664. return 1;
  8665. }
  8666. #ifdef _WIN32
  8667. #define SHADERPARM "string winuae_config : WINUAE_CONFIG ="
  8668. // Parse early because actual shader parsing happens after screen mode
  8669. // is already open and if shader config modifies screen parameters,
  8670. // it would cause annoying flickering.
  8671. void cfgfile_get_shader_config(struct uae_prefs *prefs, int rtg)
  8672. {
  8673. TCHAR pluginpath[MAX_DPATH];
  8674. if (!get_plugin_path(pluginpath, sizeof pluginpath / sizeof(TCHAR), _T("filtershaders\\direct3d")))
  8675. return;
  8676. for (int i = 0; i < 2 * MAX_FILTERSHADERS + 1; i++) {
  8677. TCHAR tmp[MAX_DPATH];
  8678. if (!prefs->gf[rtg].gfx_filtershader[i][0])
  8679. continue;
  8680. _tcscpy(tmp, pluginpath);
  8681. _tcscat(tmp, prefs->gf[rtg].gfx_filtershader[i]);
  8682. struct zfile *z = zfile_fopen(tmp, _T("r"));
  8683. if (!z)
  8684. continue;
  8685. bool started = false;
  8686. bool quoted = false;
  8687. bool done = false;
  8688. TCHAR *cmd = NULL;
  8689. int len = 0;
  8690. int totallen = 0;
  8691. int linecnt = 15;
  8692. while (!done) {
  8693. char linep[MAX_DPATH], *line;
  8694. if (!zfile_fgetsa(linep, MAX_DPATH, z))
  8695. break;
  8696. if (!started) {
  8697. linecnt--;
  8698. if (linecnt < 0)
  8699. break;
  8700. }
  8701. line = linep + strspn(linep, "\t \r\n");
  8702. trimwsa(line);
  8703. char *p = line;
  8704. if (p[0] == '/' && p[1] == '/')
  8705. continue;
  8706. if (p[0] == ';')
  8707. continue;
  8708. if (!started) {
  8709. if (!strnicmp(line, SHADERPARM, strlen(SHADERPARM))) {
  8710. started = true;
  8711. p += strlen(SHADERPARM);
  8712. totallen = 1000;
  8713. cmd = xcalloc(TCHAR, totallen);
  8714. }
  8715. } else {
  8716. while (!done && *p) {
  8717. if (*p == '\"') {
  8718. quoted = !quoted;
  8719. } else if (!quoted && *p == ';') {
  8720. done = true;
  8721. } else if (quoted) {
  8722. if (len + 2 >= totallen) {
  8723. totallen += 1000;
  8724. cmd = xrealloc(TCHAR, cmd, totallen);
  8725. }
  8726. cmd[len++] = *p;
  8727. }
  8728. p++;
  8729. }
  8730. }
  8731. }
  8732. if (cmd) {
  8733. TCHAR *argc[UAELIB_MAX_PARSE];
  8734. cmd[len] = 0;
  8735. write_log(_T("Shader '%s' config '%s'\n"), tmp, cmd);
  8736. int argv = cmdlineparser(cmd, argc, UAELIB_MAX_PARSE);
  8737. if (argv > 0) {
  8738. execcmdline(prefs, argv, argc, NULL, 0, true);
  8739. }
  8740. for (int i = 0; i < argv; i++) {
  8741. xfree(argc[i]);
  8742. }
  8743. }
  8744. xfree(cmd);
  8745. zfile_fclose(z);
  8746. }
  8747. }
  8748. #else
  8749. void cfgfile_get_shader_config(struct uae_prefs *p, int rtg)
  8750. {
  8751. }
  8752. #endif
  8753. void set_config_changed (void)
  8754. {
  8755. config_changed = 1;
  8756. }
  8757. void config_check_vsync (void)
  8758. {
  8759. if (config_changed) {
  8760. #if 0
  8761. if (config_changed == 1) {
  8762. createconfigstore (&currprefs);
  8763. uae_lua_run_handler ("on_uae_config_changed");
  8764. }
  8765. #endif
  8766. config_changed++;
  8767. if (config_changed >= 3)
  8768. config_changed = 0;
  8769. }
  8770. }
  8771. bool is_error_log (void)
  8772. {
  8773. return error_lines != NULL;
  8774. }
  8775. TCHAR *get_error_log (void)
  8776. {
  8777. strlist *sl;
  8778. int len = 0;
  8779. for (sl = error_lines; sl; sl = sl->next) {
  8780. len += _tcslen (sl->option) + 1;
  8781. }
  8782. if (!len)
  8783. return NULL;
  8784. TCHAR *s = xcalloc (TCHAR, len + 1);
  8785. for (sl = error_lines; sl; sl = sl->next) {
  8786. _tcscat (s, sl->option);
  8787. _tcscat (s, _T("\n"));
  8788. }
  8789. return s;
  8790. }
  8791. void error_log (const TCHAR *format, ...)
  8792. {
  8793. TCHAR buffer[256], *bufp;
  8794. int bufsize = 256;
  8795. va_list parms;
  8796. if (format == NULL) {
  8797. struct strlist **ps = &error_lines;
  8798. while (*ps) {
  8799. struct strlist *s = *ps;
  8800. *ps = s->next;
  8801. xfree (s->value);
  8802. xfree (s->option);
  8803. xfree (s);
  8804. }
  8805. return;
  8806. }
  8807. va_start (parms, format);
  8808. bufp = buffer;
  8809. for (;;) {
  8810. int count = _vsntprintf (bufp, bufsize - 1, format, parms);
  8811. if (count < 0) {
  8812. bufsize *= 10;
  8813. if (bufp != buffer)
  8814. xfree (bufp);
  8815. bufp = xmalloc (TCHAR, bufsize);
  8816. continue;
  8817. }
  8818. break;
  8819. }
  8820. bufp[bufsize - 1] = 0;
  8821. write_log (_T("%s\n"), bufp);
  8822. va_end (parms);
  8823. strlist *u = xcalloc (struct strlist, 1);
  8824. if (u) {
  8825. u->option = my_strdup(bufp);
  8826. if (u->option) {
  8827. u->next = error_lines;
  8828. error_lines = u;
  8829. }
  8830. }
  8831. if (bufp != buffer)
  8832. xfree (bufp);
  8833. }