]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Validate index based config entries, fix gfx_filter_autoscale interlace mode saving.
authorToni Wilen <twilen@winuae.net>
Sun, 25 Dec 2022 18:00:51 +0000 (20:00 +0200)
committerToni Wilen <twilen@winuae.net>
Sun, 25 Dec 2022 18:00:51 +0000 (20:00 +0200)
cfgfile.cpp

index 7c3d27af727c8a764eb84400fd4691baeef74581..4f0690f7d5c0fafbbceff238882796120acf282f 100644 (file)
@@ -814,6 +814,22 @@ end:
        xfree(tmp2);
        xfree(tmp1);
 }
+
+static bool checkstrarr(const TCHAR *option, const TCHAR *arr[], int value)
+{
+       if (value < 0) {
+               write_log("Invalid config entry '%s', value %d\n", option, value);
+               return false;
+       }
+       for (int i = 0; i <= value; i++) {
+               if (arr[i] == NULL) {
+                       write_log("Invalid config entry '%s', value %d\n", option, value);
+                       return false;
+               }
+       }
+       return true;
+}
+
 static void cfgfile_dwrite_coords(struct zfile *f, const TCHAR *option, int x, int y)
 {
        if (x || y)
@@ -843,6 +859,12 @@ void cfgfile_write_str(struct zfile *f, const TCHAR *option, const TCHAR *value)
 {
        cfg_dowrite(f, option, value, 0, 0, 0);
 }
+void cfgfile_write_strarr(struct zfile *f, const TCHAR *option, const TCHAR *arr[], int value)
+{
+       checkstrarr(option, arr, value);
+       const TCHAR *v = arr[value];
+       cfg_dowrite(f, option, v, 0, 0, 0);
+}
 static void cfgfile_write_str(struct zfile *f, const TCHAR *option, const TCHAR *optionext, const TCHAR *value)
 {
        cfg_dowrite(f, option, optionext, value, 0, 0, 0);
@@ -859,7 +881,16 @@ static void cfgfile_dwrite_str(struct zfile *f, const TCHAR *option, const TCHAR
 {
        cfg_dowrite(f, option, optionext, value, 1, 0, 0);
 }
-
+void cfgfile_dwrite_strarr(struct zfile *f, const TCHAR *option, const TCHAR *optionext, const TCHAR *arr[], int value)
+{
+       checkstrarr(option, arr, value);
+       const TCHAR *v = arr[value];
+       cfg_dowrite(f, option, optionext, v, 1, 0, 0);
+}
+void cfgfile_dwrite_strarr(struct zfile *f, const TCHAR *option, const TCHAR *arr[], int value)
+{
+       cfgfile_dwrite_strarr(f, option, NULL, arr, value);
+}
 void cfgfile_target_write_bool(struct zfile *f, const TCHAR *option, bool b)
 {
        cfg_dowrite(f, option, b ? _T("true") : _T("false"), 0, 1, 0);
@@ -1969,7 +2000,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
 
        cfg_write (_T("; common"), f);
 
-       cfgfile_write_str (f, _T("use_gui"), guimode1[p->start_gui]);
+       cfgfile_write_strarr (f, _T("use_gui"), guimode1, p->start_gui);
        cfgfile_write_bool (f, _T("use_debugger"), p->start_debugger);
        cfgfile_write_multichoice(f, _T("debugging_features"), debugfeatures, p->debugging_features);
        cfgfile_dwrite_str(f, _T("debugging_options"), p->debugging_options);
@@ -2094,20 +2125,20 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
        cfgfile_write_bool (f, _T("serial_hardware_ctsrts"), p->serial_hwctsrts);
        cfgfile_write_bool (f, _T("serial_direct"), p->serial_direct);
        cfgfile_dwrite (f, _T("serial_stopbits"), _T("%d"), p->serial_stopbits);
-       cfgfile_dwrite_str(f, _T("serial_translate"), serialcrlf[p->serial_crlf]);
-       cfgfile_write_str (f, _T("scsi"), scsimode[p->scsi]);
+       cfgfile_dwrite_strarr(f, _T("serial_translate"), serialcrlf, p->serial_crlf);
+       cfgfile_write_strarr (f, _T("scsi"), scsimode, p->scsi);
        cfgfile_write_bool (f, _T("uaeserial"), p->uaeserial);
        cfgfile_write_bool (f, _T("sana2"), p->sana2);
 
-       cfgfile_write_str (f, _T("sound_output"), soundmode1[p->produce_sound]);
-       cfgfile_write_str (f, _T("sound_channels"), stereomode[p->sound_stereo]);
+       cfgfile_write_strarr(f, _T("sound_output"), soundmode1, p->produce_sound);
+       cfgfile_write_strarr(f, _T("sound_channels"), stereomode, p->sound_stereo);
        cfgfile_write (f, _T("sound_stereo_separation"), _T("%d"), p->sound_stereo_separation);
        cfgfile_write (f, _T("sound_stereo_mixing_delay"), _T("%d"), p->sound_mixed_stereo_delay >= 0 ? p->sound_mixed_stereo_delay : 0);
        cfgfile_write (f, _T("sound_max_buff"), _T("%d"), p->sound_maxbsiz);
        cfgfile_write (f, _T("sound_frequency"), _T("%d"), p->sound_freq);
-       cfgfile_write_str (f, _T("sound_interpol"), interpolmode[p->sound_interpol]);
-       cfgfile_write_str (f, _T("sound_filter"), soundfiltermode1[p->sound_filter]);
-       cfgfile_write_str (f, _T("sound_filter_type"), soundfiltermode2[p->sound_filter_type]);
+       cfgfile_write_strarr (f, _T("sound_interpol"), interpolmode, p->sound_interpol);
+       cfgfile_write_strarr (f, _T("sound_filter"), soundfiltermode1, p->sound_filter);
+       cfgfile_write_strarr (f, _T("sound_filter_type"), soundfiltermode2, p->sound_filter_type);
        cfgfile_write (f, _T("sound_volume"), _T("%d"), p->sound_volume_master);
        cfgfile_write (f, _T("sound_volume_paula"), _T("%d"), p->sound_volume_paula);
        if (p->sound_volume_cd >= 0)
@@ -2126,13 +2157,13 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
        cfgfile_dwrite (f, _T("sampler_buffer"), _T("%d"), p->sampler_buffer);
        cfgfile_dwrite_bool (f, _T("sampler_stereo"), p->sampler_stereo);
 
-       cfgfile_write_str (f, _T("comp_trustbyte"), compmode[p->comptrustbyte]);
-       cfgfile_write_str (f, _T("comp_trustword"), compmode[p->comptrustword]);
-       cfgfile_write_str (f, _T("comp_trustlong"), compmode[p->comptrustlong]);
-       cfgfile_write_str (f, _T("comp_trustnaddr"), compmode[p->comptrustnaddr]);
+       cfgfile_write_strarr(f, _T("comp_trustbyte"), compmode, p->comptrustbyte);
+       cfgfile_write_strarr(f, _T("comp_trustword"), compmode, p->comptrustword);
+       cfgfile_write_strarr(f, _T("comp_trustlong"), compmode, p->comptrustlong);
+       cfgfile_write_strarr(f, _T("comp_trustnaddr"), compmode, p->comptrustnaddr);
        cfgfile_write_bool (f, _T("comp_nf"), p->compnf);
        cfgfile_write_bool (f, _T("comp_constjump"), p->comp_constjump);
-       cfgfile_write_str (f, _T("comp_flushmode"), flushmode[p->comp_hardflush]);
+       cfgfile_write_strarr(f, _T("comp_flushmode"), flushmode, p->comp_hardflush);
 #ifdef USE_JIT_FPU
        cfgfile_write_bool (f, _T("compfpu"), p->compfpu);
 #endif
@@ -2197,7 +2228,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
                if (p->dongle + 1 >= sizeof (dongles) / sizeof (TCHAR*))
                        cfgfile_write (f, _T("dongle"), _T("%d"), p->dongle);
                else
-                       cfgfile_write_str (f, _T("dongle"), dongles[p->dongle]);
+                       cfgfile_write_strarr(f, _T("dongle"), dongles, p->dongle);
        }
 
        cfgfile_write_bool (f, _T("bsdsocket_emu"), p->socket_emu);
@@ -2257,14 +2288,14 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
 
        cfgfile_write_bool (f, _T("synchronize_clock"), p->tod_hack);
        cfgfile_write (f, _T("maprom"), _T("0x%x"), p->maprom);
-       cfgfile_dwrite_str (f, _T("boot_rom_uae"), uaebootrom[p->boot_rom]);
+       cfgfile_dwrite_strarr(f, _T("boot_rom_uae"), uaebootrom, p->boot_rom);
        if (p->uaeboard_nodiag)
-               cfgfile_write_str(f, _T("uaeboard"), uaeboard_off[p->uaeboard]);
+               cfgfile_write_strarr(f, _T("uaeboard"), uaeboard_off, p->uaeboard);
        else
-               cfgfile_dwrite_str(f, _T("uaeboard"), uaeboard[p->uaeboard]);
+               cfgfile_dwrite_strarr(f, _T("uaeboard"), uaeboard, p->uaeboard);
        if (p->autoconfig_custom_sort)
                cfgfile_dwrite(f, _T("uaeboard_options"), _T("order=%d"), p->uaeboard_order);
-       cfgfile_dwrite_str (f, _T("parallel_matrix_emulation"), epsonprinter[p->parallel_matrix_emulation]);
+       cfgfile_dwrite_strarr(f, _T("parallel_matrix_emulation"), epsonprinter, p->parallel_matrix_emulation);
        cfgfile_write_bool (f, _T("parallel_postscript_emulation"), p->parallel_postscript_emulation);
        cfgfile_write_bool (f, _T("parallel_postscript_detection"), p->parallel_postscript_detection);
        cfgfile_write_str (f, _T("ghostscript_parameters"), p->ghostscript_parameters);
@@ -2272,8 +2303,8 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
        cfgfile_dwrite (f, _T("uae_hide"), _T("%d"), p->uae_hide);
        cfgfile_dwrite_bool (f, _T("uae_hide_autoconfig"), p->uae_hide_autoconfig);
        cfgfile_dwrite_bool (f, _T("magic_mouse"), (p->input_mouse_untrap & MOUSEUNTRAP_MAGIC) != 0);
-       cfgfile_dwrite_str (f, _T("magic_mousecursor"), magiccursors[p->input_magic_mouse_cursor]);
-       cfgfile_dwrite_str (f, _T("absolute_mouse"), abspointers[p->input_tablet]);
+       cfgfile_dwrite_strarr(f, _T("magic_mousecursor"), magiccursors, p->input_magic_mouse_cursor);
+       cfgfile_dwrite_strarr(f, _T("absolute_mouse"), abspointers, p->input_tablet);
        cfgfile_dwrite_bool (f, _T("tablet_library"), p->tablet_library);
        cfgfile_dwrite_bool (f, _T("clipboard_sharing"), p->clipboard_sharing);
        cfgfile_dwrite_bool(f, _T("native_code"), p->native_code);
@@ -2298,41 +2329,41 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
 
        cfgfile_write (f, _T("gfx_autoresolution"), _T("%d"), p->gfx_autoresolution);
        cfgfile_dwrite (f, _T("gfx_autoresolution_delay"), _T("%d"), p->gfx_autoresolution_delay);
-       cfgfile_dwrite (f, _T("gfx_autoresolution_min_vertical"), vertmode[p->gfx_autoresolution_minv + 1]);
-       cfgfile_dwrite (f, _T("gfx_autoresolution_min_horizontal"), horizmode[p->gfx_autoresolution_minh + 1]);
+       cfgfile_dwrite_strarr(f, _T("gfx_autoresolution_min_vertical"), vertmode, p->gfx_autoresolution_minv + 1);
+       cfgfile_dwrite_strarr(f, _T("gfx_autoresolution_min_horizontal"), horizmode, p->gfx_autoresolution_minh + 1);
        cfgfile_write_bool (f, _T("gfx_autoresolution_vga"), p->gfx_autoresolution_vga);
 
        cfgfile_write (f, _T("gfx_backbuffers"), _T("%d"), p->gfx_apmode[0].gfx_backbuffers);
        cfgfile_write (f, _T("gfx_backbuffers_rtg"), _T("%d"), p->gfx_apmode[1].gfx_backbuffers);
        if (p->gfx_apmode[APMODE_NATIVE].gfx_interlaced)
                cfgfile_write_bool (f, _T("gfx_interlace"), p->gfx_apmode[APMODE_NATIVE].gfx_interlaced);
-       cfgfile_write_str (f, _T("gfx_vsync"), vsyncmodes[p->gfx_apmode[0].gfx_vsync]);
-       cfgfile_write_str (f, _T("gfx_vsyncmode"), vsyncmodes2[p->gfx_apmode[0].gfx_vsyncmode]);
-       cfgfile_write_str (f, _T("gfx_vsync_picasso"), vsyncmodes[p->gfx_apmode[1].gfx_vsync]);
-       cfgfile_write_str (f, _T("gfx_vsyncmode_picasso"), vsyncmodes2[p->gfx_apmode[1].gfx_vsyncmode]);
+       cfgfile_write_strarr(f, _T("gfx_vsync"), vsyncmodes, p->gfx_apmode[0].gfx_vsync);
+       cfgfile_write_strarr(f, _T("gfx_vsyncmode"), vsyncmodes2, p->gfx_apmode[0].gfx_vsyncmode);
+       cfgfile_write_strarr(f, _T("gfx_vsync_picasso"), vsyncmodes, p->gfx_apmode[1].gfx_vsync);
+       cfgfile_write_strarr(f, _T("gfx_vsyncmode_picasso"), vsyncmodes2, p->gfx_apmode[1].gfx_vsyncmode);
        cfgfile_write_bool (f, _T("gfx_lores"), p->gfx_resolution == 0);
-       cfgfile_write_str (f, _T("gfx_resolution"), lorestype1[p->gfx_resolution]);
-       cfgfile_write_str (f, _T("gfx_lores_mode"), loresmode[p->gfx_lores_mode]);
+       cfgfile_write_strarr(f, _T("gfx_resolution"), lorestype1, p->gfx_resolution);
+       cfgfile_write_strarr(f, _T("gfx_lores_mode"), loresmode, p->gfx_lores_mode);
        cfgfile_write_bool (f, _T("gfx_flickerfixer"), p->gfx_scandoubler);
-       cfgfile_write_str (f, _T("gfx_linemode"), p->gfx_vresolution > 0 ? linemode[p->gfx_iscanlines * 4 + p->gfx_pscanlines + 1] : linemode[0]);
-       cfgfile_write_str (f, _T("gfx_fullscreen_amiga"), fullmodes[p->gfx_apmode[0].gfx_fullscreen]);
-       cfgfile_write_str (f, _T("gfx_fullscreen_picasso"), fullmodes[p->gfx_apmode[1].gfx_fullscreen]);
-       cfgfile_write_str (f, _T("gfx_center_horizontal"), centermode1[p->gfx_xcenter]);
-       cfgfile_write_str (f, _T("gfx_center_vertical"), centermode1[p->gfx_ycenter]);
-       cfgfile_write_str (f, _T("gfx_colour_mode"), colormode1[p->color_mode]);
+       cfgfile_write_strarr(f, _T("gfx_linemode"), linemode, p->gfx_vresolution > 0 ? p->gfx_iscanlines * 4 + p->gfx_pscanlines + 1 : 0);
+       cfgfile_write_strarr(f, _T("gfx_fullscreen_amiga"), fullmodes, p->gfx_apmode[0].gfx_fullscreen);
+       cfgfile_write_strarr(f, _T("gfx_fullscreen_picasso"), fullmodes, p->gfx_apmode[1].gfx_fullscreen);
+       cfgfile_write_strarr(f, _T("gfx_center_horizontal"), centermode1, p->gfx_xcenter);
+       cfgfile_write_strarr(f, _T("gfx_center_vertical"), centermode1, p->gfx_ycenter);
+       cfgfile_write_strarr(f, _T("gfx_colour_mode"), colormode1, p->color_mode);
        cfgfile_write_bool(f, _T("gfx_blacker_than_black"), p->gfx_blackerthanblack);
        cfgfile_dwrite_bool(f, _T("gfx_monochrome"), p->gfx_grayscale);
-       cfgfile_dwrite_str(f, _T("gfx_atari_palette_fix"), threebitcolors[p->gfx_threebitcolors]);
+       cfgfile_dwrite_strarr(f, _T("gfx_atari_palette_fix"), threebitcolors, p->gfx_threebitcolors);
        cfgfile_dwrite_bool(f, _T("gfx_black_frame_insertion"), p->lightboost_strobo);
        cfgfile_dwrite(f, _T("gfx_black_frame_insertion_ratio"), _T("%d"), p->lightboost_strobo_ratio);
-       cfgfile_write_str(f, _T("gfx_api"), filterapi[p->gfx_api]);
+       cfgfile_write_strarr(f, _T("gfx_api"), filterapi, p->gfx_api);
        cfgfile_dwrite_bool(f, _T("gfx_api_hdr"), p->gfx_api == 3);
-       cfgfile_write_str(f, _T("gfx_api_options"), filterapiopts[p->gfx_api_options]);
+       cfgfile_write_strarr(f, _T("gfx_api_options"), filterapiopts, p->gfx_api_options);
        cfgfile_dwrite(f, _T("gfx_horizontal_extra"), _T("%d"), p->gfx_extrawidth);
        cfgfile_dwrite(f, _T("gfx_vertical_extra"), _T("%d"), p->gfx_extraheight);
        cfgfile_dwrite(f, _T("gfx_frame_slices"), _T("%d"), p->gfx_display_sections);
        cfgfile_dwrite_bool(f, _T("gfx_vrr_monitor"), p->gfx_variable_sync != 0);
-       cfgfile_dwrite_str(f, _T("gfx_overscanmode"), overscanmodes[p->gfx_overscanmode]);
+       cfgfile_dwrite_strarr(f, _T("gfx_overscanmode"), overscanmodes, p->gfx_overscanmode);
        cfgfile_dwrite(f, _T("gfx_monitorblankdelay"), _T("%d"), p->gfx_monitorblankdelay);
 
 #ifdef GFXFILTER
@@ -2377,42 +2408,42 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
                                }
                        }
                }
