+#define CE_CONFIG_STR(val) \
+ { #val, 0, Config.val }
+
+#define CE_CONFIG_VAL(val) \
+ { #val, sizeof(Config.val), &Config.val }
+
+#define CE_STR(val) \
+ { #val, 0, val }
+
+#define CE_INTVAL(val) \
+ { #val, sizeof(val), &val }
+
+#define CE_INTVAL_N(name, val) \
+ { name, sizeof(val), &val }
+
+#define CE_INTVAL_P(val) \
+ { #val, sizeof(pl_rearmed_cbs.val), &pl_rearmed_cbs.val }
+
+// 'versioned' var, used when defaults change
+#define CE_CONFIG_STR_V(val, ver) \
+ { #val #ver, 0, Config.val }
+
+#define CE_INTVAL_V(val, ver) \
+ { #val #ver, sizeof(val), &val }
+
+#define CE_INTVAL_PV(val, ver) \
+ { #val #ver, sizeof(pl_rearmed_cbs.val), &pl_rearmed_cbs.val }
+
+static const struct {
+ const char *name;
+ size_t len;
+ void *val;
+} config_data[] = {
+ CE_CONFIG_STR(Bios),
+ CE_CONFIG_STR_V(Gpu, 3),
+ CE_CONFIG_STR(Spu),
+// CE_CONFIG_STR(Cdr),
+ CE_CONFIG_VAL(Xa),
+ CE_CONFIG_VAL(Mdec),
+ CE_CONFIG_VAL(Cdda),
+ CE_CONFIG_VAL(Debug),
+ CE_CONFIG_VAL(PsxOut),
+ CE_CONFIG_VAL(icache_emulation),
+ CE_CONFIG_VAL(DisableStalls),
+ CE_CONFIG_VAL(Cpu),
+ CE_CONFIG_VAL(GpuListWalking),
+ CE_CONFIG_VAL(PreciseExceptions),
+ CE_INTVAL(region),
+ CE_INTVAL_V(g_scaler, 3),
+ CE_INTVAL(g_gamma),
+ CE_INTVAL(g_layer_x),
+ CE_INTVAL(g_layer_y),
+ CE_INTVAL(g_layer_w),
+ CE_INTVAL(g_layer_h),
+ CE_INTVAL(soft_filter),
+ CE_INTVAL(scanlines),
+ CE_INTVAL(scanline_level),
+ CE_INTVAL(plat_target.vout_method),
+ CE_INTVAL(plat_target.hwfilter),
+ CE_INTVAL(plat_target.vout_fullscreen),
+ CE_INTVAL(state_slot),
+ CE_INTVAL(cpu_clock),
+ CE_INTVAL(g_opts),
+ CE_INTVAL(in_type_sel1),
+ CE_INTVAL(in_type_sel2),
+ CE_INTVAL(analog_deadzone),
+ CE_INTVAL(memcard1_sel),
+ CE_INTVAL(memcard2_sel),
+ CE_INTVAL(g_autostateld_opt),
+ CE_INTVAL_N("adev0_is_nublike", in_adev_is_nublike[0]),
+ CE_INTVAL_N("adev1_is_nublike", in_adev_is_nublike[1]),
+ CE_INTVAL_V(frameskip, 4),
+ CE_INTVAL_P(gpu_peops.iUseDither),
+ CE_INTVAL_P(gpu_peops.dwActFixes),
+ CE_INTVAL_P(gpu_unai_old.lineskip),
+ CE_INTVAL_P(gpu_unai_old.abe_hack),
+ CE_INTVAL_P(gpu_unai_old.no_light),
+ CE_INTVAL_P(gpu_unai_old.no_blend),
+ CE_INTVAL_P(gpu_unai.ilace_force),
+ CE_INTVAL_P(gpu_unai.pixel_skip),
+ CE_INTVAL_P(gpu_unai.lighting),
+ CE_INTVAL_P(gpu_unai.fast_lighting),
+ CE_INTVAL_P(gpu_unai.blending),
+ CE_INTVAL_P(gpu_unai.dithering),
+ CE_INTVAL_P(gpu_unai.scale_hires),
+ CE_INTVAL_P(gpu_neon.allow_interlace),
+ CE_INTVAL_P(gpu_neon.enhancement_enable),
+ CE_INTVAL_P(gpu_neon.enhancement_no_main),
+ CE_INTVAL_P(gpu_neon.enhancement_tex_adj),
+ CE_INTVAL_P(gpu_peopsgl.bDrawDither),
+ CE_INTVAL_P(gpu_peopsgl.iFilterType),
+ CE_INTVAL_P(gpu_peopsgl.iFrameTexType),
+ CE_INTVAL_P(gpu_peopsgl.iUseMask),
+ CE_INTVAL_P(gpu_peopsgl.bOpaquePass),
+ CE_INTVAL_P(gpu_peopsgl.bAdvancedBlend),
+ CE_INTVAL_P(gpu_peopsgl.bUseFastMdec),
+ CE_INTVAL_P(gpu_peopsgl.iVRamSize),
+ CE_INTVAL_P(gpu_peopsgl.iTexGarbageCollection),
+ CE_INTVAL_P(gpu_peopsgl.dwActFixes),
+ CE_INTVAL_P(screen_centering_type),
+ CE_INTVAL_P(screen_centering_x),
+ CE_INTVAL_P(screen_centering_y),
+ CE_INTVAL(spu_config.iUseReverb),
+ CE_INTVAL(spu_config.iXAPitch),
+ CE_INTVAL(spu_config.iUseInterpolation),
+ CE_INTVAL(spu_config.iTempo),
+ CE_INTVAL(spu_config.iUseThread),
+ CE_INTVAL(config_save_counter),
+ CE_INTVAL(in_evdev_allow_abs_only),
+ CE_INTVAL(volume_boost),
+ CE_INTVAL(psx_clock),
+ CE_INTVAL(new_dynarec_hacks),
+ CE_INTVAL(in_enable_vibration),
+};
+
+static char *get_cd_label(void)