OSDN Git Service

[Qt][AVIO] Add some codec entries (still not implement).
[csp-qt/common_source_project-fm7.git] / source / src / config.cpp
index 1d27034..f1b3c83 100644 (file)
@@ -6,24 +6,17 @@
 
        [ config ]
 */
-#if defined(_USE_AGAR)
-#include <SDL/SDL.h>
-#include <agar/core.h>
-#include <string>
-#include <vector>
-#include "fileio.h"
-#include "agar_logger.h"
-#endif
-
-#ifdef _USE_QT
-//# include <SDL/SDL.h>
+#if defined(_USE_QT)
 #include <string>
 #include <vector>
 #include "fileio.h"
-#include "agar_logger.h"
+#include "csp_logger.h"
 #include "qt_main.h"
-#else
-#include <windows.h>
+# if defined(Q_OS_WIN)
+# include <windows.h>
+# endif
+
+extern CSP_Logger *csp_logger;
 #endif
 
 #include <stdlib.h>
@@ -41,682 +34,933 @@ config_t config;
 #define CONFIG_NAME "conf"
 #endif
 
-#if defined(_USE_AGAR) || defined(_USE_QT)
-bool WritePrivateProfileString(char *lpAppName, char *lpKeyName, char *Value, FILEIO *lpFileName)
-{
-   std::string s;
-  
-   s = lpAppName;
-   s = s + ".";
-   s = s + lpKeyName + "=";
-   s = s + Value + "\n";
-   
-   lpFileName->Fwrite((void *)s.c_str(), s.length(), 1);
-   return true;
-}
-
-bool WritePrivateProfileInt(char *lpAppName, char *lpKeyName, int Value, FILEIO *lpFileName)
-{
-   std::string s;
-   int l;
-   char valuebuf[256];
-   memset(valuebuf, 0x00, 256);
-   
-   l = snprintf(valuebuf, 254, "%d", Value);
-   if((l <= 0) || (l >= 253)) return false;
-   s = lpAppName;
-   s = s + ".";
-   s = s + lpKeyName + "=";
-   s = s + valuebuf + "\n";
-   lpFileName->Fwrite((void *)s.c_str(), s.length(), 1);
-
-   return true;
-}
-
-BOOL WritePrivateProfileBool(char *lpAppName, char *lpKeyName, bool Value, FILEIO *lpFileName)
+BOOL MyWritePrivateProfileInt(LPCTSTR lpAppName, LPCTSTR lpKeyName, int Value, LPCTSTR lpFileName)
 {
-   int v = 0;
-   if(Value) v = 1; 
-   return WritePrivateProfileInt(lpAppName, lpKeyName, v, lpFileName);
+       return MyWritePrivateProfileString(lpAppName, lpKeyName, create_string(_T("%d"), Value), lpFileName);
 }
  
-
-
-std::string GetPrivateProfileStr(char *lpAppName, char *lpKeyName, FILEIO *lpFileName)
+BOOL MyWritePrivateProfileBool(LPCTSTR lpAppName, LPCTSTR lpKeyName, bool Value, LPCTSTR lpFileName)
 {
-   std::string key;
-   char ibuf[4096 + 102];
-   uint64_t i;
-   int l_len;
-   int c = '\0';
-   std::string::size_type  pos;
-   std::string key_str;
-   std::string got_str;
-  
-   key = lpAppName;
-   key = key + ".";
-   key = key + lpKeyName;
-   AGAR_DebugLog(AGAR_LOG_DEBUG, "Try App: %s Key: %s", lpAppName, lpKeyName);
-   lpFileName->Fseek(0, FILEIO_SEEK_SET);
-   do {
-      key_str = key;
-      ibuf[0] = '\0';
-      i = 0;
-      l_len = 0;
-      while(1) {
-       if(l_len > (4096 + 100)) { // Too long, read dummy.
-          c = (char)lpFileName->Fgetc();
-          if((c != EOF) && (c != '\n') && (c != '\0')) continue;
-          break;
-       }
-       c = (char)lpFileName->Fgetc();
-       if((c == EOF) || (c == '\n') || (c == '\0')) break;
-       ibuf[i] = (char)c;
-       i++;
-       l_len++;
-      }
-      l_len = 0;
-      ibuf[i] = '\0';
-      got_str = ibuf;
-      //AGAR_DebugLog(AGAR_LOG_DEBUG, "Got: %s %d chars.\n", got_str.c_str(), i);
-      key_str = key_str + "=";
-      pos = got_str.find(key_str);
-      if(pos != std::string::npos) break;
-      if(c == EOF) return "";
-   } while(c != EOF);
-
-   got_str.erase(0, pos + key_str.length());
-   //AGAR_DebugLog(AGAR_LOG_DEBUG, "Ok. Got %s = %s.\n", key, got_str.c_str());
-   return got_str;
+       return MyWritePrivateProfileString(lpAppName, lpKeyName, create_string(_T("%d"), Value ? 1 : 0), lpFileName);
 }
-
-void GetPrivateProfileString(char *section, char *key, char *defaultstr, char *str, int max_len, FILEIO *p)
-{
-   std::string sp = GetPrivateProfileStr(section, key, p);
-//   printf("Got: %s\n", sp.c_str());
-   
-   if((!sp.empty()) && (max_len > 1)){
-       strncpy(str, sp.c_str(), max_len);
-   } else {
-       strncpy(str, defaultstr, max_len);
-   }
-   printf("Got: %s\n", str);
  
-}
-
-int GetPrivateProfileInt(char *lpAppName, char *lpKeyName, int nDefault, FILEIO *lpFileName)
+bool MyGetPrivateProfileBool(LPCTSTR lpAppName, LPCTSTR lpKeyName, bool bDefault, LPCTSTR lpFileName)
 {
-   int i;
-   std::string s = GetPrivateProfileStr(lpAppName,lpKeyName, lpFileName);
-
-   if(s.empty()) {
-      i = nDefault;
-   } else {
-      i = strtol(s.c_str(), NULL, 10);
-   }
-   printf("Got: %d\n", i);
-   return i;
+       return (MyGetPrivateProfileInt(lpAppName, lpKeyName, bDefault ? 1 : 0, lpFileName) != 0);
 }
 