-               cfgfile_dwrite_str(f, _T("gfx_filter_mode"), ext, filtermode2[gf->gfx_filter_filtermodeh]);
-               cfgfile_dwrite_str(f, _T("gfx_filter_mode2"), ext, filtermode2v[gf->gfx_filter_filtermodev]);
-               cfgfile_dwrite_ext (f, _T("gfx_filter_vert_zoomf"), ext, _T("%f"), gf->gfx_filter_vert_zoom);
-               cfgfile_dwrite_ext (f, _T("gfx_filter_horiz_zoomf"), ext, _T("%f"), gf->gfx_filter_horiz_zoom);
-               cfgfile_dwrite_ext (f, _T("gfx_filter_vert_zoom_multf"), ext, _T("%f"), gf->gfx_filter_vert_zoom_mult);
-               cfgfile_dwrite_ext (f, _T("gfx_filter_horiz_zoom_multf"), ext, _T("%f"), gf->gfx_filter_horiz_zoom_mult);
-               cfgfile_dwrite_ext (f, _T("gfx_filter_vert_offsetf"), ext, _T("%f"), gf->gfx_filter_vert_offset);
-               cfgfile_dwrite_ext (f, _T("gfx_filter_horiz_offsetf"), ext, _T("%f"), gf->gfx_filter_horiz_offset);
+               cfgfile_dwrite_strarr(f, _T("gfx_filter_mode"), ext, filtermode2, gf->gfx_filter_filtermodeh);
+               cfgfile_dwrite_strarr(f, _T("gfx_filter_mode2"), ext, filtermode2v, gf->gfx_filter_filtermodev);
+               cfgfile_dwrite_ext(f, _T("gfx_filter_vert_zoomf"), ext, _T("%f"), gf->gfx_filter_vert_zoom);
+               cfgfile_dwrite_ext(f, _T("gfx_filter_horiz_zoomf"), ext, _T("%f"), gf->gfx_filter_horiz_zoom);
+               cfgfile_dwrite_ext(f, _T("gfx_filter_vert_zoom_multf"), ext, _T("%f"), gf->gfx_filter_vert_zoom_mult);
+               cfgfile_dwrite_ext(f, _T("gfx_filter_horiz_zoom_multf"), ext, _T("%f"), gf->gfx_filter_horiz_zoom_mult);
+               cfgfile_dwrite_ext(f, _T("gfx_filter_vert_offsetf"), ext, _T("%f"), gf->gfx_filter_vert_offset);
+               cfgfile_dwrite_ext(f, _T("gfx_filter_horiz_offsetf"), ext, _T("%f"), gf->gfx_filter_horiz_offset);
                
-               cfgfile_dwrite_ext (f, _T("gfx_filter_left_border"), ext, _T("%d"), gf->gfx_filter_left_border);
-               cfgfile_dwrite_ext (f, _T("gfx_filter_right_border"), ext, _T("%d"), gf->gfx_filter_right_border);
-               cfgfile_dwrite_ext (f, _T("gfx_filter_top_border"), ext, _T("%d"), gf->gfx_filter_top_border);
-               cfgfile_dwrite_ext (f, _T("gfx_filter_bottom_border"), ext, _T("%d"), gf->gfx_filter_bottom_border);
+               cfgfile_dwrite_ext(f, _T("gfx_filter_left_border"), ext, _T("%d"), gf->gfx_filter_left_border);
+               cfgfile_dwrite_ext(f, _T("gfx_filter_right_border"), ext, _T("%d"), gf->gfx_filter_right_border);
+               cfgfile_dwrite_ext(f, _T("gfx_filter_top_border"), ext, _T("%d"), gf->gfx_filter_top_border);
+               cfgfile_dwrite_ext(f, _T("gfx_filter_bottom_border"), ext, _T("%d"), gf->gfx_filter_bottom_border);
                
                cfgfile_dwrite_ext(f, _T("gfx_filter_scanlines"), ext, _T("%d"), gf->gfx_filter_scanlines);
                cfgfile_dwrite_ext(f, _T("gfx_filter_scanlinelevel"), ext, _T("%d"), gf->gfx_filter_scanlinelevel);
                cfgfile_dwrite_ext(f, _T("gfx_filter_scanlineratio"), ext, _T("%d"), gf->gfx_filter_scanlineratio);
                cfgfile_dwrite_ext(f, _T("gfx_filter_scanlineoffset"), ext, _T("%d"), gf->gfx_filter_scanlineoffset);
 