-
-
-bool GetPrivateProfileBool(char *lpAppName, char *lpKeyName, bool bDefault, FILEIO *lpFileName)
-{
-   
-       return (GetPrivateProfileInt(lpAppName, lpKeyName, bDefault ? 1 : 0, lpFileName) != 0);
-}
-   
-#else
-extern _TCHAR* get_parent_dir(_TCHAR* file);
-BOOL WritePrivateProfileInt(LPCTSTR lpAppName, LPCTSTR lpKeyName, int Value, LPCTSTR lpFileName)
-{
-       _TCHAR String[32];
-       _stprintf_s(String, 32, _T("%d"), Value);
-       return WritePrivateProfileString(lpAppName, lpKeyName, String, lpFileName);
-}
-
-BOOL WritePrivateProfileBool(LPCTSTR lpAppName, LPCTSTR lpKeyName, bool Value, LPCTSTR lpFileName)
+void initialize_config()
 {
-       _TCHAR String[32];
-       _stprintf_s(String, 32, _T("%d"), Value ? 1 : 0);
-       return WritePrivateProfileString(lpAppName, lpKeyName, String, lpFileName);
-}
-
-BOOL GetPrivateProfileBool(LPCTSTR lpAppName, LPCTSTR lpKeyName, bool bDefault, LPCTSTR lpFileName)
-{
-       return (GetPrivateProfileInt(lpAppName, lpKeyName, bDefault ? 1 : 0, lpFileName) != 0);
-}
-
-#endif
-void init_config()
-{
-       int i;
        // initial settings
        memset(&config, 0, sizeof(config_t));
+       config.window_mode = 1; 
+       // memo: set only non zero value
+       config.full_speed = false;      
        
-       config.use_direct_input = true;
-       config.disable_dwm = false;
-       
-#if !(defined(USE_BITMAP) || defined(USE_LED))
-       config.use_d3d9 = true;
-       config.stretch_type = 1;        // Stretch (Aspect)
-#endif
-       config.sound_frequency = 6;     // 48KHz
-       config.sound_latency = 1;       // 100msec
+       // control
+       #if defined(USE_BOOT_MODE) && defined(BOOT_MODE_DEFAULT)
+               config.boot_mode = BOOT_MODE_DEFAULT;
+       #endif
+       #if defined(USE_CPU_TYPE) && defined(CPU_TYPE_DEFAULT)
+               config.cpu_type = CPU_TYPE_DEFAULT;
+       #endif
+       #if defined(USE_DIPSWITCH) && defined(DIPSWITCH_DEFAULT)
+               config.dipswitch = DIPSWITCH_DEFAULT;
+       #endif
+       #if defined(USE_DEVICE_TYPE) && defined(DEVICE_TYPE_DEFAULT)
+               config.device_type = DEVICE_TYPE_DEFAULT;
+       #endif
+       #if defined(USE_DRIVE_TYPE) && defined(DRIVE_TYPE_DEFAULT)
+               config.drive_type = DRIVE_TYPE_DEFAULT;
+       #endif
+       #if defined(USE_KEYBOARD_TYPE) && defined(KEYBOARD_TYPE_DEFAULT)
+               config.keyboard_type = KEYBOARD_TYPE_DEFAULT;
+       #endif
+       #if defined(USE_MOUSE_TYPE) && defined(MOUSE_TYPE_DEFAULT)
+               config.mouse_type = MOUSE_TYPE_DEFAULT;
+       #endif
+       #if defined(USE_JOYSTICK_TYPE) && defined(JOYSTICK_TYPE_DEFAULT)
+               config.joystick_type = JOYSTICK_TYPE_DEFAULT;
+       #endif
+       #if defined(USE_SOUND_TYPE) && defined(SOUND_TYPE_DEFAULT)
+               config.sound_type = SOUND_TYPE_DEFAULT;
+       #endif
+       #if defined(USE_MONITOR_TYPE) && defined(MONITOR_TYPE_DEFAULT)
+               config.monitor_type = MONITOR_TYPE_DEFAULT;
+       #endif
+       #if defined(USE_PRINTER_TYPE) && defined(PRINTER_TYPE_DEFAULT)
+               config.printer_type = PRINTER_TYPE_DEFAULT;
+       #endif
+       #if defined(USE_FLOPPY_DISK)
+               for(int drv = 0; drv < USE_FLOPPY_DISK; drv++) {
+                       #if defined(CORRECT_DISK_TIMING_DEFAULT)
+                               config.correct_disk_timing[drv] = CORRECT_DISK_TIMING_DEFAULT;
+                       #else
+                               config.correct_disk_timing[drv] = false;
+                       #endif
+                       #if defined(IGNORE_DISK_CRC_DEFAULT)
+                               config.ignore_disk_crc[drv] = IGNORE_DISK_CRC_DEFAULT;
+                       #else
+                               config.ignore_disk_crc[drv] = false;
+                       #endif
+               }
+       #endif
+       #if defined(USE_TAPE)
+               for(int drv = 0; drv < USE_TAPE; drv++) {
+                       config.wave_shaper[drv] = true;
+                       config.direct_load_mzt[drv] = true;
+                       config.baud_high[drv] = true;
+               }
+       #endif
+       config.compress_state = true;
        
-#if defined(USE_TAPE)
-       config.wave_shaper = true;
-       config.direct_load_mzt = true;
-       config.baud_high = true;
-#endif
-#if defined(USE_BOOT_MODE) && defined(BOOT_MODE_DEFAULT)
-       config.boot_mode = BOOT_MODE_DEFAULT;
-#endif
-#if defined(USE_CPU_TYPE) && defined(CPU_TYPE_DEFAULT)
-       config.cpu_type = CPU_TYPE_DEFAULT;
-#endif
-#if defined(USE_DIPSWITCH) && defined(DIPSWITCH_DEFAULT)
-       config.dipswitch = DIPSWITCH_DEFAULT;
-#endif
-#if defined(USE_DEVICE_TYPE) && defined(DEVICE_TYPE_DEFAULT)
-       config.device_type = DEVICE_TYPE_DEFAULT;
-#endif
-#if defined(USE_FD1)
-# if defined(IGNORE_CRC_DEFAULT)
-       for(i = 0; i < 8; i++) config.ignore_crc[i] = IGNORE_CRC_DEFAULT;
-# else
-       for(i = 0; i < 8; i++) config.ignore_crc[i] = false;
-# endif        
-#endif
-#if defined(USE_SOUND_DEVICE_TYPE) && defined(SOUND_DEVICE_TYPE_DEFAULT)
-       config.sound_device_type = SOUND_DEVICE_TYPE_DEFAULT;
-#endif
-       // FM7 Series:
-       // 0 = PSG or NONE
-       // 1 = OPN (+PSG)
-       // 2 = WHG (+PSG)
-       // 3 = WHG + OPN (+PSG)
-       // 4 = THG  (+PSG)
-       // 5 = THG + OPN (+PSG)
-       // 6 = THG + WHG (+PSG)
-       // 7 = THG + WHG + OPN (+PSG)
-#if defined(_FM8)
-       config.sound_device_type = 0;   // WITHOUT PSG?
-#elif  defined(_FM7) || defined(_FMNEW7) || defined(_FM77) || defined(_FM77L4) || defined(_FM77L2)
-       config.sound_device_type = 0;   // PSG ONLY      
-#elif  defined(_FM77AV) || defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
-       config.sound_device_type = 1;   // OPN      
-#endif      
-       config.multiple_speakers = false;
-       config.general_sound_level = 0;
+       // screen
+       #ifndef ONE_BOARD_MICRO_COMPUTER
+               config.fullscreen_stretch_type = 1;     // Stretch (Aspect)
+       #endif
 
-#if defined(USE_QT)
-       config.use_opengl_scanline = false;
-       config.opengl_scanline_vert = false;
-       config.opengl_scanline_horiz = false;
-       config.use_opengl_filters = false;
-       config.opengl_filter_num = 0;
-#endif 
-#ifdef USE_MULTIPLE_SOUNDCARDS
-       {
-               int ii;
-               for(ii = 0; ii < USE_MULTIPLE_SOUNDCARDS; ii++) {
-                       config.sound_device_level[ii] = 0;
+       // sound
+       #ifdef SOUND_RATE_DEFAULT
+               config.sound_frequency = SOUND_RATE_DEFAULT;
+       #else
+               config.sound_frequency = 6;     // 48KHz
+       #endif
+               config.sound_latency = 1;       // 100msec
+               config.sound_strict_rendering = true;
+               config.sound_device_num = 0; // Add 20190221
+       #ifdef USE_FLOPPY_DISK
+               config.sound_noise_fdd = true;
+       #endif
+       #ifdef USE_TAPE
+               config.sound_noise_cmt = true;
+               config.sound_play_tape = true;
+       #endif
+       // input
+       #ifdef USE_JOYSTICK
+               for(int i = 0; i < 4; i++) {
+                       for(int j = 0; j < 16; j++) {
+                               config.joy_buttons[i][j] = (i << 5) | j;
+                       }
                }
-       }
-#endif
+               config.use_joy_to_key = false;
+               config.joy_to_key_type = 2;
+               config.joy_to_key_numpad5 = false;
+               config.joy_to_key_buttons[0] = -('Z');
+               config.joy_to_key_buttons[1] = -('X');
+       #endif
+       // debug
+       config.special_debug_fdc = false;
+       config.print_statistics = false;
+       
+       // win32
+       #if defined(_WIN32) && !defined(_USE_QT)
+               #ifndef ONE_BOARD_MICRO_COMPUTER
+                       config.use_d3d9 = true;
+               #endif
+               config.use_dinput = true;
+               config.show_status_bar = true;
+       #endif
+       
+       // qt
+       #ifdef _USE_QT
+               config.use_separate_thread_draw = true;
+               config.use_osd_virtual_media = true;            
+               config.render_platform = CONFIG_RENDER_PLATFORM_OPENGL_ES;
+               config.render_major_version = 2; // For crash with some devices.
+               config.render_minor_version = 0;
+               config.rendering_type = CONFIG_RENDER_TYPE_STD;
+               
+               config.use_opengl_scanline = false;
+               config.opengl_scanline_vert = false;
+               config.opengl_scanline_horiz = false;
+               config.use_opengl_filters = false;
+               config.opengl_filter_num = 0;
+               config.focus_with_click = false;
+               
+               config.video_width = 640;
+               config.video_height = 480;
+               config.video_codec_type = 0; // MPEG4
+       
+               config.video_h264_bitrate = 512;
+               config.video_h264_bframes = 4;
+               config.video_h264_b_adapt = 2;
+               config.video_h264_minq = 14;
+               config.video_h264_maxq = 25;
+               config.video_h264_subme = 8;
+               
+               config.video_mpeg4_bitrate = 512;
+               config.video_mpeg4_bframes = 4;
+               config.video_mpeg4_minq = 1;
+               config.video_mpeg4_maxq = 20;
+               
+               config.audio_codec_type = 0;
+               config.video_threads = 0;
+               config.audio_bitrate = 160;
+               config.video_frame_rate = 30;
+               config.log_to_syslog = false;
+               config.log_to_console = true;
+               for(int ii = 0; ii < (CSP_LOG_TYPE_VM_DEVICE_END - CSP_LOG_TYPE_VM_DEVICE_0 + 1) ; ii++) {
+                       for(int jj = 0; jj < 8; jj++) {
+                               config.dev_log_to_syslog[ii][jj] = true;
+                               config.dev_log_to_console[ii][jj] = true;
+                               config.dev_log_recording[ii][jj] = true;
+                       }
+               }
+               config.state_log_to_console = false;
+               config.state_log_to_syslog = false;
+               config.state_log_to_recording = false; 
+               
+               config.rendering_type = CONFIG_RENDER_TYPE_STD;
+               config.virtual_media_position = 2; // Down.
+               for(int drv = 0; drv < 16; drv++) {
+                       config.disk_count_immediate[drv] = false;
+               }
+               // Extra UI
+               config.cursor_as_ten_key = CONFIG_CURSOR_AS_CURSOR;
+               memset(config.debugwindow_font, 0x00, sizeof(config.debugwindow_font));
+               memset(config.logwindow_font, 0x00, sizeof(config.logwindow_font));
+               
+       #if defined(_FM7) || defined(_FMNEW7) || defined(_FM8) \
+           || defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)             
+               config.numpad_enter_as_fullkey = false;
+       #else
+               config.numpad_enter_as_fullkey = true;
+       #endif
+               config.host_keyboard_type = CONFIG_HOST_KEYBOARD_AT_109JP;
+#endif 
 }
 