-               cfgfile_dwrite_ext (f, _T("gfx_filter_luminance"), ext, _T("%d"), gf->gfx_filter_luminance);
-               cfgfile_dwrite_ext (f, _T("gfx_filter_contrast"), ext, _T("%d"), gf->gfx_filter_contrast);
-               cfgfile_dwrite_ext (f, _T("gfx_filter_saturation"), ext, _T("%d"), gf->gfx_filter_saturation);
-               cfgfile_dwrite_ext (f, _T("gfx_filter_gamma"), ext, _T("%d"), gf->gfx_filter_gamma);
-               cfgfile_dwrite_ext (f, _T("gfx_filter_gamma_r"), ext, _T("%d"), gf->gfx_filter_gamma_ch[0]);
-               cfgfile_dwrite_ext (f, _T("gfx_filter_gamma_g"), ext, _T("%d"), gf->gfx_filter_gamma_ch[1]);
-               cfgfile_dwrite_ext (f, _T("gfx_filter_gamma_b"), ext, _T("%d"), gf->gfx_filter_gamma_ch[2]);
+               cfgfile_dwrite_ext(f, _T("gfx_filter_luminance"), ext, _T("%d"), gf->gfx_filter_luminance);
+               cfgfile_dwrite_ext(f, _T("gfx_filter_contrast"), ext, _T("%d"), gf->gfx_filter_contrast);
+               cfgfile_dwrite_ext(f, _T("gfx_filter_saturation"), ext, _T("%d"), gf->gfx_filter_saturation);
+               cfgfile_dwrite_ext(f, _T("gfx_filter_gamma"), ext, _T("%d"), gf->gfx_filter_gamma);
+               cfgfile_dwrite_ext(f, _T("gfx_filter_gamma_r"), ext, _T("%d"), gf->gfx_filter_gamma_ch[0]);
+               cfgfile_dwrite_ext(f, _T("gfx_filter_gamma_g"), ext, _T("%d"), gf->gfx_filter_gamma_ch[1]);
+               cfgfile_dwrite_ext(f, _T("gfx_filter_gamma_b"), ext, _T("%d"), gf->gfx_filter_gamma_ch[2]);
                
-               cfgfile_dwrite_ext (f, _T("gfx_filter_blur"), ext, _T("%d"), gf->gfx_filter_blur);
-               cfgfile_dwrite_ext (f, _T("gfx_filter_noise"), ext, _T("%d"), gf->gfx_filter_noise);
-               cfgfile_dwrite_bool (f, _T("gfx_filter_bilinear"), ext, gf->gfx_filter_bilinear != 0);
+               cfgfile_dwrite_ext(f, _T("gfx_filter_blur"), ext, _T("%d"), gf->gfx_filter_blur);
+               cfgfile_dwrite_ext(f, _T("gfx_filter_noise"), ext, _T("%d"), gf->gfx_filter_noise);
+               cfgfile_dwrite_bool(f, _T("gfx_filter_bilinear"), ext, gf->gfx_filter_bilinear != 0);
                
-               cfgfile_dwrite_ext (f, _T("gfx_filter_keep_autoscale_aspect"), ext, _T("%d"), gf->gfx_filter_keep_autoscale_aspect);
-               cfgfile_dwrite_str (f, _T("gfx_filter_keep_aspect"), ext, aspects[gf->gfx_filter_keep_aspect]);
-               cfgfile_dwrite_str(f, _T("gfx_filter_autoscale"), ext, ext == NULL ? autoscale[gf->gfx_filter_autoscale] : autoscale_rtg[gf->gfx_filter_autoscale]);
-               cfgfile_dwrite_str (f, _T("gfx_filter_autoscale_limit"), ext, autoscalelimit[gf->gfx_filter_integerscalelimit]);
-               cfgfile_dwrite_ext (f, _T("gfx_filter_aspect_ratio"), ext, _T("%d:%d"),
+               cfgfile_dwrite_ext(f, _T("gfx_filter_keep_autoscale_aspect"), ext, _T("%d"), gf->gfx_filter_keep_autoscale_aspect);
+               cfgfile_dwrite_strarr(f, _T("gfx_filter_keep_aspect"), ext, aspects, gf->gfx_filter_keep_aspect);
+               cfgfile_dwrite_strarr(f, _T("gfx_filter_autoscale"), ext, j != GF_RTG ? autoscale : autoscale_rtg, gf->gfx_filter_autoscale);
+               cfgfile_dwrite_strarr(f, _T("gfx_filter_autoscale_limit"), ext, autoscalelimit, gf->gfx_filter_integerscalelimit);
+               cfgfile_dwrite_ext(f, _T("gfx_filter_aspect_ratio"), ext, _T("%d:%d"),
                        gf->gfx_filter_aspect >= 0 ? (gf->gfx_filter_aspect / ASPECTMULT) : -1,
                        gf->gfx_filter_aspect >= 0 ? (gf->gfx_filter_aspect & (ASPECTMULT - 1)) : -1);
                if (gf->gfx_filteroverlay[0]) {
@@ -2438,14 +2469,14 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
 #endif
 
        cfgfile_write_bool (f, _T("immediate_blits"), p->immediate_blits);
-       cfgfile_dwrite_str (f, _T("waiting_blits"), waitblits[p->waiting_blits]);
+       cfgfile_dwrite_strarr(f, _T("waiting_blits"), waitblits, p->waiting_blits);
        cfgfile_dwrite (f, _T("blitter_throttle"), _T("%.8f"), p->blitter_speed_throttle);
        cfgfile_write_bool (f, _T("ntsc"), p->ntscmode);
 
        cfgfile_write_bool(f, _T("genlock"), p->genlock);
        cfgfile_dwrite_bool(f, _T("genlock_alpha"), p->genlock_alpha);
        cfgfile_dwrite_bool(f, _T("genlock_aspect"), p->genlock_aspect);
-       cfgfile_dwrite_str(f, _T("genlockmode"), genlockmodes[p->genlock_image]);
+       cfgfile_dwrite_strarr(f, _T("genlockmode"), genlockmodes, p->genlock_image);
        cfgfile_dwrite_str(f, _T("genlock_image"), p->genlock_image_file);
        cfgfile_dwrite_str(f, _T("genlock_video"), p->genlock_video_file);
        cfgfile_dwrite(f, _T("genlock_mix"), _T("%d"), p->genlock_mix);
@@ -2482,7 +2513,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
        }
 
 
-       cfgfile_dwrite_str(f, _T("monitoremu"), specialmonitorconfignames[p->monitoremu]);
+       cfgfile_dwrite_strarr(f, _T("monitoremu"), specialmonitorconfignames, p->monitoremu);
        cfgfile_dwrite(f, _T("monitoremu_monitor"), _T("%d"), p->monitoremu_mon);
        cfgfile_dwrite_coords(f, _T("lightpen_offset"), p->lightpen_offset[0], p->lightpen_offset[1]);
        cfgfile_dwrite_bool(f, _T("lightpen_crosshair"), p->lightpen_crosshair);
@@ -2597,11 +2628,11 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
                }
        }
 