-void load_config()
+void load_config(const _TCHAR *config_path)
 {
        int drv, i;
        // initial settings
-       init_config();
-       
-       // get config path
-
-#if defined(_USE_AGAR) || defined(_USE_QT) 
-       char app_path2[_MAX_PATH], *ptr;
-        FILEIO *config_path = new FILEIO();
-   
-        memset(app_path2, 0x00, _MAX_PATH);
-        cpp_confdir.copy(app_path2, _MAX_PATH, 0);
-        
-        strncat(app_path2, CONFIG_NAME, _MAX_PATH);
-        strncat(app_path2, ".ini", _MAX_PATH);
-
-        AGAR_DebugLog(AGAR_LOG_INFO, "Try to read config: %s", app_path2);
-        if(!config_path->Fopen(app_path2, FILEIO_READ_ASCII)) return;
-#else
-       _TCHAR app_path[_MAX_PATH], config_path[_MAX_PATH], *ptr;
-       memset(config_path, 0x00, _MAX_PATH);
-       GetModuleFileName(NULL, config_path, _MAX_PATH);
-       GetFullPathName(config_path, _MAX_PATH, app_path, &ptr);
-       *ptr = _T('\0');
-       _stprintf_s(config_path, _MAX_PATH, _T("%s%s.ini"), app_path, _T(CONFIG_NAME));
-#endif
-   
+       initialize_config();
        
        // control
-       config.use_direct_input = GetPrivateProfileBool(_T("Control"), _T("UseDirectInput"), config.use_direct_input, config_path);
-       config.disable_dwm = GetPrivateProfileBool(_T("Control"), _T("DisableDwm"), config.disable_dwm, config_path);
-       
-#ifdef USE_BOOT_MODE
-       config.boot_mode = GetPrivateProfileInt(_T("Control"), _T("BootMode"), config.boot_mode, config_path);
-#endif
-#ifdef USE_CPU_TYPE
-       config.cpu_type = GetPrivateProfileInt(_T("Control"), _T("CPUType"), config.cpu_type, config_path);
-#endif
-#ifdef USE_DIPSWITCH
-       config.dipswitch = GetPrivateProfileInt(_T("Control"), _T("DipSwitch"), config.dipswitch, config_path);
-#endif
-#ifdef USE_DEVICE_TYPE
-       config.device_type = GetPrivateProfileInt(_T("Control"), _T("DeviceType"), config.device_type, config_path);
-#endif
-#ifdef USE_DRIVE_TYPE
-       config.drive_type = GetPrivateProfileInt(_T("Control"), _T("DriveType"), config.drive_type, config_path);
-#endif
-#ifdef USE_FD1
-       {
-               _TCHAR _tag[128];
-               for(drv = 0; drv < 8; drv++) {
-                       memset(_tag, 0x00, sizeof(_tag));
-                       _stprintf_s(_tag, 64, _T("IgnoreCRC_%d"), drv + 1);
-                       config.ignore_crc[drv] = GetPrivateProfileBool(_T("Control"), _tag, config.ignore_crc[drv], config_path);
+       #ifdef USE_BOOT_MODE
+               config.boot_mode = MyGetPrivateProfileInt(_T("Control"), _T("BootMode"), config.boot_mode, config_path);
+       #endif
+       #ifdef USE_CPU_TYPE
+               config.cpu_type = MyGetPrivateProfileInt(_T("Control"), _T("CPUType"), config.cpu_type, config_path);
+       #endif
+       #ifdef USE_DIPSWITCH
+               config.dipswitch = MyGetPrivateProfileInt(_T("Control"), _T("DipSwitch"), config.dipswitch, config_path);
+       #endif
+       #ifdef USE_DEVICE_TYPE
+               config.device_type = MyGetPrivateProfileInt(_T("Control"), _T("DeviceType"), config.device_type, config_path);
+       #endif
+       #ifdef USE_DRIVE_TYPE
+               config.drive_type = MyGetPrivateProfileInt(_T("Control"), _T("DriveType"), config.drive_type, config_path);
+       #endif
+       #ifdef USE_KEYBOARD_TYPE
+               config.keyboard_type = MyGetPrivateProfileInt(_T("Control"), _T("KeyboardType"), config.keyboard_type, config_path);
+       #endif
+       #ifdef USE_MOUSE_TYPE
+               config.mouse_type = MyGetPrivateProfileInt(_T("Control"), _T("MouseType"), config.mouse_type, config_path);
+       #endif
+       #ifdef USE_JOYSTICK_TYPE
+               config.joystick_type = MyGetPrivateProfileInt(_T("Control"), _T("JoystickType"), config.joystick_type, config_path);
+       #endif
+       #ifdef USE_SOUND_TYPE
+               config.sound_type = MyGetPrivateProfileInt(_T("Control"), _T("SoundType"), config.sound_type, config_path);
+       #endif
+       #ifdef USE_MONITOR_TYPE
+               config.monitor_type = MyGetPrivateProfileInt(_T("Control"), _T("MonitorType"), config.monitor_type, config_path);
+       #endif
+       #ifdef USE_SCANLINE
+               config.scan_line = MyGetPrivateProfileBool(_T("Control"), _T("ScanLine"), config.scan_line, config_path);
+       #endif
+       #ifdef USE_PRINTER
+               config.printer_type = MyGetPrivateProfileInt(_T("Control"), _T("PrinterType"), config.printer_type, config_path);
+       #endif
+       #ifdef USE_FLOPPY_DISK
+               for(int drv = 0; drv < USE_FLOPPY_DISK; drv++) {
+                       config.correct_disk_timing[drv] = MyGetPrivateProfileBool(_T("Control"), create_string(_T("CorrectDiskTiming%d"), drv + 1), config.correct_disk_timing[drv], config_path);
+                       config.ignore_disk_crc[drv] = MyGetPrivateProfileBool(_T("Control"), create_string(_T("IgnoreDiskCRC%d"), drv + 1), config.ignore_disk_crc[drv], config_path);
+               #ifdef _USE_QT
+                       config.disk_count_immediate[drv] = MyGetPrivateProfileBool(_T("Control"), create_string(_T("DiskIncrementImmediate%d"), drv + 1), config.disk_count_immediate[drv], config_path);
+               #endif
                }
-       }
-#endif
-#ifdef USE_TAPE
-       config.tape_sound = GetPrivateProfileBool(_T("Control"), _T("TapeSound"), config.tape_sound, config_path);
-       config.wave_shaper = GetPrivateProfileBool(_T("Control"), _T("WaveShaper"), config.wave_shaper, config_path);
-       config.direct_load_mzt = GetPrivateProfileBool(_T("Control"), _T("DirectLoadMZT"), config.direct_load_mzt, config_path);
-       config.baud_high = GetPrivateProfileBool(_T("Control"), _T("BaudHigh"), config.baud_high, config_path);
-#endif
-       
-       // recent files
-#ifdef USE_CART1
-       GetPrivateProfileString(_T("RecentFiles"), _T("InitialCartDir"), _T(""), config.initial_cart_dir, _MAX_PATH, config_path);
-       for(drv = 0; drv < MAX_CART; drv++) {
-               for(i = 0; i < MAX_HISTORY; i++) {
-                       _TCHAR name[64];
-                       _stprintf_s(name, 64, _T("RecentCartPath%d_%d"), drv + 1, i + 1);
-//                     sprintf(name, _T("RecentCartPath%d_%d"), drv + 1, i + 1);
-                       GetPrivateProfileString(_T("RecentFiles"), name, _T(""), config.recent_cart_path[drv][i], _MAX_PATH, config_path);
+       #endif
+       #ifdef USE_TAPE
+               for(int drv = 0; drv < USE_TAPE; drv++) {
+                       config.wave_shaper[drv] = MyGetPrivateProfileBool(_T("Control"), create_string(_T("WaveShaper%d"), drv + 1), config.wave_shaper[drv], config_path);
+                       config.direct_load_mzt[drv] = MyGetPrivateProfileBool(_T("Control"), create_string(_T("DirectLoadMZT%d"), drv + 1), config.direct_load_mzt[drv], config_path);
+                       config.baud_high[drv] = MyGetPrivateProfileBool(_T("Control"), create_string(_T("BaudHigh%d"), drv + 1), config.baud_high[drv], config_path);
                }
-       }
-#endif
-#ifdef USE_FD1
-       GetPrivateProfileString(_T("RecentFiles"), _T("InitialDiskDir"), _T(""), config.initial_disk_dir, _MAX_PATH, config_path);
-        get_parent_dir(config.initial_disk_dir);
-       for(drv = 0; drv < MAX_FD; drv++) {
-               for(i = 0; i < MAX_HISTORY; i++) {
-                       _TCHAR name[64];
-//                     sprintf(name, _T("RecentDiskPath%d_%d"), drv + 1, i + 1);
-                       _stprintf_s(name, 64, _T("RecentDiskPath%d_%d"), drv + 1, i + 1);
-                       GetPrivateProfileString(_T("RecentFiles"), name, _T(""), config.recent_disk_path[drv][i], _MAX_PATH, config_path);
+       #endif
+       config.compress_state = MyGetPrivateProfileBool(_T("Control"), _T("CompressState"), config.compress_state, config_path);                
+               // recent files
+       #ifdef USE_CART
+               MyGetPrivateProfileString(_T("RecentFiles"), _T("InitialCartDir"), _T(""), config.initial_cart_dir, _MAX_PATH, config_path);
+               for(int drv = 0; drv < USE_CART; drv++) {
+                       for(int i = 0; i < MAX_HISTORY; i++) {
+                               MyGetPrivateProfileString(_T("RecentFiles"), create_string(_T("RecentCartPath%d_%d"), drv + 1, i + 1), _T(""), config.recent_cart_path[drv][i], _MAX_PATH, config_path);
+                       }
                }
-       }
-#endif
-#ifdef USE_QD1
-       GetPrivateProfileString(_T("RecentFiles"), _T("InitialQuickDiskDir"), _T(""), config.initial_quickdisk_dir, _MAX_PATH, config_path);
-       for(drv = 0; drv < MAX_QD; drv++) {
-               for(i = 0; i < MAX_HISTORY; i++) {
-                       _TCHAR name[64];
-//                     sprintf(name, _T("RecentQuickDiskPath%d_%d"), drv + 1, i + 1);
-                       _stprintf_s(name, 64, _T("RecentQuickDiskPath%d_%d"), drv + 1, i + 1);
-                       GetPrivateProfileString(_T("RecentFiles"), name, _T(""), config.recent_quickdisk_path[drv][i], _MAX_PATH, config_path);
+       #endif
+       #ifdef USE_FLOPPY_DISK
+               MyGetPrivateProfileString(_T("RecentFiles"), _T("InitialDiskDir"), _T(""), config.initial_floppy_disk_dir, _MAX_PATH, config_path);
+               for(int drv = 0; drv < USE_FLOPPY_DISK; drv++) {
+                       for(int i = 0; i < MAX_HISTORY; i++) {
+                               MyGetPrivateProfileString(_T("RecentFiles"), create_string(_T("RecentDiskPath%d_%d"), drv + 1, i + 1), _T(""), config.recent_floppy_disk_path[drv][i], _MAX_PATH, config_path);
+                       }
                }
-       }
-#endif
-#ifdef USE_TAPE
-       GetPrivateProfileString(_T("RecentFiles"), _T("InitialTapeDir"), _T(""), config.initial_tape_dir, _MAX_PATH, config_path);
-       for(i = 0; i < MAX_HISTORY; i++) {
-               _TCHAR name[64];
-//             sprintf(name, _T("RecentTapePath1_%d"), i + 1);
-               _stprintf_s(name, 64, _T("RecentTapePath1_%d"), i + 1);
-               GetPrivateProfileString(_T("RecentFiles"), name, _T(""), config.recent_tape_path[i], _MAX_PATH, config_path);
-       }
-#endif
-#ifdef USE_LASER_DISC
-       GetPrivateProfileString(_T("RecentFiles"), _T("InitialLaserDiscDir"), _T(""), config.initial_laser_disc_dir, _MAX_PATH, config_path);
-       for(int i = 0; i < MAX_HISTORY; i++) {
-               _TCHAR name[64];
-//             sprintf(name, _T("RecentLaserDiscPath1_%d"), i + 1);
-               _stprintf_s(name, 64, _T("RecentLaserDiscPath1_%d"), i + 1);
-               GetPrivateProfileString(_T("RecentFiles"), name, _T(""), config.recent_laser_disc_path[i], _MAX_PATH, config_path);
-       }
-#endif
-#ifdef USE_BINARY_FILE1
-       GetPrivateProfileString(_T("RecentFiles"), _T("InitialBinaryDir"), _T(""), config.initial_binary_dir, _MAX_PATH, config_path);
-       for(drv = 0; drv < MAX_BINARY; drv++) {
-               for(i = 0; i < MAX_HISTORY; i++) {
-                       _TCHAR name[64];
-//                     sprintf(name, _T("RecentBinaryPath%d_%d"), drv + 1, i + 1);
-                       _stprintf_s(name, 64, _T("RecentBinaryPath%d_%d"), drv + 1, i + 1);
-                       GetPrivateProfileString(_T("RecentFiles"), name, _T(""), config.recent_binary_path[drv][i], _MAX_PATH, config_path);
+       #endif
+       #ifdef USE_QUICK_DISK
+               MyGetPrivateProfileString(_T("RecentFiles"), _T("InitialQuickDiskDir"), _T(""), config.initial_quick_disk_dir, _MAX_PATH, config_path);
+               for(int drv = 0; drv < USE_QUICK_DISK; drv++) {
+                       for(int i = 0; i < MAX_HISTORY; i++) {
+                               MyGetPrivateProfileString(_T("RecentFiles"), create_string(_T("RecentQuickDiskPath%d_%d"), drv + 1, i + 1), _T(""), config.recent_quick_disk_path[drv][i], _MAX_PATH, config_path);
+                       }
                }
-       }
-#endif
+       #endif
+       #ifdef USE_HARD_DISK
+               MyGetPrivateProfileString(_T("RecentFiles"), _T("InitialHardDiskDir"), _T(""), config.initial_hard_disk_dir, _MAX_PATH, config_path);
+               for(int drv = 0; drv < USE_HARD_DISK; drv++) {
+                       for(int i = 0; i < MAX_HISTORY; i++) {
+                               MyGetPrivateProfileString(_T("RecentFiles"), create_string(_T("RecentHardDiskPath%d_%d"), drv + 1, i + 1), _T(""), config.recent_hard_disk_path[drv][i], _MAX_PATH, config_path);
+                       }
+                       MyGetPrivateProfileString(_T("RecentFiles"), create_string(_T("LastHardDiskPath%d"), drv + 1), _T(""), config.last_hard_disk_path[drv], _MAX_PATH, config_path);
+               }
+       #endif
+       #ifdef USE_TAPE
+               MyGetPrivateProfileString(_T("RecentFiles"), _T("InitialTapeDir"), _T(""), config.initial_tape_dir, _MAX_PATH, config_path);
+               for(int drv = 0; drv < USE_TAPE; drv++) {
+                       for(int i = 0; i < MAX_HISTORY; i++) {
+                               MyGetPrivateProfileString(_T("RecentFiles"), create_string(_T("RecentTapePath%d_%d"), drv + 1, i + 1), _T(""), config.recent_tape_path[drv][i], _MAX_PATH, config_path);
+                       }
+               }
+       #endif
+       #ifdef USE_COMPACT_DISC
+               MyGetPrivateProfileString(_T("RecentFiles"), _T("InitialCompactDiscDir"), _T(""), config.initial_compact_disc_dir, _MAX_PATH, config_path);
+               for(int drv = 0; drv < USE_COMPACT_DISC; drv++) {
+                       for(int i = 0; i < MAX_HISTORY; i++) {
+                               MyGetPrivateProfileString(_T("RecentFiles"), create_string(_T("RecentCompactDiscPath%d_%d"), drv + 1, i + 1), _T(""), config.recent_compact_disc_path[drv][i], _MAX_PATH, config_path);
+                       }
+               }
+       #endif
+       #ifdef USE_LASER_DISC
+               MyGetPrivateProfileString(_T("RecentFiles"), _T("InitialLaserDiscDir"), _T(""), config.initial_laser_disc_dir, _MAX_PATH, config_path);
+               for(int drv = 0; drv < USE_LASER_DISC; drv++) {
+                       for(int i = 0; i < MAX_HISTORY; i++) {
+                               MyGetPrivateProfileString(_T("RecentFiles"), create_string(_T("RecentLaserDiscPath%d_%d"), drv + 1, i + 1), _T(""), config.recent_laser_disc_path[drv][i], _MAX_PATH, config_path);
+                       }
+               }
+       #endif
+       #ifdef USE_BINARY_FILE
+               MyGetPrivateProfileString(_T("RecentFiles"), _T("InitialBinaryDir"), _T(""), config.initial_binary_dir, _MAX_PATH, config_path);
+               for(int drv = 0; drv < USE_BINARY_FILE; drv++) {
+                       for(int i = 0; i < MAX_HISTORY; i++) {
+                               MyGetPrivateProfileString(_T("RecentFiles"), create_string(_T("RecentBinaryPath%d_%d"), drv + 1, i + 1), _T(""), config.recent_binary_path[drv][i], _MAX_PATH, config_path);
+                       }
+               }
+       #endif
+       #ifdef USE_BUBBLE
+               MyGetPrivateProfileString(_T("RecentFiles"), _T("InitialBubbleDir"), _T(""), config.initial_bubble_casette_dir, _MAX_PATH, config_path);
+               for(int drv = 0; drv < USE_BUBBLE; drv++) {
+                       for(int i = 0; i < MAX_HISTORY; i++) {
+                               MyGetPrivateProfileString(_T("RecentFiles"), create_string(_T("RecentBubblePath%d_%d"), drv + 1, i + 1), _T(""), config.recent_bubble_casette_path[drv][i], _MAX_PATH, config_path);
+                       }
+               }
+       #endif
        
        // screen
-#if !(defined(USE_BITMAP) || defined(USE_LED))
-       config.window_mode = GetPrivateProfileInt(_T("Screen"), _T("WindowMode"), config.window_mode, config_path);
-       config.use_d3d9 = GetPrivateProfileBool(_T("Screen"), _T("UseD3D9"), config.use_d3d9, config_path);
-       config.wait_vsync = GetPrivateProfileBool(_T("Screen"), _T("WaitVSync"), config.wait_vsync, config_path);
-       config.stretch_type = GetPrivateProfileInt(_T("Screen"), _T("StretchType"), config.stretch_type, config_path);
-#else
-       config.window_mode = GetPrivateProfileInt(_T("Screen"), _T("WindowMode"), config.window_mode, config_path);
-#endif
-#ifdef USE_MONITOR_TYPE
-       config.monitor_type = GetPrivateProfileInt(_T("Screen"), _T("MonitorType"), config.monitor_type, config_path);
-#endif
-#ifdef USE_CRT_FILTER
-       config.crt_filter = GetPrivateProfileBool(_T("Screen"), _T("CRTFilter"), config.crt_filter, config_path);
-#endif
-#ifdef USE_SCANLINE
-       config.scan_line = GetPrivateProfileBool(_T("Screen"), _T("ScanLine"), config.scan_line, config_path);
-#endif
+       #ifndef ONE_BOARD_MICRO_COMPUTER
+               config.window_mode = MyGetPrivateProfileInt(_T("Screen"), _T("WindowMode"), config.window_mode, config_path);
+               config.window_stretch_type = MyGetPrivateProfileInt(_T("Screen"), _T("WindowStretchType"), config.window_stretch_type, config_path);
+               config.fullscreen_stretch_type = MyGetPrivateProfileInt(_T("Screen"), _T("FullScreenStretchType"), config.fullscreen_stretch_type, config_path);
+//             #ifdef USE_SCREEN_ROTATE
+                       config.rotate_type = MyGetPrivateProfileInt(_T("Screen"), _T("RotateType"), config.rotate_type, config_path);
+//             #endif
+       #endif
+
+       
+       // filter
+       #ifdef USE_SCREEN_FILTER
+               config.filter_type = MyGetPrivateProfileInt(_T("Screen"), _T("FilterType"), config.filter_type, config_path);
+       #endif
 
-#ifdef USE_SCREEN_ROTATE
-       config.rotate_type = GetPrivateProfileBool(_T("Screen"), _T("RotateType"), config.rotate_type, config_path);
-#endif
-#if defined(USE_QT)
-       config.use_opengl_scanline = GetPrivateProfileBool(_T("Screen"), _T("UseOpenGLScanLine"),
-                                                                                                          config.use_opengl_scanline, config_path);
-       config.opengl_scanline_vert = GetPrivateProfileBool(_T("Screen"), _T("OpenGLScanLineVert"),
-                                                                                                          config.opengl_scanline_vert, config_path);;
-       config.opengl_scanline_horiz = GetPrivateProfileBool(_T("Screen"), _T("OpenGLScanLineHoriz"),
-                                                                                                          config.opengl_scanline_horiz, config_path);;
-       config.use_opengl_filters = GetPrivateProfileBool(_T("Screen"), _T("UseOpenGLFilters"),
-                                                                                                          config.use_opengl_filters, config_path);
-       config.opengl_filter_num =      GetPrivateProfileInt(_T("Screen"), _T("OpenGlFilterNum"),
-                                                                                                        config.opengl_filter_num, config_path);
-#endif 
        // sound
-       config.sound_frequency = GetPrivateProfileInt(_T("Sound"), _T("Frequency"), config.sound_frequency, config_path);
-       config.sound_latency = GetPrivateProfileInt(_T("Sound"), _T("Latency"), config.sound_latency, config_path);
-#ifdef USE_SOUND_DEVICE_TYPE
-       config.sound_device_type = GetPrivateProfileInt(_T("Sound"), _T("DeviceType"), config.sound_device_type, config_path);
-#endif
-       config.multiple_speakers = GetPrivateProfileBool(_T("Sound"), _T("MultipleSpeakers"),
-                                                                                                        config.multiple_speakers, config_path);
-       config.general_sound_level = GetPrivateProfileInt(_T("Sound"), _T("GeneralSoundLevel"),
-                                                                                                         config.general_sound_level, config_path);
-#ifdef USE_MULTIPLE_SOUNDCARDS
-       {
-               _TCHAR _tag[128];
-               int ii;
-               for(ii = 0; ii < USE_MULTIPLE_SOUNDCARDS; ii++) {
-                       memset(_tag, 0x00, sizeof(_tag));
-                       _stprintf_s(_tag, 64, _T("DeviceVolumeLevel_%d"), ii + 1);
-                       config.sound_device_level[ii] = GetPrivateProfileInt(_T("Sound"), _tag, config.sound_device_level[ii], config_path);
+       config.sound_frequency = MyGetPrivateProfileInt(_T("Sound"), _T("Frequency"), config.sound_frequency, config_path);
+       config.sound_latency = MyGetPrivateProfileInt(_T("Sound"), _T("Latency"), config.sound_latency, config_path);
+       config.sound_strict_rendering = MyGetPrivateProfileInt(_T("Sound"), _T("StrictRendering"), config.sound_strict_rendering, config_path);
+       config.sound_device_num = MyGetPrivateProfileBool(_T("Sound"), _T("DeviceNumber"), config.sound_device_num, config_path);
+       #ifdef USE_FLOPPY_DISK
+               config.sound_noise_fdd = MyGetPrivateProfileBool(_T("Sound"), _T("NoiseFDD"), config.sound_noise_fdd, config_path);;
+       #endif
+       #ifdef USE_TAPE
+               config.sound_noise_cmt = MyGetPrivateProfileBool(_T("Sound"), _T("NoiseCMT"), config.sound_noise_cmt, config_path);;
+               config.sound_play_tape = MyGetPrivateProfileBool(_T("Sound"), _T("PlayTape"), config.sound_play_tape, config_path);
+       #endif
+       #ifdef USE_SOUND_VOLUME
+               for(int i = 0; i < USE_SOUND_VOLUME; i++) {
+                       int tmp_l = MyGetPrivateProfileInt(_T("Sound"), create_string(_T("VolumeLeft%d"), i + 1), config.sound_volume_l[i], config_path);
+                       int tmp_r = MyGetPrivateProfileInt(_T("Sound"), create_string(_T("VolumeRight%d"), i + 1), config.sound_volume_r[i], config_path);
+                       #ifdef _USE_QT
+                               // Note: when using balance , levels are -40±20db to 0±20db.
+                               config.sound_volume_l[i] = max(-60, min(20, tmp_l));
+                               config.sound_volume_r[i] = max(-60, min(20, tmp_r));
+                       #else
+                               config.sound_volume_l[i] = max(-40, min(0, tmp_l));
+                               config.sound_volume_r[i] = max(-40, min(0, tmp_r));
+                       #endif
+               }
+       #endif
+       
+       #if defined(_WIN32) && !defined(_USE_QT)
+               // for compatibilities
+               #ifdef _X1_H_
+                       MyGetPrivateProfileString(_T("Sound"), _T("FMGenDll"), _T("mame2151.dll"), config.mame2151_dll_path, _MAX_PATH, config_path);
+                       my_tcscpy_s(config.mame2608_dll_path, _MAX_PATH, _T("mamefm.dll"));
+               #else
+                       MyGetPrivateProfileString(_T("Sound"), _T("FMGenDll"), _T("mamefm.dll"), config.mame2608_dll_path, _MAX_PATH, config_path);
+                       my_tcscpy_s(config.mame2151_dll_path, _MAX_PATH, _T("mame2151.dll"));
+               #endif
+               MyGetPrivateProfileString(_T("Sound"), _T("YM2151GenDll"), config.mame2151_dll_path, config.mame2151_dll_path, _MAX_PATH, config_path);
+               MyGetPrivateProfileString(_T("Sound"), _T("YM2608GenDll"), config.mame2608_dll_path, config.mame2608_dll_path, _MAX_PATH, config_path);
+       #endif
+
+       // input
+       #ifdef USE_JOYSTICK
+               for(int i = 0; i < 4; i++) {
+                       for(int j = 0; j < 16; j++) {
+                               int old = (i << 4) | j;
+                               old = MyGetPrivateProfileInt(_T("Input"), create_string(_T("JoyButtons%d_%d"), i + 1, j + 1), old, config_path);
+                               old = ((old >> 4) << 5) | (old & 0x0f);
+                               config.joy_buttons[i][j] = MyGetPrivateProfileInt(_T("Input"), create_string(_T("JoyButtonsEx%d_%d"), i + 1, j + 1), old, config_path);
+                       }
+               }
+               config.use_joy_to_key = MyGetPrivateProfileBool(_T("Input"), _T("UseJoyToKey"), config.use_joy_to_key, config_path);
+               config.joy_to_key_type = MyGetPrivateProfileInt(_T("Input"), _T("JoyToKeyType"), config.joy_to_key_type, config_path);
+               config.joy_to_key_numpad5 = MyGetPrivateProfileBool(_T("Input"), _T("JoyToKeyNumPad5"), config.joy_to_key_numpad5, config_path);
+               for(int i = 0; i < 16; i++) {
+                       config.joy_to_key_buttons[i] = MyGetPrivateProfileInt(_T("Input"), create_string(_T("JoyToKeyButtons%d"), i + 1), config.joy_to_key_buttons[i], config_path);
+               }
+       #endif
+       // debug
+       #ifdef USE_FLOPPY_DISK
+               config.special_debug_fdc =      MyGetPrivateProfileInt(_T("Debug"), _T("SpecialDebugFDC"), config.special_debug_fdc, config_path);
+       #endif
+               config.print_statistics = MyGetPrivateProfileBool(_T("Debug"), _T("PrintCPUStatistics"), config.print_statistics, config_path);
+       // printer
+       #ifdef USE_PRINTER
+               MyGetPrivateProfileString(_T("Printer"), _T("PrinterDll"), _T("printer.dll"), config.printer_dll_path, _MAX_PATH, config_path);
+       #endif
+
+       // win32
+       #if defined(_WIN32) && !defined(_USE_QT)
+               #ifndef ONE_BOARD_MICRO_COMPUTER
+                       config.use_d3d9 = MyGetPrivateProfileBool(_T("Win32"), _T("UseDirect3D9"), config.use_d3d9, config_path);
+                       config.wait_vsync = MyGetPrivateProfileBool(_T("Win32"), _T("WaitVSync"), config.wait_vsync, config_path);
+               #endif
+               config.use_dinput = MyGetPrivateProfileBool(_T("Win32"), _T("UseDirectInput"), config.use_dinput, config_path);
+               config.disable_dwm = MyGetPrivateProfileBool(_T("Win32"), _T("DisableDwm"), config.disable_dwm, config_path);
+               config.show_status_bar = MyGetPrivateProfileBool(_T("Win32"), _T("ShowStatusBar"), config.show_status_bar, config_path);
+       #endif
+
+       // qt
+       #ifdef _USE_QT
+               config.use_separate_thread_draw = MyGetPrivateProfileBool(_T("Qt"), _T("UseSeparateThreadDraw"), config.use_separate_thread_draw, config_path);
+               config.use_osd_virtual_media = MyGetPrivateProfileBool(_T("Qt"), _T("UseOSDVirtualMedia"), config.use_osd_virtual_media, config_path); 
+               config.use_opengl_scanline = MyGetPrivateProfileBool(_T("Qt"), _T("UseOpenGLScanLine"), config.use_opengl_scanline, config_path);
+               config.opengl_scanline_vert = MyGetPrivateProfileBool(_T("Qt"), _T("OpenGLScanLineVert"), config.opengl_scanline_vert, config_path);;
+               config.opengl_scanline_horiz = MyGetPrivateProfileBool(_T("Qt"), _T("OpenGLScanLineHoriz"), config.opengl_scanline_horiz, config_path);;
+               config.use_opengl_filters = MyGetPrivateProfileBool(_T("Qt"), _T("UseOpenGLFilters"), config.use_opengl_filters, config_path);
+               config.opengl_filter_num = MyGetPrivateProfileInt(_T("Qt"), _T("OpenGLFilterNum"), config.opengl_filter_num, config_path);
+               config.render_platform = MyGetPrivateProfileInt(_T("Qt"), _T("RenderPlatform"), config.render_platform, config_path);
+               config.render_major_version = MyGetPrivateProfileInt(_T("Qt"), _T("RenderMajorVersion"), config.render_major_version, config_path);
+               config.render_minor_version = MyGetPrivateProfileInt(_T("Qt"), _T("RenderMinorVersion"), config.render_minor_version, config_path);
+               config.rendering_type = MyGetPrivateProfileInt(_T("Qt"), _T("RenderType"), config.rendering_type, config_path);
+
+               config.general_sound_level = MyGetPrivateProfileInt(_T("Qt"), _T("GeneralSoundLevel"), config.general_sound_level, config_path);
+               config.focus_with_click = MyGetPrivateProfileBool(_T("Qt"), _T("FocusWithClick"), config.focus_with_click, config_path);
+               
+               if(config.rendering_type < 0) config.rendering_type = 0;
+               if(config.rendering_type >= CONFIG_RENDER_TYPE_END) config.rendering_type = CONFIG_RENDER_TYPE_END - 1;
+               // Assigning joysticks.
+               for(i = 0; i < 16; i++) {
+                       _TCHAR name[256];
+                       my_stprintf_s(name, 256, _T("AssignedJoystick"), i + 1);
+                       MyGetPrivateProfileString(_T("Qt"), (const _TCHAR *)name, _T(""),
+                                                                         config.assigned_joystick_name[i], 256, config_path);
                }
-       }
-#endif
-#if defined(_USE_AGAR) || defined(_USE_QT)
-     config_path->Fclose();
-     delete config_path;
-     AGAR_DebugLog(AGAR_LOG_INFO, "Read Done.");
-#endif
-}
 
-void save_config()
+               // Extra UI
+               config.swap_kanji_pause = MyGetPrivateProfileBool(_T("Qt"), _T("SwapKanjiPause"), config.swap_kanji_pause, config_path);
+               config.cursor_as_ten_key = MyGetPrivateProfileInt(_T("Qt"), _T("CursorAsTenKey"), config.cursor_as_ten_key, config_path);
+               config.numpad_enter_as_fullkey = MyGetPrivateProfileBool(_T("Qt"), _T("NumpadEnterAsFullKey"), config.numpad_enter_as_fullkey, config_path);
+               config.host_keyboard_type = MyGetPrivateProfileInt(_T("Qt"), _T("HostKeyboardType"), config.host_keyboard_type, config_path);
+               MyGetPrivateProfileString(_T("Qt"), _T("DebugWindowFont"), _T("Sans"), config.debugwindow_font, sizeof(config.debugwindow_font) - 1, config_path);
+               config.debugwindow_width = MyGetPrivateProfileInt(_T("Qt"), _T("DebugWindowWidth"), 800, config_path);
+               config.debugwindow_height = MyGetPrivateProfileInt(_T("Qt"), _T("DebugWindowHeight"), 500, config_path);
+               MyGetPrivateProfileString(_T("Qt"), _T("LogWindowFont"), _T("Sans"), config.logwindow_font, sizeof(config.logwindow_font) - 1, config_path);
+               config.logwindow_width = MyGetPrivateProfileInt(_T("Qt"), _T("LogWindowWidth"), 800, config_path);
+               config.logwindow_height = MyGetPrivateProfileInt(_T("Qt"), _T("LogWindowHeight"), 500, config_path);
+
+               
+               // Movie load/save.
+               config.video_width   = MyGetPrivateProfileInt(_T("Qt"), _T("VideoWidth"), config.video_width, config_path);
+               if(config.video_width < 128) config.video_width = 128;
+               config.video_height  = MyGetPrivateProfileInt(_T("Qt"), _T("VideoHeight"), config.video_height, config_path);
+               if(config.video_height < 80) config.video_height = 80;
+               
+               config.video_codec_type = MyGetPrivateProfileInt(_T("Qt"), _T("VideoCodecType"), config.video_codec_type, config_path);
+               if(config.video_codec_type > 1) config.video_codec_type = 1;
+               if(config.video_codec_type < 0) config.video_codec_type = 0;
+               
+               config.audio_codec_type = MyGetPrivateProfileInt(_T("Qt"), _T("AudioCodecType"), config.audio_codec_type, config_path);
+               if(config.video_codec_type > 2) config.audio_codec_type = 2;
+               if(config.video_codec_type < 0) config.audio_codec_type = 0;
+               
+               config.video_h264_bitrate = MyGetPrivateProfileInt(_T("Qt"), _T("H264Bitrate"), config.video_h264_bitrate, config_path);
+               if(config.video_h264_bitrate < 64) config.video_h264_bitrate = 64;
+               
+               config.video_h264_bframes = MyGetPrivateProfileInt(_T("Qt"), _T("H264BFrames"), config.video_h264_bframes, config_path);
+               if(config.video_h264_bframes < 0) config.video_h264_bframes = 0;
+               if(config.video_h264_bframes > 10) config.video_h264_bframes = 10;
+               
+               config.video_h264_b_adapt = MyGetPrivateProfileInt(_T("Qt"), _T("H264BAdapt"), config.video_h264_b_adapt, config_path);
+               if(config.video_h264_b_adapt < 0) config.video_h264_b_adapt = 0;
+               if(config.video_h264_b_adapt > 2) config.video_h264_b_adapt = 2;
+               
+               config.video_h264_subme   = MyGetPrivateProfileInt(_T("Qt"), _T("H264Subme"), config.video_h264_subme, config_path);
+               if(config.video_h264_subme < 0) config.video_h264_subme = 0;
+               if(config.video_h264_subme > 11) config.video_h264_subme = 11;
+               
+               config.video_h264_minq   = MyGetPrivateProfileInt(_T("Qt"), _T("H264MinQ"), config.video_h264_minq, config_path);
+               if(config.video_h264_minq < 0) config.video_h264_minq = 0;
+               if(config.video_h264_minq > 63) config.video_h264_minq = 63;
+               
+               config.video_h264_maxq   = MyGetPrivateProfileInt(_T("Qt"), _T("H264MaxQ"), config.video_h264_maxq, config_path);
+               if(config.video_h264_maxq < 0) config.video_h264_maxq = 0;
+               if(config.video_h264_maxq > 63) config.video_h264_maxq = 63;
+               
+               config.video_mpeg4_bitrate = MyGetPrivateProfileInt(_T("Qt"), _T("MPEG4Bitrate"), config.video_mpeg4_bitrate, config_path);
+               if(config.video_mpeg4_bitrate < 64) config.video_mpeg4_bitrate = 64;
+               
+               config.video_mpeg4_bframes = MyGetPrivateProfileInt(_T("Qt"), _T("MPEG4BFrames"), config.video_mpeg4_bframes, config_path);
+               if(config.video_mpeg4_bframes < 0) config.video_mpeg4_bframes = 0;
+               if(config.video_mpeg4_bframes > 10) config.video_mpeg4_bframes = 10;
+               
+               config.video_mpeg4_minq   = MyGetPrivateProfileInt(_T("Qt"), _T("MPEG4MinQ"), config.video_mpeg4_minq, config_path);
+               if(config.video_mpeg4_minq < 1) config.video_mpeg4_minq = 1;
+               if(config.video_mpeg4_minq > 31) config.video_mpeg4_minq = 31;
+               
+               config.video_mpeg4_maxq   = MyGetPrivateProfileInt(_T("Qt"), _T("MPEG4MaxQ"), config.video_mpeg4_maxq, config_path);
+               if(config.video_mpeg4_maxq < 1) config.video_mpeg4_maxq = 1;
+               if(config.video_mpeg4_maxq > 31) config.video_mpeg4_maxq = 31;
+               if(config.video_mpeg4_maxq < config.video_mpeg4_minq) {
+                       int n;
+                       n = config.video_mpeg4_maxq;
+                       config.video_mpeg4_maxq  = config.video_mpeg4_minq;
+                       config.video_mpeg4_minq = n;
+               }
+               
+               config.video_threads = MyGetPrivateProfileInt(_T("Qt"), _T("VideoThreads"), config.video_threads, config_path);
+               if(config.video_threads < 0) config.video_threads = 0;
+               if(config.video_threads > 16) config.video_threads = 16;
+               
+               config.audio_bitrate = MyGetPrivateProfileInt(_T("Qt"), _T("AudioBitrate"), config.audio_bitrate, config_path);
+               if(config.audio_bitrate < 16) config.audio_bitrate = 16;
+               if(config.audio_bitrate > 448) config.audio_bitrate = 448;
+               
+               config.video_frame_rate = MyGetPrivateProfileInt(_T("Qt"), _T("VideoFramerate"), config.video_frame_rate, config_path);
+               if(config.video_frame_rate < 15) config.video_frame_rate = 15;
+               if(config.video_frame_rate > 75) config.video_frame_rate = 75;
+               // Logging
+               config.log_to_syslog = MyGetPrivateProfileBool(_T("Qt"), _T("WriteToSyslog"), config.log_to_syslog, config_path);
+               config.log_to_console = MyGetPrivateProfileBool(_T("Qt"), _T("WriteToConsole"), config.log_to_console, config_path);
+               
+               for(int ii = 0; ii < (CSP_LOG_TYPE_VM_DEVICE_END - CSP_LOG_TYPE_VM_DEVICE_0 + 1) ; ii++) {
+                       uint32_t flags = 0;
+                       flags = MyGetPrivateProfileInt(_T("Qt"), create_string(_T("SyslogEnabled%d"), ii), 0xffff, config_path);
+                       for(int jj = 0; jj < 8; jj++) {
+                               config.dev_log_to_syslog[ii][jj] = ((flags & 0x0080) != 0) ? true : false;
+                               flags <<= 1;
+                       }
+                       flags = 0;
+                       flags = MyGetPrivateProfileInt(_T("Qt"), create_string(_T("ConsoleLogEnabled%d"), ii), 0xffff, config_path);
+                       for(int jj = 0; jj < 8; jj++) {
+                               config.dev_log_to_console[ii][jj] = ((flags & 0x0080) != 0) ? true : false;
+                               flags <<= 1;
+                       }
+                       flags = MyGetPrivateProfileInt(_T("Qt"), create_string(_T("RecordLogEnabled%d"), ii), 0xffff, config_path);
+                       for(int jj = 0; jj < 8; jj++) {
+                               config.dev_log_recording[ii][jj] = ((flags & 0x0080) != 0) ? true : false;
+                               flags <<= 1;
+                       }
+               }
+               config.state_log_to_console = MyGetPrivateProfileBool(_T("Qt"), _T("StateLogToConsole"), config.state_log_to_console, config_path);;
+               config.state_log_to_syslog = MyGetPrivateProfileBool(_T("Qt"), _T("StateLogToSyslog"), config.state_log_to_syslog, config_path);;
+               config.state_log_to_recording = MyGetPrivateProfileBool(_T("Qt"), _T("StateLogToRecording"), config.state_log_to_recording, config_path);;
+
+               config.virtual_media_position = MyGetPrivateProfileInt(_T("Qt"), _T("UiVirtualMediaPosition"), config.virtual_media_position, config_path);
+               //csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Read config done.");
+       #endif
+}
+               
+void save_config(const _TCHAR *config_path)
 {
        int drv, i;
-       // get config path
-#if defined(_USE_AGAR) || defined(_USE_QT)
-       char app_path2[_MAX_PATH], *ptr;
-        FILEIO *config_path = new FILEIO();
-   
-        app_path2[0] = '\0';
-               //GetFullPathName(config_path, _MAX_PATH, app_path, &ptr);
-        memset(app_path2, 0x00, _MAX_PATH);
-        cpp_confdir.copy(app_path2, _MAX_PATH, 0);
-        
-        strncat(app_path2, CONFIG_NAME, _MAX_PATH);
-        strncat(app_path2, ".ini", _MAX_PATH);
-
-        AGAR_DebugLog(AGAR_LOG_INFO, "Try to write config: %s", app_path2);
-        if(config_path->Fopen(app_path2, FILEIO_WRITE_ASCII) != true) return;
-#else
-        _TCHAR app_path[_MAX_PATH], config_path[_MAX_PATH], *ptr;
-       memset(config_path, 0x00, _MAX_PATH);
-       GetModuleFileName(NULL, config_path, _MAX_PATH);
-       GetFullPathName(config_path, _MAX_PATH, app_path, &ptr);
-       *ptr = _T('\0');
-       _stprintf_s(config_path, _MAX_PATH, _T("%s%s.ini"), app_path, _T(CONFIG_NAME));
-#endif 
-       // control
-       WritePrivateProfileBool(_T("Control"), _T("UseDirectInput"), config.use_direct_input, config_path);
-       WritePrivateProfileBool(_T("Control"), _T("DisableDwm"), config.disable_dwm, config_path);
-
-# ifdef USE_BOOT_MODE
-       WritePrivateProfileInt(_T("Control"), _T("BootMode"), config.boot_mode, config_path);
-#endif
-#ifdef USE_CPU_TYPE
-       WritePrivateProfileInt(_T("Control"), _T("CPUType"), config.cpu_type, config_path);
-#endif
-#ifdef USE_DIPSWITCH
-       WritePrivateProfileInt(_T("Control"), _T("DipSwitch"), config.dipswitch, config_path);
-#endif
-#ifdef USE_DEVICE_TYPE
-       WritePrivateProfileInt(_T("Control"), _T("DeviceType"), config.device_type, config_path);
-#endif
-#ifdef USE_DRIVE_TYPE
-       WritePrivateProfileInt(_T("Control"), _T("DriveType"), config.drive_type, config_path);
-#endif
-#ifdef USE_FD1
+#if !defined(_MSC_VER)
        {
-               _TCHAR _tag[128];
-               for(drv = 0; drv < 8; drv++) {
-                       memset(_tag, 0x00, sizeof(_tag));
-                       _stprintf_s(_tag, 64, _T("IgnoreCRC_%d"), drv + 1);
-                       WritePrivateProfileBool(_T("Control"), _tag, config.ignore_crc[drv], config_path);
+               FILEIO *pt = new FILEIO;
+               if(pt->Fopen(config_path, FILEIO_WRITE_ASCII) != true) {
+                       delete pt;
+                       return;
                }
+               pt->Fclose();
+               delete pt;
        }
        
-#endif
-#ifdef USE_TAPE
-       WritePrivateProfileBool(_T("Control"), _T("TapeSound"), config.tape_sound, config_path);
-       WritePrivateProfileBool(_T("Control"), _T("WaveShaper"), config.wave_shaper, config_path);
-       WritePrivateProfileBool(_T("Control"), _T("DirectLoadMZT"), config.direct_load_mzt, config_path);
-       WritePrivateProfileBool(_T("Control"), _T("BaudHigh"), config.baud_high, config_path);
-#endif
+#endif 
+       // control
+       #ifdef USE_BOOT_MODE
+               MyWritePrivateProfileInt(_T("Control"), _T("BootMode"), config.boot_mode, config_path);
+       #endif
+       #ifdef USE_CPU_TYPE
+               MyWritePrivateProfileInt(_T("Control"), _T("CPUType"), config.cpu_type, config_path);
+       #endif
+       #ifdef USE_DIPSWITCH
+               MyWritePrivateProfileInt(_T("Control"), _T("DipSwitch"), config.dipswitch, config_path);
+       #endif
+       #ifdef USE_DEVICE_TYPE
+               MyWritePrivateProfileInt(_T("Control"), _T("DeviceType"), config.device_type, config_path);
+       #endif
+       #ifdef USE_DRIVE_TYPE
+               MyWritePrivateProfileInt(_T("Control"), _T("DriveType"), config.drive_type, config_path);
+       #endif
+       #ifdef USE_KEYBOARD_TYPE
+               MyWritePrivateProfileInt(_T("Control"), _T("KeyboardType"), config.keyboard_type, config_path);
+       #endif
+       #ifdef USE_MOUSE_TYPE
+               MyWritePrivateProfileInt(_T("Control"), _T("MouseType"), config.mouse_type, config_path);
+       #endif
+       #ifdef USE_JOYSTICK_TYPE
+               MyWritePrivateProfileInt(_T("Control"), _T("JoystickType"), config.joystick_type, config_path);
+       #endif
+       #ifdef USE_SOUND_TYPE
+               MyWritePrivateProfileInt(_T("Control"), _T("SoundType"), config.sound_type, config_path);
+       #endif
+       #ifdef USE_MONITOR_TYPE
+               MyWritePrivateProfileInt(_T("Control"), _T("MonitorType"), config.monitor_type, config_path);
+       #endif
+       #ifdef USE_SCANLINE
+               MyWritePrivateProfileBool(_T("Control"), _T("ScanLine"), config.scan_line, config_path);
+       #endif
+       #ifdef USE_PRINTER
+               MyWritePrivateProfileInt(_T("Control"), _T("PrinterType"), config.printer_type, config_path);
+       #endif
+       #ifdef USE_FLOPPY_DISK
+               for(int drv = 0; drv < USE_FLOPPY_DISK; drv++) {
+                       MyWritePrivateProfileBool(_T("Control"), create_string(_T("CorrectDiskTiming%d"), drv + 1), config.correct_disk_timing[drv], config_path);
+                       MyWritePrivateProfileBool(_T("Control"), create_string(_T("IgnoreDiskCRC%d"), drv + 1), config.ignore_disk_crc[drv], config_path);
+               #ifdef _USE_QT
+                       MyWritePrivateProfileBool(_T("Control"), create_string(_T("DiskIncrementImmediate%d"), drv + 1), config.disk_count_immediate[drv], config_path);
+               #endif
+               }
+       #endif
+       #ifdef USE_TAPE
+               for(int drv = 0; drv < USE_TAPE; drv++) {
+                       MyWritePrivateProfileBool(_T("Control"), create_string(_T("WaveShaper%d"), drv + 1), config.wave_shaper[drv], config_path);
+                       MyWritePrivateProfileBool(_T("Control"), create_string(_T("DirectLoadMZT%d"), drv + 1), config.direct_load_mzt[drv], config_path);
+                       MyWritePrivateProfileBool(_T("Control"), create_string(_T("BaudHigh%d"), drv + 1), config.baud_high[drv], config_path);
+               }
+       #endif
+       MyWritePrivateProfileBool(_T("Control"), _T("CompressState"), config.compress_state, config_path);
+       
+       // recent files
        
        // recent files
-#ifdef USE_CART1
-       WritePrivateProfileString(_T("RecentFiles"), _T("InitialCartDir"), config.initial_cart_dir, config_path);
-       for(drv = 0; drv < MAX_CART; drv++) {
-               for(i = 0; i < MAX_HISTORY; i++) {
-                       _TCHAR name[64];
-                       _stprintf_s(name, 64, _T("RecentCartPath%d_%d"), drv + 1, i + 1);
-//                     sprintf(name, _T("RecentCartPath%d_%d"), drv + 1, i + 1);
-                       WritePrivateProfileString(_T("RecentFiles"), name, config.recent_cart_path[drv][i], config_path);
+       #ifdef USE_CART
+               MyWritePrivateProfileString(_T("RecentFiles"), _T("InitialCartDir"), config.initial_cart_dir, config_path);
+               for(int drv = 0; drv < USE_CART; drv++) {
+                       for(int i = 0; i < MAX_HISTORY; i++) {
+                               MyWritePrivateProfileString(_T("RecentFiles"), create_string(_T("RecentCartPath%d_%d"), drv + 1, i + 1), config.recent_cart_path[drv][i], config_path);
+                       }
                }
-       }
-#endif
-#ifdef USE_FD1
-       WritePrivateProfileString(_T("RecentFiles"), _T("InitialDiskDir"), config.initial_disk_dir, config_path);
-       for(drv = 0; drv < MAX_FD; drv++) {
-               for(i = 0; i < MAX_HISTORY; i++) {
-                       _TCHAR name[64];
-//                     sprintf(name, _T("RecentDiskPath%d_%d"), drv + 1, i + 1);
-                       _stprintf_s(name, 64, _T("RecentDiskPath%d_%d"), drv + 1, i + 1);
-                       WritePrivateProfileString(_T("RecentFiles"), name, config.recent_disk_path[drv][i], config_path);
+       #endif
+       #ifdef USE_FLOPPY_DISK
+               MyWritePrivateProfileString(_T("RecentFiles"), _T("InitialDiskDir"), config.initial_floppy_disk_dir, config_path);
+               for(int drv = 0; drv < USE_FLOPPY_DISK; drv++) {
+                       for(int i = 0; i < MAX_HISTORY; i++) {
+                               MyWritePrivateProfileString(_T("RecentFiles"), create_string(_T("RecentDiskPath%d_%d"), drv + 1, i + 1), config.recent_floppy_disk_path[drv][i], config_path);
+                       }
                }
-       }
-#endif
-#ifdef USE_QD1
-       WritePrivateProfileString(_T("RecentFiles"), _T("InitialQuickDiskDir"), config.initial_quickdisk_dir, config_path);
-       for(drv = 0; drv < MAX_QD; drv++) {
-               for(i = 0; i < MAX_HISTORY; i++) {
-                       _TCHAR name[64];
-                       _stprintf_s(name, 64, _T("RecentQuickDiskPath%d_%d"), drv + 1, i + 1);
-//                     sprintf(name, _T("RecentQuickDiskPath%d_%d"), drv + 1, i + 1);
-                       WritePrivateProfileString(_T("RecentFiles"), name, config.recent_quickdisk_path[drv][i], config_path);
+       #endif
+       #ifdef USE_QUICK_DISK
+               MyWritePrivateProfileString(_T("RecentFiles"), _T("InitialQuickDiskDir"), config.initial_quick_disk_dir, config_path);
+               for(int drv = 0; drv < USE_QUICK_DISK; drv++) {
+                       for(int i = 0; i < MAX_HISTORY; i++) {
+                               MyWritePrivateProfileString(_T("RecentFiles"), create_string(_T("RecentQuickDiskPath%d_%d"), drv + 1, i + 1), config.recent_quick_disk_path[drv][i], config_path);
+                       }
                }
-       }
-#endif
-#ifdef USE_TAPE
-       WritePrivateProfileString(_T("RecentFiles"), _T("InitialTapeDir"), config.initial_tape_dir, config_path);
-       for(i = 0; i < MAX_HISTORY; i++) {
-               _TCHAR name[64];
-//             sprintf(name, _T("RecentTapePath1_%d"), i + 1);
-               _stprintf_s(name, 64, _T("RecentTapePath1_%d"), i + 1);
-               WritePrivateProfileString(_T("RecentFiles"), name, config.recent_tape_path[i], config_path);
-       }
-#endif
-#ifdef USE_LASER_DISC
-       WritePrivateProfileString(_T("RecentFiles"), _T("InitialLaserDiscDir"), config.initial_laser_disc_dir, config_path);
-       for(int i = 0; i < MAX_HISTORY; i++) {
-               _TCHAR name[64];
-//             sprintf(name, _T("RecentLaserDiscPath1_%d"), i + 1);
-               _stprintf_s(name, 64, _T("RecentLaserDiscPath1_%d"), i + 1);
-               WritePrivateProfileString(_T("RecentFiles"), name, config.recent_laser_disc_path[i], config_path);
-       }
-#endif
-#ifdef USE_BINARY_FILE1
-       WritePrivateProfileString(_T("RecentFiles"), _T("InitialBinaryDir"), config.initial_binary_dir, config_path);
-       for(drv = 0; drv < MAX_BINARY; drv++) {
-               for(i = 0; i < MAX_HISTORY; i++) {
-                       _TCHAR name[64];
-//                     sprintf(name, _T("RecentBinaryPath%d_%d"), drv + 1, i + 1);
-                       _stprintf_s(name, 64, _T("RecentBinaryPath%d_%d"), drv + 1, i + 1);
-                       WritePrivateProfileString(_T("RecentFiles"), name, config.recent_binary_path[drv][i], config_path);
+       #endif
+       #ifdef USE_HARD_DISK
+               MyWritePrivateProfileString(_T("RecentFiles"), _T("InitialHardDiskDir"), config.initial_hard_disk_dir, config_path);
+               for(int drv = 0; drv < USE_HARD_DISK; drv++) {
+                       for(int i = 0; i < MAX_HISTORY; i++) {
+                               MyWritePrivateProfileString(_T("RecentFiles"), create_string(_T("RecentHardDiskPath%d_%d"), drv + 1, i + 1), config.recent_hard_disk_path[drv][i], config_path);
+                       }
+                       MyWritePrivateProfileString(_T("RecentFiles"), create_string(_T("LastHardDiskPath%d"), drv + 1), config.last_hard_disk_path[drv], config_path);
                }
-       }
-#endif
+       #endif
+       #ifdef USE_TAPE
+               MyWritePrivateProfileString(_T("RecentFiles"), _T("InitialTapeDir"), config.initial_tape_dir, config_path);
+               for(int drv = 0; drv < USE_TAPE; drv++) {
+                       for(int i = 0; i < MAX_HISTORY; i++) {
+                               MyWritePrivateProfileString(_T("RecentFiles"), create_string(_T("RecentTapePath%d_%d"), drv + 1, i + 1), config.recent_tape_path[drv][i], config_path);
+                       }
+               }
+       #endif
+       #ifdef USE_COMPACT_DISC
+               MyWritePrivateProfileString(_T("RecentFiles"), _T("InitialCompactDiscDir"), config.initial_compact_disc_dir, config_path);
+               for(int drv = 0; drv < USE_COMPACT_DISC; drv++) {
+                       for(int i = 0; i < MAX_HISTORY; i++) {
+                               MyWritePrivateProfileString(_T("RecentFiles"), create_string(_T("RecentCompactDiscPath%d_%d"), drv + 1, i + 1), config.recent_compact_disc_path[drv][i], config_path);
+                       }
+               }
+       #endif
+       #ifdef USE_LASER_DISC
+               MyWritePrivateProfileString(_T("RecentFiles"), _T("InitialLaserDiscDir"), config.initial_laser_disc_dir, config_path);
+               for(int drv = 0; drv < USE_LASER_DISC; drv++) {
+                       for(int i = 0; i < MAX_HISTORY; i++) {
+                               MyWritePrivateProfileString(_T("RecentFiles"), create_string(_T("RecentLaserDiscPath%d_%d"), drv + 1, i + 1), config.recent_laser_disc_path[drv][i], config_path);
+                       }
+               }
+       #endif
+       #ifdef USE_BINARY_FILE
+               MyWritePrivateProfileString(_T("RecentFiles"), _T("InitialBinaryDir"), config.initial_binary_dir, config_path);
+               for(int drv = 0; drv < USE_BINARY_FILE; drv++) {
+                       for(int i = 0; i < MAX_HISTORY; i++) {
+                               MyWritePrivateProfileString(_T("RecentFiles"), create_string(_T("RecentBinaryPath%d_%d"), drv + 1, i + 1), config.recent_binary_path[drv][i], config_path);
+                       }
+               }
+       #endif
+       #ifdef USE_BUBBLE
+               MyWritePrivateProfileString(_T("RecentFiles"), _T("InitialBubbleDir"), config.initial_bubble_casette_dir, config_path);
+               for(int drv = 0; drv < USE_BUBBLE; drv++) {
+                       for(int i = 0; i < MAX_HISTORY; i++) {
+                               MyWritePrivateProfileString(_T("RecentFiles"), create_string(_T("RecentBubblePath%d_%d"), drv + 1, i + 1), config.recent_bubble_casette_path[drv][i], config_path);
+                       }
+               }
+       #endif
        
        // screen
-#if !(defined(USE_BITMAP) || defined(USE_LED))
-       WritePrivateProfileInt(_T("Screen"), _T("WindowMode"), config.window_mode, config_path);
-       WritePrivateProfileBool(_T("Screen"), _T("UseD3D9"), config.use_d3d9, config_path);
-       WritePrivateProfileBool(_T("Screen"), _T("WaitVSync"), config.wait_vsync, config_path);
-       WritePrivateProfileInt(_T("Screen"), _T("StretchType"), config.stretch_type, config_path);
-#else
-       WritePrivateProfileInt(_T("Screen"), _T("WindowMode"), config.window_mode, config_path);
-#endif
-#ifdef USE_MONITOR_TYPE
-       WritePrivateProfileInt(_T("Screen"), _T("MonitorType"), config.monitor_type, config_path);
-#endif
-#ifdef USE_CRT_FILTER
-       WritePrivateProfileBool(_T("Screen"), _T("CRTFilter"), config.crt_filter, config_path);
-#endif
-#ifdef USE_SCANLINE
-       WritePrivateProfileBool(_T("Screen"), _T("ScanLine"), config.scan_line, config_path);
-#endif
-#ifdef USE_SCREEN_ROTATE
-       WritePrivateProfileBool(_T("Screen"), _T("RotateType"), config.rotate_type, config_path);
-#endif
-#if defined(USE_QT)
-       WritePrivateProfileBool(_T("Screen"), _T("UseOpenGLScanLine"),
-                                                       config.use_opengl_scanline, config_path);
-       WritePrivateProfileBool(_T("Screen"), _T("OpenGLScanLineVert"),
-                                                       config.opengl_scanline_vert, config_path);;
-       WritePrivateProfileBool(_T("Screen"), _T("OpenGLScanLineHoriz"),
-                                                       config.opengl_scanline_horiz, config_path);;
-       WritePrivateProfileBool(_T("Screen"), _T("UseOpenGLFilters"),
-                                                       config.use_opengl_filters, config_path);
-       WritePrivateProfileInt(_T("Screen"), _T("OpenGlFilterNum"),
-                                                  config.opengl_filter_num, config_path);
-#endif 
-       
+       #ifndef ONE_BOARD_MICRO_COMPUTER
+               MyWritePrivateProfileInt(_T("Screen"), _T("WindowMode"), config.window_mode, config_path);
+               MyWritePrivateProfileInt(_T("Screen"), _T("WindowStretchType"), config.window_stretch_type, config_path);
+               MyWritePrivateProfileInt(_T("Screen"), _T("FullScreenStretchType"), config.fullscreen_stretch_type, config_path);
+//             #ifdef USE_SCREEN_ROTATE
+                       MyWritePrivateProfileInt(_T("Screen"), _T("RotateType"), config.rotate_type, config_path);
+//             #endif
+       #endif
+
+       // filter
+       #ifdef USE_SCREEN_FILTER
+               MyWritePrivateProfileInt(_T("Screen"), _T("FilterType"), config.filter_type, config_path);
+       #endif
+               
        // sound
-       WritePrivateProfileInt(_T("Sound"), _T("Frequency"), config.sound_frequency, config_path);
-       WritePrivateProfileInt(_T("Sound"), _T("Latency"), config.sound_latency, config_path);
-#ifdef USE_SOUND_DEVICE_TYPE
-       WritePrivateProfileInt(_T("Sound"), _T("DeviceType"), config.sound_device_type, config_path);
-#endif
-       WritePrivateProfileBool(_T("Sound"), _T("MultipleSpeakers"),
-                                                       config.multiple_speakers, config_path);
-       WritePrivateProfileInt(_T("Sound"), _T("GeneralSoundLevel"),
-                                                  config.general_sound_level, config_path);
-#ifdef USE_MULTIPLE_SOUNDCARDS
-       {
-               _TCHAR _tag[128];
-               int ii;
-               for(ii = 0; ii < USE_MULTIPLE_SOUNDCARDS; ii++) {
-                       memset(_tag, 0x00, sizeof(_tag));
-                       _stprintf_s(_tag, 64, _T("DeviceVolumeLevel_%d"), ii + 1);
-                       WritePrivateProfileInt(_T("Sound"), _tag, config.sound_device_level[ii], config_path);
+               MyWritePrivateProfileInt(_T("Sound"), _T("Frequency"), config.sound_frequency, config_path);
+               MyWritePrivateProfileInt(_T("Sound"), _T("Latency"), config.sound_latency, config_path);
+               MyWritePrivateProfileBool(_T("Sound"), _T("StrictRendering"), config.sound_strict_rendering, config_path);
+               MyWritePrivateProfileInt(_T("Sound"), _T("DeviceNumber"), config.sound_device_num, config_path);
+       #ifdef USE_FLOPPY_DISK
+               MyWritePrivateProfileBool(_T("Sound"), _T("NoiseFDD"), config.sound_noise_fdd, config_path);
+       #endif
+       #ifdef USE_TAPE
+               MyWritePrivateProfileBool(_T("Sound"), _T("NoiseCMT"), config.sound_noise_cmt, config_path);
+               MyWritePrivateProfileBool(_T("Sound"), _T("PlayTape"), config.sound_play_tape, config_path);
+       #endif
+       #ifdef USE_SOUND_VOLUME
+               for(int i = 0; i < USE_SOUND_VOLUME; i++) {
+                       MyWritePrivateProfileInt(_T("Sound"), create_string(_T("VolumeLeft%d"), i + 1), config.sound_volume_l[i], config_path);
+                       MyWritePrivateProfileInt(_T("Sound"), create_string(_T("VolumeRight%d"), i + 1), config.sound_volume_r[i], config_path);
                }
-       }
-#endif
-#if defined(_USE_AGAR) || defined(_USE_QT)
-        config_path->Fclose();
-        delete config_path;
-        AGAR_DebugLog(AGAR_LOG_INFO, "Write done.");
-#endif
-
-}
-
-#define STATE_VERSION  1
-
-void save_config_state(void *f)
-{
-       FILEIO *state_fio = (FILEIO *)f;
-       int drv;
+       #endif
+       #if defined(_WIN32) && !defined(_USE_QT)
+               MyWritePrivateProfileString(_T("Sound"), _T("YM2151GenDll"), config.mame2151_dll_path, config_path);
+               MyWritePrivateProfileString(_T("Sound"), _T("YM2608GenDll"), config.mame2608_dll_path, config_path);
+       #endif
        
-       state_fio->FputUint32(STATE_VERSION);
+       // input
+       #ifdef USE_JOYSTICK
+               for(int i = 0; i < 4; i++) {
+                       for(int j = 0; j < 16; j++) {
+                               MyWritePrivateProfileInt(_T("Input"), create_string(_T("JoyButtonsEx%d_%d"), i + 1, j + 1), config.joy_buttons[i][j], config_path);
+                       }
+               }
+               MyWritePrivateProfileBool(_T("Input"), _T("UseJoyToKey"), config.use_joy_to_key, config_path);
+               MyWritePrivateProfileInt(_T("Input"), _T("JoyToKeyType"), config.joy_to_key_type, config_path);
+               MyWritePrivateProfileBool(_T("Input"), _T("JoyToKeyNumPad5"), config.joy_to_key_numpad5, config_path);
+               for(int i = 0; i < 16; i++) {
+                       MyWritePrivateProfileInt(_T("Input"), create_string(_T("JoyToKeyButtons%d"), i + 1), config.joy_to_key_buttons[i], config_path);
+               }
+       #endif
+
+       // debug
+       #ifdef USE_FLOPPY_DISK
+               MyWritePrivateProfileInt(_T("Debug"), _T("SpecialDebugFDC"), config.special_debug_fdc, config_path);
+       #endif
+               MyWritePrivateProfileBool(_T("Debug"), _T("PrintCPUStatistics"), config.print_statistics, config_path);
+       // printer
+       #ifdef USE_PRINTER
+               MyWritePrivateProfileString(_T("Printer"), _T("PrinterDll"), config.printer_dll_path, config_path);
+       #endif
+
        
-#ifdef USE_BOOT_MODE
-       state_fio->FputInt32(config.boot_mode);
-#endif
-#ifdef USE_CPU_TYPE
-       state_fio->FputInt32(config.cpu_type);
-#endif
-#ifdef USE_DIPSWITCH
-       state_fio->FputUint32(config.dipswitch);
-#endif
-#ifdef USE_DEVICE_TYPE
-       state_fio->FputInt32(config.device_type);
-#endif
-#ifdef USE_DRIVE_TYPE
-       state_fio->FputInt32(config.drive_type);
-#endif
-#ifdef USE_FD1
-       for(drv = 0; drv < 8; drv++) state_fio->FputBool(config.ignore_crc[drv]);
-#endif
-#ifdef USE_MONITOR_TYPE
-       state_fio->FputInt32(config.monitor_type);
-#endif
-#ifdef USE_SOUND_DEVICE_TYPE
-       state_fio->FputInt32(config.sound_device_type);
-#endif
+       // win32
+       #if defined(_WIN32) && !defined(_USE_QT)
+               #ifndef ONE_BOARD_MICRO_COMPUTER
+                       MyWritePrivateProfileBool(_T("Win32"), _T("UseDirect3D9"), config.use_d3d9, config_path);
+                       MyWritePrivateProfileBool(_T("Win32"), _T("WaitVSync"), config.wait_vsync, config_path);
+               #endif
+               MyWritePrivateProfileBool(_T("Win32"), _T("UseDirectInput"), config.use_dinput, config_path);
+               MyWritePrivateProfileBool(_T("Win32"), _T("DisableDwm"), config.disable_dwm, config_path);
+               MyWritePrivateProfileBool(_T("Win32"), _T("ShowStatusBar"), config.show_status_bar, config_path);
+       #endif
+       #ifdef _USE_QT
+               MyWritePrivateProfileBool(_T("Qt"), _T("UseSeparateThreadDraw"), config.use_separate_thread_draw, config_path);
+               MyWritePrivateProfileBool(_T("Qt"), _T("UseOSDVirtualMedia"), config.use_osd_virtual_media, config_path); 
+               MyWritePrivateProfileBool(_T("Qt"), _T("UseOpenGLScanLine"), config.use_opengl_scanline, config_path);
+               MyWritePrivateProfileBool(_T("Qt"), _T("OpenGLScanLineVert"), config.opengl_scanline_vert, config_path);;
+               MyWritePrivateProfileBool(_T("Qt"), _T("OpenGLScanLineHoriz"), config.opengl_scanline_horiz, config_path);;
+               MyWritePrivateProfileBool(_T("Qt"), _T("UseOpenGLFilters"), config.use_opengl_filters, config_path);
+               MyWritePrivateProfileInt(_T("Qt"), _T("OpenGLFilterNum"), config.opengl_filter_num, config_path);
+               MyWritePrivateProfileInt(_T("Qt"), _T("RenderType"), config.rendering_type, config_path);
+               MyWritePrivateProfileInt(_T("Qt"), _T("RenderPlatform"), config.render_platform, config_path);
+               MyWritePrivateProfileInt(_T("Qt"), _T("RenderMajorVersion"), config.render_major_version, config_path);
+               MyWritePrivateProfileInt(_T("Qt"), _T("RenderMinorVersion"), config.render_minor_version, config_path);
+
+               MyWritePrivateProfileInt(_T("Qt"), _T("GeneralSoundLevel"), config.general_sound_level, config_path);
+               MyWritePrivateProfileBool(_T("Qt"), _T("FocusWithClick"), config.focus_with_click, config_path);
+
+               // Extra UI
+               MyWritePrivateProfileBool(_T("Qt"), _T("SwapKanjiPause"), config.swap_kanji_pause, config_path);
+               MyWritePrivateProfileInt(_T("Qt"), _T("CursorAsTenKey"), config.cursor_as_ten_key, config_path);
+               MyWritePrivateProfileBool(_T("Qt"), _T("NumpadEnterAsFullKey"), config.numpad_enter_as_fullkey, config_path);
+               MyWritePrivateProfileInt(_T("Qt"), _T("HostKeyboardType"), config.host_keyboard_type, config_path);
+               MyWritePrivateProfileString(_T("Qt"), _T("DebugWindowFont"), config.debugwindow_font, config_path);
+               MyWritePrivateProfileInt(_T("Qt"), _T("DebugWindowWidth"), config.debugwindow_width, config_path);
+               MyWritePrivateProfileInt(_T("Qt"), _T("DebugWindowHeight"), config.debugwindow_height, config_path);
+               MyWritePrivateProfileString(_T("Qt"), _T("LogWindowFont"), config.logwindow_font, config_path);
+               MyWritePrivateProfileInt(_T("Qt"), _T("LogWindowWidth"), config.logwindow_width, config_path);
+               MyWritePrivateProfileInt(_T("Qt"), _T("LogWindowHeight"), config.logwindow_height, config_path);
+
+               for(i = 0; i < 16; i++) {
+                       _TCHAR name[256];
+                       my_stprintf_s(name, 256, _T("AssignedJoystick%d"), i + 1);
+                       MyWritePrivateProfileString(_T("Qt"), (const _TCHAR *)name, 
+                                                                               config.assigned_joystick_name[i], config_path);
+               }
+               MyWritePrivateProfileInt(_T("Qt"), _T("VideoWidth"), config.video_width, config_path);
+               MyWritePrivateProfileInt(_T("Qt"), _T("VideoHeight"), config.video_height, config_path);
+               MyWritePrivateProfileInt(_T("Qt"), _T("VideoCodecType"), config.video_codec_type, config_path);
+               MyWritePrivateProfileInt(_T("Qt"), _T("AudioCodecType"), config.audio_codec_type, config_path);
+               
+               MyWritePrivateProfileInt(_T("Qt"), _T("H264Bitrate"), config.video_h264_bitrate, config_path);
+               MyWritePrivateProfileInt(_T("Qt"), _T("H264BFrames"), config.video_h264_bframes, config_path);
+               MyWritePrivateProfileInt(_T("Qt"), _T("H264BAdapt"), config.video_h264_b_adapt, config_path);
+               MyWritePrivateProfileInt(_T("Qt"), _T("H264MinQ"), config.video_h264_minq, config_path);
+               MyWritePrivateProfileInt(_T("Qt"), _T("H264MaxQ"), config.video_h264_maxq, config_path);
+               MyWritePrivateProfileInt(_T("Qt"), _T("H264Subme"), config.video_h264_subme, config_path);
+               
+               MyWritePrivateProfileInt(_T("Qt"), _T("MPEG4Bitrate"), config.video_mpeg4_bitrate, config_path);
+               MyWritePrivateProfileInt(_T("Qt"), _T("MPEG4BFrames"), config.video_mpeg4_bframes, config_path);
+               MyWritePrivateProfileInt(_T("Qt"), _T("MPEG4MinQ"), config.video_mpeg4_minq, config_path);
+               MyWritePrivateProfileInt(_T("Qt"), _T("MPEG4MaxQ"), config.video_mpeg4_maxq, config_path);
+               
+               MyWritePrivateProfileInt(_T("Qt"), _T("VideoThreads"), config.video_threads, config_path);
+               MyWritePrivateProfileInt(_T("Qt"), _T("AudioBitrate"), config.audio_bitrate, config_path);
+               MyWritePrivateProfileInt(_T("Qt"), _T("VideoFramerate"), config.video_frame_rate, config_path);
+               
+               MyWritePrivateProfileBool(_T("Qt"), _T("WriteToSyslog"), config.log_to_syslog, config_path);
+               MyWritePrivateProfileBool(_T("Qt"), _T("WriteToConsole"), config.log_to_console, config_path);
+               
+               for(int ii = 0; ii < (CSP_LOG_TYPE_VM_DEVICE_END - CSP_LOG_TYPE_VM_DEVICE_0 + 1) ; ii++) {
+                       uint32_t flags = 0;
+                       flags = 0;
+                       for(int jj = 0; jj < 8; jj++) {
+                               flags <<= 1;
+                               if(config.dev_log_to_syslog[ii][jj]) flags |= 0x0001;
+                       }
+                       MyWritePrivateProfileInt(_T("Qt"), create_string(_T("SyslogEnabled%d"), ii), flags, config_path);
+                       
+                       flags = 0;
+                       for(int jj = 0; jj < 8; jj++) {
+                               flags <<= 1;
+                               if(config.dev_log_to_console[ii][jj]) flags |= 0x0001;
+                       }
+                       MyWritePrivateProfileInt(_T("Qt"), create_string(_T("ConsoleLogEnabled%d"), ii), flags, config_path);
+                       
+                       flags = 0;
+                       for(int jj = 0; jj < 8; jj++) {
+                               flags <<= 1;
+                               if(config.dev_log_recording[ii][jj]) flags |= 0x0001;
+                       }
+                       MyWritePrivateProfileInt(_T("Qt"), create_string(_T("RecordLogEnabled%d"), ii), flags, config_path);
+               }
+               MyWritePrivateProfileBool(_T("Qt"), _T("StateLogToConsole"), config.state_log_to_console, config_path);
+               MyWritePrivateProfileBool(_T("Qt"), _T("StateLogToSyslog"), config.state_log_to_syslog, config_path);
+               MyWritePrivateProfileBool(_T("Qt"), _T("StateLogToRecording"), config.state_log_to_recording, config_path);
+               
+               MyWritePrivateProfileInt(_T("Qt"), _T("UiVirtualMediaPosition"), config.virtual_media_position, config_path);
+               //csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Write config done.");
+       #endif  
 }
 
-bool load_config_state(void *f)
+#define STATE_VERSION  6
+
+bool process_config_state(void *f, bool loading)
 {
        FILEIO *state_fio = (FILEIO *)f;
-       int drv;
        
-       if(state_fio->FgetUint32() != STATE_VERSION) {
+       if(!state_fio->StateCheckUint32(STATE_VERSION)) {
                return false;
        }
-#ifdef USE_BOOT_MODE
-       config.boot_mode = state_fio->FgetInt32();
-#endif
-#ifdef USE_CPU_TYPE
-       config.cpu_type = state_fio->FgetInt32();
-#endif
-#ifdef USE_DIPSWITCH
-       config.dipswitch = state_fio->FgetUint32();
-#endif
-#ifdef USE_DEVICE_TYPE
-       config.device_type = state_fio->FgetInt32();
-#endif
-#ifdef USE_DRIVE_TYPE
-       config.drive_type = state_fio->FgetInt32();
-#endif
-#ifdef USE_FD1
-       for(drv = 0; drv < 8; drv++) config.ignore_crc[drv] = state_fio->FgetBool();
-#endif
-#ifdef USE_MONITOR_TYPE
-       config.monitor_type = state_fio->FgetInt32();
-#endif
-#ifdef USE_SOUND_DEVICE_TYPE
-       config.sound_device_type = state_fio->FgetInt32();
-#endif
+       #ifdef USE_BOOT_MODE
+               state_fio->StateValue(config.boot_mode);
+       #endif
+       #ifdef USE_CPU_TYPE
+               state_fio->StateValue(config.cpu_type);
+       #endif
+       #ifdef USE_DIPSWITCH
+               state_fio->StateValue(config.dipswitch);
+       #endif
+       #ifdef USE_DEVICE_TYPE
+               state_fio->StateValue(config.device_type);
+       #endif
+       #ifdef USE_DRIVE_TYPE
+               state_fio->StateValue(config.drive_type);
+       #endif
+       #ifdef USE_KEYBOARD_TYPE
+               state_fio->StateValue(config.keyboard_type);
+       #endif
+       #ifdef USE_MOUSE_TYPE
+               state_fio->StateValue(config.mouse_type);
+       #endif
+       #ifdef USE_JOYSTICK_TYPE
+               state_fio->StateValue(config.joystick_type);
+       #endif
+       #ifdef USE_SOUND_TYPE
+               state_fio->StateValue(config.sound_type);
+       #endif
+       #ifdef USE_MONITOR_TYPE
+               state_fio->StateValue(config.monitor_type);
+       #endif
+       #ifdef USE_PRINTER_TYPE
+               state_fio->StateValue(config.printer_type);
+       #endif
+       #ifdef USE_FLOPPY_DISK
+               for(int drv = 0; drv < USE_FLOPPY_DISK; drv++) {
+                       state_fio->StateValue(config.correct_disk_timing[drv]);
+                       state_fio->StateValue(config.ignore_disk_crc[drv]);
+               }
+       #endif
+       state_fio->StateValue(config.sound_frequency);
+       state_fio->StateValue(config.sound_latency);
        return true;
 }