-       cfgfile_write_str (f, _T("collision_level"), collmode[p->collision_level]);
+       cfgfile_write_strarr(f, _T("collision_level"), collmode, p->collision_level);
 
-       cfgfile_write_str(f, _T("chipset_compatible"), cscompa[p->cs_compatible]);
-       cfgfile_dwrite_str(f, _T("ciaatod"), ciaatodmode[p->cs_ciaatod]);
-       cfgfile_dwrite_str(f, _T("rtc"), rtctype[p->cs_rtc]);
+       cfgfile_write_strarr(f, _T("chipset_compatible"), cscompa, p->cs_compatible);
+       cfgfile_dwrite_strarr(f, _T("ciaatod"), ciaatodmode, p->cs_ciaatod);
+       cfgfile_dwrite_strarr(f, _T("rtc"), rtctype, p->cs_rtc);
        cfgfile_dwrite (f, _T("chipset_rtc_adjust"), _T("%d"), p->cs_rtc_adjust);
        cfgfile_dwrite_bool(f, _T("cia_overlay"), p->cs_ciaoverlay);    
        cfgfile_dwrite_bool(f, _T("ksmirror_e0"), p->cs_ksmirror_e0);
@@ -2626,17 +2657,17 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
        cfgfile_dwrite_bool(f, _T("z3_autoconfig"), p->cs_z3autoconfig);
        cfgfile_dwrite_bool(f, _T("1mchipjumper"), p->cs_1mchipjumper);
        cfgfile_dwrite_bool(f, _T("color_burst"), p->cs_color_burst);
-       cfgfile_dwrite_str(f, _T("hvcsync"), hvcsync[p->cs_hvcsync]);
+       cfgfile_dwrite_strarr(f, _T("hvcsync"), hvcsync, p->cs_hvcsync);
        cfgfile_dwrite_bool(f, _T("toshiba_gary"), p->cs_toshibagary);
        cfgfile_dwrite_bool(f, _T("rom_is_slow"), p->cs_romisslow);
-       cfgfile_dwrite_str(f, _T("ciaa_type"), ciatype[p->cs_ciatype[0]]);
-       cfgfile_dwrite_str(f, _T("ciab_type"), ciatype[p->cs_ciatype[1]]);
-       cfgfile_dwrite_str(f, _T("unmapped_address_space"), unmapped[p->cs_unmapped_space]);
+       cfgfile_dwrite_strarr(f, _T("ciaa_type"), ciatype, p->cs_ciatype[0]);
+       cfgfile_dwrite_strarr(f, _T("ciab_type"), ciatype, p->cs_ciatype[1]);
+       cfgfile_dwrite_strarr(f, _T("unmapped_address_space"), unmapped, p->cs_unmapped_space);
        cfgfile_dwrite_bool(f, _T("memory_pattern"), p->cs_memorypatternfill);
        cfgfile_dwrite(f, _T("keyboard_handshake"), _T("%d"), currprefs.cs_kbhandshake);
        cfgfile_dwrite(f, _T("chipset_hacks"), _T("0x%x"), p->cs_hacks);
        cfgfile_dwrite(f, _T("eclockphase"), _T("%d"), p->cs_eclockphase);
-       cfgfile_dwrite_str(f, _T("eclocksync"), eclocksync[p->cs_eclocksync]);
+       cfgfile_dwrite_strarr(f, _T("eclocksync"), eclocksync, p->cs_eclocksync);
 
        if (is_board_enabled(p, ROMTYPE_CD32CART, 0)) {
                cfgfile_dwrite_bool(f, _T("cd32fmv"), true);
@@ -2657,7 +2688,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
                cfgfile_dwrite_bool(f, _T("scsi_a4000t"), true);
        }
 
-       cfgfile_dwrite_str (f, _T("z3mapping"), z3mapping[p->z3_mapping_mode]);
+       cfgfile_dwrite_strarr(f, _T("z3mapping"), z3mapping, p->z3_mapping_mode);
        cfgfile_dwrite_bool(f, _T("board_custom_order"), p->autoconfig_custom_sort);
        for (int i = 0; i < MAX_RAM_BOARDS; i++) {
                if (p->fastmem[i].size < 0x100000 && p->fastmem[i].size) {
@@ -2789,7 +2820,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
        }
        if (p->ppc_mode) {
                cfgfile_write_str(f, _T("ppc_model"), p->ppc_model[0] ? p->ppc_model : (p->ppc_mode == 1 ? _T("automatic") : _T("manual")));
-               cfgfile_write_str(f, _T("ppc_cpu_idle"), ppc_cpu_idle[p->ppc_cpu_idle]);
+               cfgfile_write_strarr(f, _T("ppc_cpu_idle"), ppc_cpu_idle, p->ppc_cpu_idle);
        }
        cfgfile_write_bool (f, _T("cpu_compatible"), p->cpu_compatible);
        cfgfile_write_bool (f, _T("cpu_24bit_addressing"), p->address_space_24);
@@ -2799,7 +2830,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
        cfgfile_dwrite_bool(f, _T("cpu_halt_auto_reset"), p->crash_auto_reset);
        cfgfile_dwrite_bool(f, _T("cpu_threaded"), p->cpu_thread);
        if (p->ppc_mode)
-               cfgfile_write_str(f, _T("ppc_implementation"), ppc_implementations[p->ppc_implementation]);
+               cfgfile_write_strarr(f, _T("ppc_implementation"), ppc_implementations, p->ppc_implementation);
 
        if (p->cpu_cycle_exact) {
                if (p->cpu_frequency)
@@ -2876,7 +2907,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
        cfgfile_dwrite_str (f, _T("filesys_inject_icons_drawer"), p->filesys_inject_icons_drawer);
        cfgfile_dwrite_str (f, _T("filesys_inject_icons_project"), p->filesys_inject_icons_project);
        cfgfile_dwrite_str (f, _T("filesys_inject_icons_tool"), p->filesys_inject_icons_tool);
-       cfgfile_dwrite_str (f, _T("scsidev_mode"), uaescsidevmodes[p->uaescsidevmode]);
+       cfgfile_dwrite_strarr(f, _T("scsidev_mode"), uaescsidevmodes, p->uaescsidevmode);
 #endif
        cfgfile_dwrite_bool(f, _T("harddrive_write_protect"), p->harddrive_read_only);
 
@@ -3650,7 +3681,7 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value)
        for (int j = 0; j < MAX_FILTERDATA; j++) {
                struct gfx_filterdata *gf = &p->gf[j];
                const TCHAR *ext = j == 0 ? NULL : (j == 1 ? _T("_rtg") : _T("_lace"));
-               if (cfgfile_strval (option, value, _T("gfx_filter_autoscale"), ext, &gf->gfx_filter_autoscale, j == 0 || j == 2 ? autoscale : autoscale_rtg, 0)
+               if (cfgfile_strval (option, value, _T("gfx_filter_autoscale"), ext, &gf->gfx_filter_autoscale, j != GF_RTG ? autoscale : autoscale_rtg, 0)
                        || cfgfile_strval (option, value, _T("gfx_filter_keep_aspect"), ext, &gf->gfx_filter_keep_aspect, aspects, 0)
                        || cfgfile_strval (option, value, _T("gfx_filter_autoscale_limit"), ext, &gf->gfx_filter_integerscalelimit, autoscalelimit, 0)
                        || cfgfile_floatval(option, value, _T("gfx_filter_vert_zoomf"), ext, &gf->gfx_filter_vert_zoom)