OSDN Git Service

[BUILD] Set SOVERSION and GIT hash automatically.
[csp-qt/common_source_project-fm7.git] / source / src / qt / common / qt_utils.cpp
index 08e4a97..d912e3d 100644 (file)
 #include <stdio.h>
 #include <string>
 #include <vector>
+#include <QApplication>
 #include <QString>
 #include <QTextCodec>
 #include <QImage>
 #include <QImageReader>
 #include <QDateTime>
 #include <QDir>
+#include <QTranslator>
+#include <QProcessEnvironment>
+#include <QCommandLineParser>
 
 #include "common.h"
 #include "fileio.h"
+#include "config.h"
 #include "emu.h"
 #include "menuclasses.h"
 #include "mainwidget.h"
 #include "draw_thread.h"
 
 #include "qt_gldraw.h"
-#include "qt_glutil_gl2_0.h"
+#include "../gui/gl2/qt_glutil_gl2_0.h"
 #include "csp_logger.h"
-
+#include "dock_disks.h"
 #include "menu_disk.h"
 #include "menu_bubble.h"
-#include "menu_flags.h"
+#include "menu_flags_ext.h"
 #include "dialog_movie.h"
 #include "../avio/movie_saver.h"
 // emulation core
+#include "../../vm/fmgen/fmgen.h"
 
 EMU* emu;
 QApplication *GuiMain = NULL;
+extern config_t config;
+#if defined(CSP_OS_WINDOWS)
+CSP_Logger DLL_PREFIX_I *csp_logger;
+#else
+extern CSP_Logger *csp_logger;
+#endif
 
 // Start to define MainWindow.
 class META_MainWindow *rMainWindow;
 
+
 // buttons
 #ifdef MAX_BUTTONS
 #define MAX_FONT_SIZE 32
 #endif
 
 // menu
-std::string cpp_homedir;
-std::string cpp_confdir;
-std::string my_procname;
-std::string sRssDir;
+extern DLL_PREFIX_I std::string cpp_homedir;
+extern DLL_PREFIX_I std::string cpp_confdir;
+extern DLL_PREFIX_I std::string my_procname;
+extern DLL_PREFIX_I std::string sRssDir;
 bool now_menuloop = false;
 static int close_notified = 0;
 // timing control
@@ -107,7 +120,6 @@ void Ui_MainWindow::rise_movie_dialog(void)
        dlg->setWindowTitle(QApplication::translate("CSP_DialogMovie", "Configure movie encodings", 0));
        dlg->show();
 }
-
 void Ui_MainWindow::LaunchEmuThread(void)
 {
        QString objNameStr;
@@ -115,7 +127,7 @@ void Ui_MainWindow::LaunchEmuThread(void)
 
        int drvs;
        
-       hRunEmu = new EmuThreadClass(rMainWindow, emu, using_flags, this);
+       hRunEmu = new EmuThreadClass(rMainWindow, using_flags);
        connect(hRunEmu, SIGNAL(message_changed(QString)), this, SLOT(message_status_bar(QString)));
        connect(hRunEmu, SIGNAL(sig_is_enable_mouse(bool)), glv, SLOT(do_set_mouse_enabled(bool)));
        connect(glv, SIGNAL(sig_key_down(uint32_t, uint32_t, bool)), hRunEmu, SLOT(do_key_down(uint32_t, uint32_t, bool)));
@@ -124,107 +136,87 @@ void Ui_MainWindow::LaunchEmuThread(void)
 
        
        //connect(hRunEmu, SIGNAL(sig_finished()), this, SLOT(delete_emu_thread()));
-       connect(this, SIGNAL(sig_vm_reset()), hRunEmu, SLOT(doReset()));
-       connect(this, SIGNAL(sig_vm_specialreset()), hRunEmu, SLOT(doSpecialReset()));
-       connect(this, SIGNAL(sig_vm_loadstate()), hRunEmu, SLOT(doLoadState()));
-       connect(this, SIGNAL(sig_vm_savestate()), hRunEmu, SLOT(doSaveState()));
+       connect(this, SIGNAL(sig_vm_reset()), hRunEmu, SLOT(do_reset()));
+       connect(this, SIGNAL(sig_vm_specialreset()), hRunEmu, SLOT(do_special_reset()));
 
-       connect(this, SIGNAL(sig_emu_update_config()), hRunEmu, SLOT(doUpdateConfig()));
-       connect(this, SIGNAL(sig_emu_update_volume_level(int, int)), hRunEmu, SLOT(doUpdateVolumeLevel(int, int)));
-       connect(this, SIGNAL(sig_emu_update_volume_balance(int, int)), hRunEmu, SLOT(doUpdateVolumeBalance(int, int)));
-       connect(this, SIGNAL(sig_emu_start_rec_sound()), hRunEmu, SLOT(doStartRecordSound()));
-       connect(this, SIGNAL(sig_emu_stop_rec_sound()), hRunEmu, SLOT(doStopRecordSound()));
-       connect(this, SIGNAL(sig_emu_set_display_size(int, int, int, int)), hRunEmu, SLOT(doSetDisplaySize(int, int, int, int)));
+       connect(this, SIGNAL(sig_emu_update_config()), hRunEmu, SLOT(do_update_config()));
+       connect(this, SIGNAL(sig_emu_update_volume_level(int, int)), hRunEmu, SLOT(do_update_volume_level(int, int)));
+       connect(this, SIGNAL(sig_emu_update_volume_balance(int, int)), hRunEmu, SLOT(do_update_volume_balance(int, int)));
+       connect(this, SIGNAL(sig_emu_start_rec_sound()), hRunEmu, SLOT(do_start_record_sound()));
+       connect(this, SIGNAL(sig_emu_stop_rec_sound()), hRunEmu, SLOT(do_stop_record_sound()));
+       connect(this, SIGNAL(sig_emu_set_display_size(int, int, int, int)), hRunEmu, SLOT(do_set_display_size(int, int, int, int)));
        
-
-#if defined(USE_FD1) || defined(USE_FD2) || defined(USE_FD3) || defined(USE_FD4) || \
-    defined(USE_FD5) || defined(USE_FD6) || defined(USE_FD7) || defined(USE_FD8)
+       if(using_flags->is_use_state()) {
+               for(int i = 0; i < 10; i++) {
+                       connect(actionLoad_State[i], SIGNAL(sig_load_state(QString)), hRunEmu, SLOT(do_load_state(QString))); // OK?
+                       connect(actionSave_State[i], SIGNAL(sig_save_state(QString)), hRunEmu, SLOT(do_save_state(QString))); // OK?
+               }
+       }
+#if defined(USE_FLOPPY_DISK)
        connect(this, SIGNAL(sig_write_protect_disk(int, bool)), hRunEmu, SLOT(do_write_protect_disk(int, bool)));
        connect(this, SIGNAL(sig_open_disk(int, QString, int)), hRunEmu, SLOT(do_open_disk(int, QString, int)));
        connect(this, SIGNAL(sig_close_disk(int)), hRunEmu, SLOT(do_close_disk(int)));
        connect(hRunEmu, SIGNAL(sig_update_recent_disk(int)), this, SLOT(do_update_recent_disk(int)));
-       connect(hRunEmu, SIGNAL(sig_change_osd_fd(int, QString)), this, SLOT(do_change_osd_fd(int, QString)));
-       drvs = 0;
-# if defined(USE_FD1)
-       drvs = 1;
-# endif
-# if defined(USE_FD2)
-       drvs = 2;
-# endif
-# if defined(USE_FD3)
-       drvs = 3;
-# endif
-# if defined(USE_FD4)
-       drvs = 4;
-# endif
-# if defined(USE_FD5)
-       drvs = 5;
-# endif
-# if defined(USE_FD6)
-       drvs = 6;
-# endif
-# if defined(USE_FD7)
-       drvs = 7;
-# endif
-# if defined(USE_FD8)
-       drvs = 8;
-# endif
+       //connect(hRunEmu, SIGNAL(sig_change_osd_fd(int, QString)), this, SLOT(do_change_osd_fd(int, QString)));
+       drvs = USE_FLOPPY_DISK;
        for(int ii = 0; ii < drvs; ii++) {
                menu_fds[ii]->setEmu(emu);
                connect(menu_fds[ii], SIGNAL(sig_update_inner_fd(int ,QStringList , class Action_Control **, QStringList , int, bool)),
                                this, SLOT(do_update_inner_fd(int ,QStringList , class Action_Control **, QStringList , int, bool)));
        }
 #endif
+#if defined(USE_HARD_DISK)
+       connect(this, SIGNAL(sig_open_hard_disk(int, QString)), hRunEmu, SLOT(do_open_hard_disk(int, QString)));
+       connect(this, SIGNAL(sig_close_hard_disk(int)), hRunEmu, SLOT(do_close_hard_disk(int)));
+       connect(hRunEmu, SIGNAL(sig_update_recent_hard_disk(int)), this, SLOT(do_update_recent_hard_disk(int)));
+       //connect(hRunEmu, SIGNAL(sig_change_osd_fd(int, QString)), this, SLOT(do_change_osd_fd(int, QString)));
+#endif
 #if defined(USE_TAPE)
-       connect(this, SIGNAL(sig_play_tape(QString)), hRunEmu, SLOT(do_play_tape(QString)));
-       connect(this, SIGNAL(sig_rec_tape(QString)),  hRunEmu, SLOT(do_rec_tape(QString)));
-       connect(this, SIGNAL(sig_close_tape(void)),   hRunEmu, SLOT(do_close_tape(void)));
-       connect(hRunEmu, SIGNAL(sig_change_osd_cmt(QString)), this, SLOT(do_change_osd_cmt(QString)));
+       connect(this, SIGNAL(sig_play_tape(int, QString)), hRunEmu, SLOT(do_play_tape(int, QString)));
+       connect(this, SIGNAL(sig_rec_tape(int, QString)),  hRunEmu, SLOT(do_rec_tape(int, QString)));
+       connect(this, SIGNAL(sig_close_tape(int)),   hRunEmu, SLOT(do_close_tape(int)));
+       //connect(hRunEmu, SIGNAL(sig_change_osd_cmt(QString)), this, SLOT(do_change_osd_cmt(QString)));
 # if defined(USE_TAPE_BUTTON)
-       connect(this, SIGNAL(sig_cmt_push_play(void)), hRunEmu, SLOT(do_cmt_push_play(void)));
-       connect(this, SIGNAL(sig_cmt_push_stop(void)), hRunEmu, SLOT(do_cmt_push_stop(void)));
-       connect(this, SIGNAL(sig_cmt_push_fast_forward(void)), hRunEmu, SLOT(do_cmt_push_fast_forward(void)));
-       connect(this, SIGNAL(sig_cmt_push_fast_rewind(void)),  hRunEmu, SLOT(do_cmt_push_fast_rewind(void)));
-       connect(this, SIGNAL(sig_cmt_push_apss_forward(void)), hRunEmu, SLOT(do_cmt_push_apss_forward(void)));
-       connect(this, SIGNAL(sig_cmt_push_apss_rewind(void)),  hRunEmu, SLOT(do_cmt_push_apss_rewind(void)));
+       connect(this, SIGNAL(sig_cmt_push_play(int)), hRunEmu, SLOT(do_cmt_push_play(int)));
+       connect(this, SIGNAL(sig_cmt_push_stop(int)), hRunEmu, SLOT(do_cmt_push_stop(int)));
+       connect(this, SIGNAL(sig_cmt_push_fast_forward(int)), hRunEmu, SLOT(do_cmt_push_fast_forward(int)));
+       connect(this, SIGNAL(sig_cmt_push_fast_rewind(int)),  hRunEmu, SLOT(do_cmt_push_fast_rewind(int)));
+       connect(this, SIGNAL(sig_cmt_push_apss_forward(int)), hRunEmu, SLOT(do_cmt_push_apss_forward(int)));
+       connect(this, SIGNAL(sig_cmt_push_apss_rewind(int)),  hRunEmu, SLOT(do_cmt_push_apss_rewind(int)));
 # endif
 #endif
-#if defined(USE_QD1)
+#if defined(USE_QUICK_DISK)
        connect(this, SIGNAL(sig_write_protect_quickdisk(int, bool)), hRunEmu, SLOT(do_write_protect_quickdisk(int, bool)));
        connect(this, SIGNAL(sig_open_quickdisk(int, QString)), hRunEmu, SLOT(do_open_quickdisk(int, QString)));
        connect(this, SIGNAL(sig_close_quickdisk(int)), hRunEmu, SLOT(do_close_quickdisk(int)));
-       connect(hRunEmu, SIGNAL(sig_change_osd_qd(int, QString)), this, SLOT(do_change_osd_qd(int, QString)));
+       //connect(hRunEmu, SIGNAL(sig_change_osd_qd(int, QString)), this, SLOT(do_change_osd_qd(int, QString)));
 #endif
-#if defined(USE_CART1)
+#if defined(USE_CART)
        connect(this, SIGNAL(sig_open_cart(int, QString)), hRunEmu, SLOT(do_open_cart(int, QString)));
        connect(this, SIGNAL(sig_close_cart(int)), hRunEmu, SLOT(do_close_cart(int)));
 #endif
 #if defined(USE_COMPACT_DISC)
-       connect(this, SIGNAL(sig_open_cdrom(QString)), hRunEmu, SLOT(do_open_cdrom(QString)));
-       connect(this, SIGNAL(sig_close_cdrom()), hRunEmu, SLOT(do_eject_cdrom()));
-       connect(hRunEmu, SIGNAL(sig_change_osd_cdrom(QString)), this, SLOT(do_change_osd_cdrom(QString)));
+       connect(this, SIGNAL(sig_open_cdrom(int, QString)), hRunEmu, SLOT(do_open_cdrom(int, QString)));
+       connect(this, SIGNAL(sig_close_cdrom(int)), hRunEmu, SLOT(do_eject_cdrom(int)));
+       //connect(hRunEmu, SIGNAL(sig_change_osd_cdrom(QString)), this, SLOT(do_change_osd_cdrom(QString)));
+       // ToDo: multiple CDs
 #endif 
 #if defined(USE_LASER_DISC)
-       connect(this, SIGNAL(sig_open_laserdisc(QString)), hRunEmu, SLOT(do_open_laser_disc(QString)));
-       connect(this, SIGNAL(sig_close_laserdisc(void)), hRunEmu, SLOT(do_close_laser_disc(void)));
+       connect(this, SIGNAL(sig_open_laserdisc(int, QString)), hRunEmu, SLOT(do_open_laser_disc(int, QString)));
+       connect(this, SIGNAL(sig_close_laserdisc(int)), hRunEmu, SLOT(do_close_laser_disc(int)));
+       // ToDo: multiple LDs
 #endif
-#if defined(USE_BINARY_FILE1)
+#if defined(USE_BINARY_FILE)
        connect(this, SIGNAL(sig_load_binary(int, QString)), hRunEmu, SLOT(do_load_binary(int, QString)));
        connect(this, SIGNAL(sig_save_binary(int, QString)), hRunEmu, SLOT(do_save_binary(int, QString)));
 #endif
-#if defined(USE_BUBBLE1)
+#if defined(USE_BUBBLE)
        connect(this, SIGNAL(sig_write_protect_bubble(int, bool)), hRunEmu, SLOT(do_write_protect_bubble_casette(int, bool)));
        connect(this, SIGNAL(sig_open_bubble(int, QString, int)), hRunEmu, SLOT(do_open_bubble_casette(int, QString, int)));
        connect(this, SIGNAL(sig_close_bubble(int)), hRunEmu, SLOT(do_close_bubble_casette(int)));
        connect(hRunEmu, SIGNAL(sig_update_recent_bubble(int)), this, SLOT(do_update_recent_bubble(int)));
-       connect(hRunEmu, SIGNAL(sig_change_osd_bubble(int, QString)), this, SLOT(do_change_osd_bubble(int, QString)));
-       drvs = 0;
-# if defined(USE_BUBBLE1)
-       drvs = 1;
-# endif
-# if defined(USE_BUBBLE2)
-       drvs = 2;
-# endif
+       //connect(hRunEmu, SIGNAL(sig_change_osd_bubble(int, QString)), this, SLOT(do_change_osd_bubble(int, QString)));
+       drvs = USE_BUBBLE;
        for(int ii = 0; ii < drvs; ii++) {
                menu_bubbles[ii]->setEmu(emu);
                connect(menu_bubbles[ii],
@@ -237,22 +229,25 @@ void Ui_MainWindow::LaunchEmuThread(void)
        connect(this, SIGNAL(quit_emu_thread()), hRunEmu, SLOT(doExit()));
        connect(hRunEmu, SIGNAL(sig_mouse_enable(bool)),
                        this, SLOT(do_set_mouse_enable(bool)));
+
+       
 #ifdef USE_TAPE_BUTTON
        hRunEmu->set_tape_play(false);
 #endif
-#ifdef USE_LED_DEVICE
+#if defined(USE_KEY_LOCKED) || defined(USE_LED_DEVICE)
        connect(hRunEmu, SIGNAL(sig_send_data_led(quint32)), this, SLOT(do_recv_data_led(quint32)));
 #endif
 #ifdef USE_AUTO_KEY
        connect(this, SIGNAL(sig_start_auto_key(QString)), hRunEmu, SLOT(do_start_auto_key(QString)));
        connect(this, SIGNAL(sig_stop_auto_key()), hRunEmu, SLOT(do_stop_auto_key()));
+       connect(this, SIGNAL(sig_set_roma_kana(bool)), hRunEmu, SLOT(set_romakana(bool)));
 #endif 
        //connect(actionExit_Emulator, SIGNAL(triggered()), hRunEmu, SLOT(doExit()));
        csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "EmuThread : Start.");
        objNameStr = QString("EmuThreadClass");
        hRunEmu->setObjectName(objNameStr);
        
-       hDrawEmu = new DrawThreadClass(emu, emu->get_osd(), this);
+       hDrawEmu = new DrawThreadClass(emu->get_osd(), csp_logger, this);
        emu->set_parent_handler(hRunEmu, hDrawEmu);
        
 #ifdef ONE_BOARD_MICRO_COMPUTER
@@ -267,17 +262,24 @@ void Ui_MainWindow::LaunchEmuThread(void)
 #endif
        csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "DrawThread : Start.");
        connect(hDrawEmu, SIGNAL(sig_draw_frames(int)), hRunEmu, SLOT(print_framerate(int)));
+       //connect(emu->get_osd(), SIGNAL(sig_draw_frames(int)), hRunEmu, SLOT(print_framerate(int)));
        connect(hRunEmu, SIGNAL(window_title_changed(QString)), this, SLOT(do_set_window_title(QString)));
        connect(hDrawEmu, SIGNAL(message_changed(QString)), this, SLOT(message_status_bar(QString)));
        connect(actionCapture_Screen, SIGNAL(triggered()), glv, SLOT(do_save_frame_screen()));
-               
-       connect(hRunEmu, SIGNAL(sig_draw_thread(bool)), hDrawEmu, SLOT(doDraw(bool)), Qt::QueuedConnection);
+
+       /*if(config.use_separate_thread_draw) {
+               connect(hRunEmu, SIGNAL(sig_draw_thread(bool)), hDrawEmu, SLOT(doDraw(bool)), Qt::QueuedConnection);
+               connect(hRunEmu, SIGNAL(sig_set_draw_fps(double)), hDrawEmu, SLOT(do_set_frames_per_second(double)), Qt::QueuedConnection);
+               connect(hRunEmu, SIGNAL(sig_draw_one_turn(bool)), hDrawEmu, SLOT(do_draw_one_turn(bool)), Qt::QueuedConnection);
+               } else*/ {
+               connect(hRunEmu, SIGNAL(sig_draw_thread(bool)), hDrawEmu, SLOT(doDraw(bool)));
+               connect(hRunEmu, SIGNAL(sig_set_draw_fps(double)), hDrawEmu, SLOT(do_set_frames_per_second(double)));
+               connect(hRunEmu, SIGNAL(sig_draw_one_turn(bool)), hDrawEmu, SLOT(do_draw_one_turn(bool)));
+       }
+       //connect(hRunEmu, SIGNAL(sig_draw_thread(bool)), emu->get_osd(), SLOT(do_draw(bool)));
        //connect(hRunEmu, SIGNAL(quit_draw_thread()), hDrawEmu, SLOT(doExit()));
        connect(this, SIGNAL(quit_draw_thread()), hDrawEmu, SLOT(doExit()));
 
-//     connect(glv, SIGNAL(sig_draw_timing(bool)), hRunEmu, SLOT(do_draw_timing(bool)));
-//     connect(hDrawEmu, SIGNAL(sig_draw_timing(bool)), hRunEmu, SLOT(do_draw_timing(bool)));
-       
        connect(glv, SIGNAL(do_notify_move_mouse(int, int)),
                        hRunEmu, SLOT(moved_mouse(int, int)));
        connect(glv, SIGNAL(do_notify_button_pressed(Qt::MouseButton)),
@@ -290,6 +292,7 @@ void Ui_MainWindow::LaunchEmuThread(void)
 #endif
        connect(hRunEmu, SIGNAL(sig_resize_screen(int, int)),
                        glv, SLOT(resizeGL(int, int)));
+       connect(hRunEmu, SIGNAL(sig_resize_osd(int)), driveData, SLOT(setScreenWidth(int)));
        
        connect(glv, SIGNAL(sig_resize_uibar(int, int)),
                        this, SLOT(resize_statusbar(int, int)));
@@ -302,17 +305,19 @@ void Ui_MainWindow::LaunchEmuThread(void)
        connect(hRunEmu, SIGNAL(sig_finished()), this, SLOT(delete_emu_thread()));
        objNameStr = QString("EmuDrawThread");
        hDrawEmu->setObjectName(objNameStr);
-       hDrawEmu->start();
+
+       if(config.use_separate_thread_draw) hDrawEmu->start();
+
        csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "DrawThread : Launch done.");
 
-       hSaveMovieThread = new MOVIE_SAVER(640, 400,  30, emu->get_osd(), using_flags->get_config_ptr());
+       hSaveMovieThread = new MOVIE_SAVER(640, 400,  30, emu->get_osd(), &config);
        
-       connect(actionStart_Record_Movie->binds, SIGNAL(sig_start_record_movie(int)), hRunEmu, SLOT(doStartRecordVideo(int)));
+       connect(actionStart_Record_Movie->binds, SIGNAL(sig_start_record_movie(int)), hRunEmu, SLOT(do_start_record_video(int)));
        connect(this, SIGNAL(sig_start_saving_movie()),
                        actionStart_Record_Movie->binds, SLOT(do_save_as_movie()));
        connect(actionStart_Record_Movie, SIGNAL(triggered()), this, SLOT(do_start_saving_movie()));
 
-       connect(actionStop_Record_Movie->binds, SIGNAL(sig_stop_record_movie()), hRunEmu, SLOT(doStopRecordVideo()));
+       connect(actionStop_Record_Movie->binds, SIGNAL(sig_stop_record_movie()), hRunEmu, SLOT(do_stop_record_video()));
        connect(this, SIGNAL(sig_stop_saving_movie()), actionStop_Record_Movie->binds, SLOT(do_stop_saving_movie()));
        connect(hSaveMovieThread, SIGNAL(sig_set_state_saving_movie(bool)), this, SLOT(do_set_state_saving_movie(bool)));
        connect(actionStop_Record_Movie, SIGNAL(triggered()), this, SLOT(do_stop_saving_movie()));
@@ -343,11 +348,13 @@ void Ui_MainWindow::LaunchEmuThread(void)
        csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "MovieThread : Launch done.");
 
        connect(action_SetupMovie, SIGNAL(triggered()), this, SLOT(rise_movie_dialog()));
-
+       connect(hRunEmu, SIGNAL(sig_change_osd(int, int, QString)), driveData, SLOT(updateMessage(int, int, QString)));
+       connect(hRunEmu, SIGNAL(sig_change_access_lamp(int, int, QString)), driveData, SLOT(updateLabel(int, int, QString)));
+       connect(hRunEmu, SIGNAL(sig_set_access_lamp(int, bool)), graphicsView, SLOT(do_display_osd_leds(int, bool)));
 
        hRunEmu->start();
        csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "EmuThread : Launch done.");
-       this->set_screen_aspect(using_flags->get_config_ptr()->window_stretch_type);
+       this->set_screen_aspect(config.window_stretch_type);
        emit sig_movie_set_width(SCREEN_WIDTH);
        emit sig_movie_set_height(SCREEN_HEIGHT);
 }
@@ -355,7 +362,7 @@ void Ui_MainWindow::LaunchEmuThread(void)
 void Ui_MainWindow::LaunchJoyThread(void)
 {
 #if defined(USE_JOYSTICK)
-       hRunJoy = new JoyThreadClass(emu, emu->get_osd(), using_flags, using_flags->get_config_ptr());
+       hRunJoy = new JoyThreadClass(emu, emu->get_osd(), using_flags, &config, csp_logger);
        connect(this, SIGNAL(quit_joy_thread()), hRunJoy, SLOT(doExit()));
        hRunJoy->setObjectName("JoyThread");
        hRunJoy->start();
@@ -377,7 +384,6 @@ void Ui_MainWindow::delete_joy_thread(void)
 
 void Ui_MainWindow::on_actionExit_triggered()
 {
-       save_config(create_local_path(_T("%s.ini"), _T(CONFIG_NAME)));
        OnMainWindowClosed();
 }
 
@@ -404,6 +410,8 @@ bool Ui_MainWindow::GetPowerState(void)
 }
 #endif
 
+#include <string>
+
 void Ui_MainWindow::OnMainWindowClosed(void)
 {
        // notify power off
@@ -419,7 +427,7 @@ void Ui_MainWindow::OnMainWindowClosed(void)
        }
 #endif
        if(statusUpdateTimer != NULL) statusUpdateTimer->stop();
-#ifdef USE_LED_DEVICE
+#if defined(USE_KEY_LOCKED) || defined(USE_LED_DEVICE)
        if(ledUpdateTimer != NULL) ledUpdateTimer->stop();
 #endif
        emit quit_draw_thread();
@@ -431,24 +439,41 @@ void Ui_MainWindow::OnMainWindowClosed(void)
        if(hSaveMovieThread != NULL) {
                hSaveMovieThread->wait();
                delete hSaveMovieThread;
+               hSaveMovieThread = NULL;
        }
    
        if(hDrawEmu != NULL) {
                hDrawEmu->wait();
                delete hDrawEmu;
+               hDrawEmu = NULL;
        }
        if(hRunEmu != NULL) {
+               OnCloseDebugger();
                hRunEmu->quit();
                hRunEmu->wait();
                delete hRunEmu;
+#if 0
+               save_config(create_local_path(_T("%s.ini"), _T(CONFIG_NAME)));
+#else
+               {
+                       char tmps[128];
+                       std::string localstr;
+                       snprintf(tmps, sizeof(tmps), _T("%s.ini"), _T(CONFIG_NAME));
+                       localstr = tmps;
+                       localstr = cpp_confdir + localstr;
+                       save_config(localstr.c_str());
+               }
+#endif
        }
 #if defined(USE_JOYSTICK)
        if(hRunJoy != NULL) {
                hRunJoy->wait();
                delete hRunJoy;
+               hRunJoy = NULL;
        }
-#endif 
+#endif
        do_release_emu_resources();
+       hRunEmu = NULL;
 
        // release window
        if(now_fullscreen) {
@@ -477,17 +502,29 @@ void Ui_MainWindow::do_release_emu_resources(void)
        }
 }
 
-extern void get_long_full_path_name(_TCHAR* src, _TCHAR* dst);
-extern _TCHAR* get_parent_dir(_TCHAR* file);
+extern void DLL_PREFIX_I get_long_full_path_name(_TCHAR* src, _TCHAR* dst);
+extern _TCHAR* DLL_PREFIX_I get_parent_dir(_TCHAR* file);
 extern void get_short_filename(_TCHAR *dst, _TCHAR *file, int maxlen);
 
+#if defined(Q_OS_CYGWIN)       
+#include <sys/stat.h>
+#endif
+static void my_util_mkdir(std::string n)
+{
+#if !defined(Q_OS_CYGWIN)      
+               QDir dir = QDir::current();
+               dir.mkdir( QString::fromStdString(n));
+#else
+               struct stat st;
+               if(stat(n.c_str(), &st) != 0) {
+                       _mkdir(n.c_str()); // Not found
+               }
+#endif   
+}      
 
 static void setup_logs(void)
 {
-       std::string archstr;
        std::string delim;
-       int  bLogSYSLOG;
-       int  bLogSTDOUT;
        char    *p;
 
        my_procname = "emu";
@@ -516,35 +553,19 @@ static void setup_logs(void)
        cpp_homedir = ".";
 #endif 
        cpp_homedir = cpp_homedir + delim;
-#ifdef _WINDOWS
-       cpp_confdir = cpp_homedir + my_procname + delim;
+
+#if !defined(CSP_OS_WINDOWS)
+       cpp_confdir = cpp_homedir + ".config" + delim;
+       my_util_mkdir(cpp_confdir);
 #else
-       cpp_confdir = cpp_homedir + ".config" + delim + my_procname + delim;
-#endif
-       bLogSYSLOG = (int)0;
-       bLogSTDOUT = (int)1;
-       //csp_logger = new CSP_Logger((bLogSYSLOG != 0), (bLogSTDOUT != 0), DEVICE_NAME); // Write to syslog, console
-       
-       archstr = "Generic";
-#if defined(__x86_64__)
-       archstr = "amd64";
-#endif
-#if defined(__i386__)
-       archstr = "ia32";
+       cpp_confdir = cpp_homedir;
 #endif
+
+       cpp_confdir = cpp_confdir + "CommonSourceCodeProject" + delim;
+       my_util_mkdir(cpp_confdir);
        
-       csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Start Common Source Project '%s'", my_procname.c_str());
-       csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "(C) Toshiya Takeda / Qt Version K.Ohta");
-       csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Architecture: %s", archstr.c_str());
-       
-       //csp_logger->debug_log(AGAR_LOG_INFO, " -? is print help(s).");
-       csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Moduledir = %s home = %s", cpp_confdir.c_str(), cpp_homedir.c_str()); // Debug
-#if !defined(Q_OS_CYGWIN)      
-       {
-               QDir dir;
-               dir.mkdir( QString::fromStdString(cpp_confdir));
-       }
-#endif   
+       cpp_confdir = cpp_confdir + my_procname + delim;
+       my_util_mkdir(cpp_confdir);
    //AG_MkPath(cpp_confdir.c_str());
    /* Gettext */
 #ifndef RSSDIR
@@ -559,79 +580,817 @@ static void setup_logs(void)
 #endif
 }
 
-int MainLoop(int argc, char *argv[], config_t *cfg)
+QStringList virtualMediaList; // {TYPE, POSITION}
+QCommandLineOption *_opt_fds[8];
+QCommandLineOption *_opt_hdds[8];
+QCommandLineOption *_opt_cmts[2];
+QCommandLineOption *_opt_lds[2];
+QCommandLineOption *_opt_cds[2];
+QCommandLineOption *_opt_binaries[8];
+QCommandLineOption *_opt_bubbles[8];
+QCommandLineOption *_opt_qds[8];
+QCommandLineOption *_opt_carts[8];
+extern QCommandLineOption *_opt_homedir;
+extern QCommandLineOption *_opt_cfgfile;
+extern QCommandLineOption *_opt_cfgdir;
+extern QCommandLineOption *_opt_resdir;
+extern QCommandLineOption *_opt_opengl;
+extern QCommandLineOption *_opt_envver;
+extern QCommandLineOption *_opt_dump_envver;
+extern QCommandLineOption *_opt_dipsw_on;
+extern QCommandLineOption *_opt_dipsw_off;
+extern QProcessEnvironment _envvers;
+bool _b_dump_envver;
+std::string config_fullpath;
+
+void SetFDOptions(QCommandLineParser *cmdparser)
+{
+#if defined(USE_FLOPPY_DISK)
+       for(int i = 0; i < USE_FLOPPY_DISK; i++) {
+               QString sfdType1 = QString::fromUtf8("fd%1").arg(i);
+               QString sfdType2 = QString::fromUtf8("vFd%1").arg(i);
+               QString sfdType3 = QString::fromUtf8("vFloppyDisk%1").arg(i);
+               QStringList _cl;
+               _cl.append(sfdType1);
+               _cl.append(sfdType2);
+               _cl.append(sfdType3);
+               _opt_fds[i] = new QCommandLineOption(_cl,QCoreApplication::translate("main", "Set virtual floppy disk %1.").arg(i) , "[D88_SLOT@]fullpath");
+               cmdparser->addOption(*_opt_fds[i]);
+               _cl.clear();
+       }
+#endif
+}
+
+void SetHDDOptions(QCommandLineParser *cmdparser)
+{
+#if defined(USE_HARD_DISK)
+       for(int i = 0; i < USE_HARD_DISK; i++) {
+               QString sfdType1 = QString::fromUtf8("hd%1").arg(i);
+               QString sfdType2 = QString::fromUtf8("vHd%1").arg(i);
+               QString sfdType3 = QString::fromUtf8("vHardDisk%1").arg(i);
+               QString sfdType4 = QString::fromUtf8("vHardDrive%1").arg(i);
+               QStringList _cl;
+               _cl.append(sfdType1);
+               _cl.append(sfdType2);
+               _cl.append(sfdType3);
+               _cl.append(sfdType4);
+               _opt_hdds[i] = new QCommandLineOption(_cl,QCoreApplication::translate("main", "Set virtual hard drive %1.").arg(i) , "[D88_SLOT@]fullpath");
+               cmdparser->addOption(*_opt_hdds[i]);
+               _cl.clear();
+       }
+#endif
+}
+
+void SetBinaryOptions(QCommandLineParser *cmdparser)
+{
+#if defined(USE_BINARY_FILE)
+       for(int i = 0; i < USE_BINARY_FILE; i++) {
+               QString sfdType1 = QString::fromUtf8("bin%1").arg(i);
+               QString sfdType2 = QString::fromUtf8("vBinary%1").arg(i);
+               QStringList _cl;
+               _cl.append(sfdType1);
+               _cl.append(sfdType2);
+               _opt_binaries[i] = new QCommandLineOption(_cl,QCoreApplication::translate("main", "Set virtual binary image %1.").arg(i) , "fullpath");
+               cmdparser->addOption(*_opt_binaries[i]);
+               _cl.clear();
+       }
+#endif
+}
+
+void SetCartOptions(QCommandLineParser *cmdparser)
+{
+#if defined(USE_CART)
+       for(int i = 0; i < USE_CART; i++) {
+               QString sfdType1 = QString::fromUtf8("cart%1").arg(i);
+               QString sfdType2 = QString::fromUtf8("vCart%1").arg(i);
+               QString sfdType3 = QString::fromUtf8("vCartridge%1").arg(i);
+               QStringList _cl;
+               _cl.append(sfdType1);
+               _cl.append(sfdType2);
+               _cl.append(sfdType3);
+               _opt_carts[i] = new QCommandLineOption(_cl,QCoreApplication::translate("main", "Set virtual cartridge %1 (mostly ROM).").arg(i) , "fullpath");
+               cmdparser->addOption(*_opt_carts[i]);
+               _cl.clear();
+       }
+#endif
+}
+void SetBubbleOptions(QCommandLineParser *cmdparser)
+{
+#if defined(USE_BUBBLE)
+       for(int i = 0; i < USE_BUBBLE; i++) {
+               QString sfdType1 = QString::fromUtf8("bub%1").arg(i);
+               QString sfdType2 = QString::fromUtf8("vBubble%1").arg(i);
+               QStringList _cl;
+               _cl.append(sfdType1);
+               _cl.append(sfdType2);
+               _opt_bubbles[i] = new QCommandLineOption(_cl,QCoreApplication::translate("main", "Set virtual bubble cartridge %1.").arg(i) , "[B88_SLOT@]fullpath");
+               cmdparser->addOption(*_opt_bubbles[i]);
+       }
+#endif
+}
+
+void SetLDOptions(QCommandLineParser *cmdparser)
+{
+#if defined(USE_LASER_DISC)
+       for(int i = 0; i < USE_LASER_DISC; i++) {
+               QString sfdType1 = QString::fromUtf8("ld%1").arg(i);
+               QString sfdType2 = QString::fromUtf8("vLaserDisc%1").arg(i);
+               QStringList _cl;
+               _cl.append(sfdType1);
+               _cl.append(sfdType2);
+               _opt_lds[i] = new QCommandLineOption(_cl, QCoreApplication::translate("main", "Set virtual laser disc %1 (mostly movie file).").arg(i) , "fullpath");
+               cmdparser->addOption(*_opt_lds[i]);
+               _cl.clear();
+       }
+#endif
+}
+void SetCDOptions(QCommandLineParser *cmdparser)
+{
+#if defined(USE_COMPACT_DISC)
+       for(int i = 0; i < USE_COMPACT_DISC; i++) {
+               QString sfdType1 = QString::fromUtf8("cd%1").arg(i);
+               QString sfdType2 = QString::fromUtf8("vCompactDisc%1").arg(i);
+               QStringList _cl;
+               _cl.append(sfdType1);
+               _cl.append(sfdType2);
+               _opt_cds[i] = new QCommandLineOption(_cl,QCoreApplication::translate("main", "Set virtual compact disc %1.").arg(i) , "fullpath");
+               cmdparser->addOption(*_opt_cds[i]);
+               _cl.clear();
+       }
+#endif
+}
+
+void SetCmtOptions(QCommandLineParser *cmdparser)
+{
+#if defined(USE_TAPE)
+       for(int i = 0; i < USE_TAPE; i++) {
+               QString sfdType1 = QString::fromUtf8("cmt%1").arg(i);
+               QString sfdType2 = QString::fromUtf8("tape%1").arg(i);
+               QString sfdType3 = QString::fromUtf8("vCmt%1").arg(i);
+               QString sfdType4 = QString::fromUtf8("vTape%1").arg(i);
+               QStringList _cl;
+               _cl.append(sfdType1);
+               _cl.append(sfdType2);
+               _cl.append(sfdType3);
+               _cl.append(sfdType4);
+               _opt_cmts[i] = new QCommandLineOption(_cl, QCoreApplication::translate("main", "Set virtual casette tape %1.").arg(i) , "fullpath");
+               cmdparser->addOption(*_opt_cmts[i]);
+               _cl.clear();
+       }
+#endif
+}
+
+void SetQuickDiskOptions(QCommandLineParser *cmdparser)
+{
+#if defined(USE_QUICK_DISK)
+       for(int i = 0; i < USE_QUICK_DISK; i++) {
+               QString sfdType1 = QString::fromUtf8("qd%1").arg(i);
+               QString sfdType2 = QString::fromUtf8("vQuickDisk%1").arg(i);
+
+               QStringList _cl;
+               _cl.append(sfdType1);
+               _cl.append(sfdType2);
+               _opt_qds[i] = new QCommandLineOption(_cl, QCoreApplication::translate("main", "Set virtual quick disk %1.").arg(i) , "fullpath");
+               cmdparser->addOption(*_opt_qds[i]);
+               _cl.clear();
+       }
+#endif
+}
+
+
+void SetProcCmdFD(QCommandLineParser *cmdparser, QStringList *_l)
+{
+#if defined(USE_FLOPPY_DISK)
+       for(int i = 0; i < USE_FLOPPY_DISK; i++) {
+               if(_opt_fds[i] != NULL) {
+                       if(cmdparser->isSet(*_opt_fds[i])) {
+                               QString sfdType = QString::fromUtf8("vFloppyDisk%1").arg(i);
+                               QString medianame = cmdparser->value(*_opt_fds[i]);
+                               _l->append(sfdType);
+                               _l->append(medianame);
+                       }
+               }
+       }
+#endif
+}
+
+void SetProcCmdHDD(QCommandLineParser *cmdparser, QStringList *_l)
+{
+#if defined(USE_HARD_DISK)
+       for(int i = 0; i < USE_HARD_DISK; i++) {
+               if(_opt_hdds[i] != NULL) {
+                       if(cmdparser->isSet(*_opt_hdds[i])) {
+                               QString sfdType = QString::fromUtf8("vHardDisk%1").arg(i);
+                               QString medianame = cmdparser->value(*_opt_hdds[i]);
+                               _l->append(sfdType);
+                               _l->append(medianame);
+                       }
+               }
+       }
+#endif
+}
+
+void SetProcCmdQuickDisk(QCommandLineParser *cmdparser, QStringList *_l)
+{
+#if defined(USE_QUICK_DISK)
+       for(int i = 0; i < USE_QUICK_DISK; i++) {
+               if(_opt_qds[i] != NULL) {
+                       if(cmdparser->isSet(*_opt_qds[i])) {
+                               QString sfdType = QString::fromUtf8("vQuickDisk%1").arg(i);
+                               QString medianame = cmdparser->value(*_opt_qds[i]);
+                               _l->append(sfdType);
+                               _l->append(medianame);
+                       }
+               }
+       }
+#endif
+}
+
+void SetProcCmdCmt(QCommandLineParser *cmdparser, QStringList *_l)
+{
+#if defined(USE_TAPE)
+       for(int i = 0; i < USE_TAPE; i++) {
+               if(_opt_cmts[i] != NULL) {
+                       if(cmdparser->isSet(*_opt_cmts[i])) {
+                               QString sfdType = QString::fromUtf8("vCmt%1").arg(i);
+                               QString medianame = cmdparser->value(*_opt_cmts[i]);
+                               _l->append(sfdType);
+                               _l->append(medianame);
+                       }
+               }
+       }
+#endif
+}
+
+void SetProcCmdBinary(QCommandLineParser *cmdparser, QStringList *_l)
+{
+#if defined(USE_BINARY_FILE)
+       for(int i = 0; i < USE_BINARY_FILE; i++) {
+               if(_opt_binaries[i] != NULL) {
+                       if(cmdparser->isSet(*_opt_binaries[i])) {
+                               QString sfdType = QString::fromUtf8("vBinary%1").arg(i);
+                               QString medianame = cmdparser->value(*_opt_binaries[i]);
+                               _l->append(sfdType);
+                               _l->append(medianame);
+                       }
+               }
+       }
+#endif
+}
+
+void SetProcCmdBubble(QCommandLineParser *cmdparser, QStringList *_l)
+{
+#if defined(USE_BUBBLE)
+       for(int i = 0; i < USE_BUBBLE; i++) {
+               if(_opt_bubbles[i] != NULL) {
+                       if(cmdparser->isSet(*_opt_bubbles[i])) {
+                               QString sfdType = QString::fromUtf8("vBubble%1").arg(i);
+                               QString medianame = cmdparser->value(*_opt_bubbles[i]);
+                               _l->append(sfdType);
+                               _l->append(medianame);
+                       }
+               }
+       }
+#endif
+}
+
+void SetProcCmdCart(QCommandLineParser *cmdparser, QStringList *_l)
+{
+#if defined(USE_CART)
+       for(int i = 0; i < USE_CART; i++) {
+               if(_opt_carts[i] != NULL) {
+                       if(cmdparser->isSet(*_opt_carts[i])) {
+                               QString sfdType = QString::fromUtf8("vCart%1").arg(i);
+                               QString medianame = cmdparser->value(*_opt_carts[i]);
+                               _l->append(sfdType);
+                               _l->append(medianame);
+                       }
+               }
+       }
+#endif
+}
+
+void SetProcCmdLD(QCommandLineParser *cmdparser, QStringList *_l)
+{
+#if defined(USE_LASER_DISC)
+       for(int i = 0; i < USE_LASER_DISC; i++) {
+               if(_opt_lds[i] != NULL) {
+                       if(cmdparser->isSet(*_opt_lds[i])) {
+                               QString sfdType = QString::fromUtf8("vLD%1").arg(i);
+                               QString medianame = cmdparser->value(*_opt_lds[i]);
+                               _l->append(sfdType);
+                               _l->append(medianame);
+                       }
+               }
+       }
+#endif
+}
+
+void SetProcCmdCD(QCommandLineParser *cmdparser, QStringList *_l)
+{
+#if defined(USE_COMPACT_DISC)
+       for(int i = 0; i < USE_COMPACT_DISC; i++) {
+               if(_opt_cds[i] != NULL) {
+                       if(cmdparser->isSet(*_opt_cds[i])) {
+                               QString sfdType = QString::fromUtf8("vCD%1").arg(i);
+                               QString medianame = cmdparser->value(*_opt_cds[i]);
+                               _l->append(sfdType);
+                               _l->append(medianame);
+                       }
+               }
+       }
+#endif
+}
+
+extern void SetOptions_Sub(QCommandLineParser *cmdparser);
+void SetOptions(QCommandLineParser *cmdparser)
+{
+       QString emudesc = QString::fromUtf8("Emulator for ");
+       emudesc = emudesc + QString::fromUtf8(DEVICE_NAME);
+    cmdparser->setApplicationDescription(emudesc);
+    cmdparser->addHelpOption();
+    //cmdparser->addVersionOption();
+
+       SetOptions_Sub(cmdparser);
+       QStringList _cl;
+       
+       for(int i = 0; i < 8; i++) {
+               _opt_fds[i] = NULL;
+               _opt_hdds[i] = NULL;
+               _opt_qds[i] = NULL;
+               _opt_bubbles[i] = NULL;
+               _opt_binaries[i] = NULL;
+               _opt_carts[i] = NULL;
+       }
+       for(int i = 0; i < 2; i++) {
+               _opt_cmts[i] = NULL;
+               _opt_lds[i] = NULL;
+               _opt_cds[i] = NULL;
+       }               
+
+       SetFDOptions(cmdparser);
+       SetHDDOptions(cmdparser);
+       //SetBinaryOptions(cmdparser); // Temporally disabled.
+       SetCmtOptions(cmdparser);
+       SetCartOptions(cmdparser);
+       SetBubbleOptions(cmdparser); // Temporally disabled.
+       SetQuickDiskOptions(cmdparser);
+       SetLDOptions(cmdparser); // Temporally disabled.
+       SetCDOptions(cmdparser);
+       
+    cmdparser->addOption(*_opt_envver);
+    cmdparser->addOption(*_opt_dump_envver);
+}
+
+extern void ProcessCmdLine_Sub(QCommandLineParser *cmdparser, QStringList *_l);
+
+void ProcessCmdLine(QCommandLineParser *cmdparser, QStringList *_l)
 {
-       char c;
-       char strbuf[2048];
-       bool flag;
        char homedir[PATH_MAX];
-       int thread_ret;
-       int w, h;
-       setup_logs();
-       cpp_homedir.copy(homedir, PATH_MAX - 1, 0);
-       flag = FALSE;
+       std::string delim;
+#if defined(Q_OS_WIN)
+       delim = "\\";
+#else
+       delim = "/";
+#endif
+       ProcessCmdLine_Sub(cmdparser, _l);      
+       {
+               char tmps[128];
+               std::string localstr;
+               memset(tmps, 0x00, 128);
+               if(cmdparser->isSet(*_opt_cfgfile)) {
+                       strncpy(tmps, cmdparser->value(*_opt_cfgfile).toLocal8Bit().constData(), 127);
+               }
+               if(strlen(tmps) <= 0){
+                       snprintf(tmps, sizeof(tmps), _T("%s.ini"), _T(CONFIG_NAME));
+               }
+               localstr = tmps;
+               localstr = cpp_confdir + localstr;
+               load_config(localstr.c_str());
+               config_fullpath = localstr;
+       }
+       if(cmdparser->isSet(*_opt_opengl)) {
+               char tmps[128] = {0};
+               strncpy(tmps, cmdparser->value(*_opt_opengl).toLocal8Bit().constData(), 128 - 1);
+               if(strlen(tmps) > 0) {
+                       QString render = QString::fromLocal8Bit(tmps).toUpper();
+                       if((render == QString::fromUtf8("GL2")) ||
+                          (render == QString::fromUtf8("GLV2"))) {
+                               config.render_platform = CONFIG_RENDER_PLATFORM_OPENGL_MAIN;
+                               config.render_major_version = 2;
+                               config.render_minor_version = 0;
+                               GuiMain->setAttribute(Qt::AA_UseDesktopOpenGL, true);
+                               GuiMain->setAttribute(Qt::AA_UseOpenGLES, false);
+                       } else if((render == QString::fromUtf8("GL3")) ||
+                                         (render == QString::fromUtf8("GLV3")) ||
+                                         (render == QString::fromUtf8("OPENGLV3")) ||
+                                         (render == QString::fromUtf8("OPENGL")) ||
+                                         (render == QString::fromUtf8("GL"))) {
+                               config.render_platform = CONFIG_RENDER_PLATFORM_OPENGL_MAIN;
+                               config.render_major_version = 3;
+                               config.render_minor_version = 0;
+                               GuiMain->setAttribute(Qt::AA_UseDesktopOpenGL, true);
+                               GuiMain->setAttribute(Qt::AA_UseOpenGLES, false);
+                       } else if((render == QString::fromUtf8("GLES2")) ||
+                                        (render == QString::fromUtf8("GLESV2")) ||
+                                        (render == QString::fromUtf8("GLES3")) ||
+                                        (render == QString::fromUtf8("GLESV3")) ||
+                                        (render == QString::fromUtf8("GLES"))) {
+                               config.render_platform = CONFIG_RENDER_PLATFORM_OPENGL_ES;
+                               config.render_major_version = 2;
+                               config.render_minor_version = 1;
+                               GuiMain->setAttribute(Qt::AA_UseDesktopOpenGL, false);
+                               GuiMain->setAttribute(Qt::AA_UseOpenGLES, true);
+                       } else if((render == QString::fromUtf8("GL4")) ||
+                                        (render == QString::fromUtf8("GL43")) ||
+                                        (render == QString::fromUtf8("GL4.3")) ||
+                                        (render == QString::fromUtf8("GL4_3")) ||
+                                        (render == QString::fromUtf8("GL4_CORE"))) {
+                               config.render_platform = CONFIG_RENDER_PLATFORM_OPENGL_CORE;
+                               config.render_major_version = 4;
+                               config.render_minor_version = 3;
+                               GuiMain->setAttribute(Qt::AA_UseDesktopOpenGL, true);
+                               GuiMain->setAttribute(Qt::AA_UseOpenGLES, false);
+                       }
+               }
+       }
+       SetProcCmdFD(cmdparser, _l);
+       SetProcCmdHDD(cmdparser, _l);
+       SetProcCmdQuickDisk(cmdparser, _l);
+       SetProcCmdCmt(cmdparser, _l);
+       SetProcCmdCart(cmdparser, _l);
+       SetProcCmdBinary(cmdparser, _l);
+       SetProcCmdBubble(cmdparser, _l);
+       SetProcCmdLD(cmdparser, _l);
+       SetProcCmdCD(cmdparser, _l);
+
+#if 0
+       memset(homedir, 0x00, PATH_MAX);
+       if(cmdparser->isSet(*_opt_homedir)) {
+               strncpy(homedir, cmdparser->value(*_opt_homedir).toLocal8Bit().constData(), PATH_MAX - 1);
+               cpp_homedir = homedir;
+               size_t _len = cpp_homedir.length() - 1;
+               size_t _pos = cpp_homedir.rfind(delim);
+               if((_pos < _len) ||
+                  (_pos == std::string::npos)) {
+                       cpp_homedir.append(delim);
+               }
+       } else {
+               cpp_homedir.copy(homedir, PATH_MAX - 1, 0);
+       }
+
+       if(cmdparser->isSet(*_opt_cfgdir)) {
+               char tmps[PATH_MAX];
+               std::string tmpstr;
+               memset(tmps, 0x00, PATH_MAX);
+               strncpy(tmps, cmdparser->value(*_opt_cfgdir).toLocal8Bit().constData(), PATH_MAX - 1);
+               cpp_confdir = tmps;
+               size_t _len = cpp_confdir.length() - 1;
+               size_t _pos = cpp_confdir.rfind(delim);
+               if((_pos < _len) ||
+                  (_pos == std::string::npos)) {
+                       cpp_confdir.append(delim);
+               }
+       }
+       
+       {
+               char tmps[128];
+               std::string localstr;
+               memset(tmps, 0x00, 128);
+               if(cmdparser->isSet(*_opt_cfgfile)) {
+                       strncpy(tmps, cmdparser->value(*_opt_cfgfile).toLocal8Bit().constData(), 127);
+               }
+               if(strlen(tmps) <= 0){
+                       snprintf(tmps, sizeof(tmps), _T("%s.ini"), _T(CONFIG_NAME));
+               }
+               localstr = tmps;
+               localstr = cpp_confdir + localstr;
+               load_config(localstr.c_str());
+               config_fullpath = localstr;
+       }
+       if(cmdparser->isSet(*_opt_resdir)) {
+               char tmps[PATH_MAX];
+               std::string tmpstr;
+               memset(tmps, 0x00, PATH_MAX);
+               strncpy(tmps, cmdparser->value(*_opt_resdir).toLocal8Bit().constData(), PATH_MAX - 1);
+               sRssDir = tmps;
+               size_t _len = sRssDir.length() - 1;
+               size_t _pos = sRssDir.rfind(delim);
+               if((_pos < _len) ||
+                  (_pos == std::string::npos)) {
+                       sRssDir.append(delim);
+               }
+       }
+       if(cmdparser->isSet(*_opt_opengl)) {
+               char tmps[128] = {0};
+               strncpy(tmps, cmdparser->value(*_opt_opengl).toLocal8Bit().constData(), 128 - 1);
+               if(strlen(tmps) > 0) {
+                       QString render = QString::fromLocal8Bit(tmps).toUpper();
+                       if((render == QString::fromUtf8("GL2")) ||
+                          (render == QString::fromUtf8("GLV2"))) {
+                               config.render_platform = CONFIG_RENDER_PLATFORM_OPENGL_MAIN;
+                               config.render_major_version = 2;
+                               config.render_minor_version = 0;
+                               GuiMain->setAttribute(Qt::AA_UseDesktopOpenGL, true);
+                               GuiMain->setAttribute(Qt::AA_UseOpenGLES, false);
+                       } else if((render == QString::fromUtf8("GL3")) ||
+                                         (render == QString::fromUtf8("GLV3")) ||
+                                         (render == QString::fromUtf8("OPENGLV3")) ||
+                                         (render == QString::fromUtf8("OPENGL")) ||
+                                         (render == QString::fromUtf8("GL"))) {
+                               config.render_platform = CONFIG_RENDER_PLATFORM_OPENGL_MAIN;
+                               config.render_major_version = 3;
+                               config.render_minor_version = 0;
+                               GuiMain->setAttribute(Qt::AA_UseDesktopOpenGL, true);
+                               GuiMain->setAttribute(Qt::AA_UseOpenGLES, false);
+                       } else if((render == QString::fromUtf8("GLES2")) ||
+                                        (render == QString::fromUtf8("GLESV2")) ||
+                                        (render == QString::fromUtf8("GLES3")) ||
+                                        (render == QString::fromUtf8("GLESV3")) ||
+                                        (render == QString::fromUtf8("GLES"))) {
+                               config.render_platform = CONFIG_RENDER_PLATFORM_OPENGL_ES;
+                               config.render_major_version = 2;
+                               config.render_minor_version = 1;
+                               GuiMain->setAttribute(Qt::AA_UseDesktopOpenGL, false);
+                               GuiMain->setAttribute(Qt::AA_UseOpenGLES, true);
+                       } else if((render == QString::fromUtf8("GL4")) ||
+                                        (render == QString::fromUtf8("GL43")) ||
+                                        (render == QString::fromUtf8("GL4.3")) ||
+                                        (render == QString::fromUtf8("GL4_3")) ||
+                                        (render == QString::fromUtf8("GL4_CORE"))) {
+                               config.render_platform = CONFIG_RENDER_PLATFORM_OPENGL_CORE;
+                               config.render_major_version = 4;
+                               config.render_minor_version = 3;
+                               GuiMain->setAttribute(Qt::AA_UseDesktopOpenGL, true);
+                               GuiMain->setAttribute(Qt::AA_UseOpenGLES, false);
+                       }
+               }
+       }
+       if(cmdparser->isSet(*_opt_envver)) {
+               QStringList nList = cmdparser->values(*_opt_envver);
+               QString tv;
+               //QProcessEnvironment ev = QProcessEnvironment::systemEnvironment();
+               QProcessEnvironment ev = _envvers;
+               if(nList.size() > 0) {
+                       for(int i = 0; i < nList.size(); i++) {
+                               tv = nList.at(i);
+                               if(tv.indexOf(QString::fromUtf8("-")) == 0) {
+                                       // Delete var
+                                       int n1 = tv.indexOf(QString::fromUtf8("="));
+                                       if(n1 > 0) {
+                                               tv = tv.left(n1).right(n1 - 1);
+                                       } else {
+                                               tv = tv.right(tv.length() - 1);
+                                       }
+                                       printf("DEBUG: DEL ENV:%s\n", tv.toLocal8Bit().constData());
+                                       ev.remove(tv);
+                               } else if(tv.indexOf(QString::fromUtf8("=")) > 0) {
+                                       // Delete var
+                                       int n1 = tv.indexOf(QString::fromUtf8("="));
+                                       QString skey;
+                                       QString sval;
+                                       skey = tv.left(n1);
+                                       if((tv.length() - n1) < 1) {
+                                               sval = QString::fromUtf8("");
+                                       } else {
+                                               sval = tv.right(tv.length() - n1 - 1);
+                                       }
+                                       printf("DEBUG: SET ENV:%s to %s\n", skey.toLocal8Bit().constData(), sval.toLocal8Bit().constData());
+                                       if(skey.length() > 0) ev.insert(skey, sval);
+                               } else if(tv.indexOf(QString::fromUtf8("=")) < 0) {
+                                       printf("DEBUG: SET ENV:%s to (NULL)\n", tv.toLocal8Bit().constData());
+                                       if(tv.length() > 0) ev.insert(tv, QString::fromUtf8(""));
+                               }
+                       }
+                       _envvers.swap(ev);
+               }
+       }
+       _b_dump_envver = false;
+       if(cmdparser->isSet(*_opt_dump_envver)) {
+               _b_dump_envver = true;
+       }
+#endif
+       uint32_t dipsw_onbits = 0x0000000;
+       uint32_t dipsw_offmask = 0xffffffff;
+       if(cmdparser->isSet(*_opt_dipsw_off)) {
+               QStringList bitList = cmdparser->values(*_opt_dipsw_off);
+               QString tv;
+               bool num_ok;
+               for(int i = 0; i < bitList.size(); i++) {
+                       tv = bitList.at(i);
+                       int _bit = tv.toInt(&num_ok);
+                       if(num_ok) {
+                               if((_bit >= 0) && (_bit < 32)) {
+                                       dipsw_offmask &= (uint32_t)(~(1 << _bit));
+                               }
+                       }
+               }
+       }
+       if(cmdparser->isSet(*_opt_dipsw_on)) {
+               QStringList bitList = cmdparser->values(*_opt_dipsw_on);
+               QString tv;
+               bool num_ok;
+               for(int i = 0; i < bitList.size(); i++) {
+                       tv = bitList.at(i);
+                       int _bit = tv.toInt(&num_ok);
+                       if(num_ok) {
+                               if((_bit >= 0) && (_bit < 32)) {
+                                       dipsw_onbits |= (uint32_t)(1 << _bit);
+                               }
+                       }
+               }
+       }
+       config.dipswitch &= dipsw_offmask;
+       config.dipswitch |= dipsw_onbits;
+}
+
+void OpeningMessage(std::string archstr)
+{
        csp_logger->set_emu_vm_name(DEVICE_NAME); // Write to syslog, console
-       /*
-        * Into Qt's Loop.
-        */
+       csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Start Common Source Project '%s'", my_procname.c_str());
+       csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "(C) Toshiya Takeda / Qt Version K.Ohta");
+       csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Architecture: %s", archstr.c_str());
+       csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Use -h or --help for help.");
+       
+       //csp_logger->debug_log(AGAR_LOG_INFO, " -? is print help(s).");
+       csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Home = %s, Resource directory = %s",
+                                                 cpp_homedir.c_str(),
+                                                 sRssDir.c_str()); // Debug
+       
+       csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Config dir = %s, config_file = %s",
+                                                 cpp_confdir.c_str(),
+                                                 config_fullpath.c_str()); // Debug
+       
+       csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "DIPSW VALUE IS 0x%08x", config.dipswitch);
+       if(virtualMediaList.size() >= 2) {
+               for(int i = 0; i < virtualMediaList.size(); i += 2) {
+                       csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Virtual media %d, type %s, name %s",
+                                                                 i / 2,
+                                                                 virtualMediaList.at(i).toLocal8Bit().constData(),
+                                                                 virtualMediaList.at(i + 1).toLocal8Bit().constData());
+               }
+       }
+}
+
+void SetupSDL(void)
+{
+       QStringList _el = _envvers.toStringList();
+       if(_el.size() > 0) {
+               for(int i = 0; i < _el.size(); i++) {
+                       QString _s = _el.at(i);
+                       if(_s.startsWith("SDL_")) {
+                               QString skey, svar;
+                               int _nl;
+                               _nl = _s.indexOf('=');
+                               if(_nl >= 0) {
+                                       skey = _s.left(_nl);
+                                       svar = _s.right(_s.length() - _nl);
+                               } else {
+                                       skey = _s;
+                                       svar = QString::fromUtf8("");
+                               }
+                               SDL_setenv(skey.toLocal8Bit().constData(), svar.toLocal8Bit().constData(), 1);
+                               csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Note: SDL ENVIROMENT : %s to %s.",
+                                                                         skey.toLocal8Bit().constData(),
+                                                                         svar.toLocal8Bit().constData());
+                       }
+               }
+       }
 #if defined(USE_SDL2)
        SDL_Init(SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER);
 #else
        SDL_Init(SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_VIDEO);
-       //SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO);
 #endif
        csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Audio and JOYSTICK subsystem was initialised.");
+}
+
+
+void SetupLogger(QObject *parent, std::string emustr, int _size)
+{
+
+       csp_logger = new CSP_Logger(parent, config.log_to_syslog, config.log_to_console, emustr.c_str()); // Write to syslog, console
+       csp_logger->set_log_stdout(CSP_LOG_DEBUG, true);
+       csp_logger->set_log_stdout(CSP_LOG_INFO, true);
+       csp_logger->set_log_stdout(CSP_LOG_WARN, true);
+       
+       csp_logger->set_state_log(0, config.state_log_to_recording);
+       csp_logger->set_state_log(1, config.state_log_to_syslog);
+       csp_logger->set_state_log(2, config.state_log_to_console);
+       
+       for(int ii = 0; ii < _size; ii++) {
+               for(int jj = 0; jj < 8; jj++) {
+                       csp_logger->set_device_node_log(ii, 1, jj, config.dev_log_to_syslog[ii][jj]);
+                       csp_logger->set_device_node_log(ii, 2, jj, config.dev_log_to_console[ii][jj]);
+                       csp_logger->set_device_node_log(ii, 0, jj, config.dev_log_recording[ii][jj]);
+               }
+       }
+}
+
+int MainLoop(int argc, char *argv[])
+{
+
+       std::string archstr;
+       std::string emustr("emu");
+       std::string cfgstr(CONFIG_NAME);
+       std::string delim;
+       QString emudesc;
+
+       setup_logs();
+#if defined(Q_OS_WIN)
+       delim = "\\";
+#else
+       delim = "/";
+#endif
+       
        GuiMain = new QApplication(argc, argv);
-       load_config(create_local_path(_T("%s.ini"), _T(CONFIG_NAME)));
+       GuiMain->setObjectName(QString::fromUtf8("Gui_Main"));
+       _envvers = QProcessEnvironment::systemEnvironment();
+       
+    QCommandLineParser cmdparser;
+
+       virtualMediaList.clear();
+       SetOptions(&cmdparser);
+
+       cmdparser.process(QCoreApplication::arguments());
+
+       ProcessCmdLine(&cmdparser, &virtualMediaList);
+
+       emustr = emustr + cfgstr;
+
+       SetupLogger(GuiMain, emustr, CSP_LOG_TYPE_VM_DEVICE_END - CSP_LOG_TYPE_VM_DEVICE_0 + 1);
+
        
-       USING_FLAGS *using_flags = new USING_FLAGS(cfg);
+       archstr = "Generic";
+#if defined(__x86_64__)
+       archstr = "amd64";
+#endif
+#if defined(__i386__)
+       archstr = "ia32";
+#endif
+       OpeningMessage(archstr);
+       SetupSDL();
+       /*
+        * Into Qt's Loop.
+        */
+
+       //SetupTranslators();
+       QTranslator local_translator;
+       QLocale s_locale;
+       if(local_translator.load(s_locale, QLatin1String("csp_qt_machine"), QLatin1String("_"), QLatin1String(":/"))) {
+               GuiMain->installTranslator(&local_translator);
+       }
+       QTranslator s_translator;
+       if(s_translator.load(s_locale, QLatin1String("csp_qt_gui"), QLatin1String("_"), QLatin1String(":/"))) {
+               GuiMain->installTranslator(&s_translator);
+       }
+       QTranslator common_translator;
+       if(common_translator.load(s_locale, QLatin1String("csp_qt_common"), QLatin1String("_"), QLatin1String(":/"))) {
+               GuiMain->installTranslator(&common_translator);
+       }
+       QTranslator debugger_translator;
+       if(debugger_translator.load(s_locale, QLatin1String("csp_qt_debugger"), QLatin1String("_"), QLatin1String(":/"))) {
+               GuiMain->installTranslator(&debugger_translator);
+       }
+       //QProcessEnvironment::systemEnvironment() = _envvers;
+       if(_b_dump_envver) {
+               //QProcessEnvironment ev = QProcessEnvironment::systemEnvironment();
+               QProcessEnvironment ev = _envvers;
+               QStringList el = _envvers.toStringList();
+               if(el.size() > 0) {
+                       csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Environment Variables:");
+                       for(int i = 0; i < el.size(); i++) {
+                               csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "#%d : %s", i, el.at(i).toLocal8Bit().constData());
+                       }
+               }
+       }
+       
+       USING_FLAGS_EXT *using_flags = new USING_FLAGS_EXT(&config);
        // initialize emulation core
-       rMainWindow = new META_MainWindow(using_flags);
+       rMainWindow = new META_MainWindow(using_flags, csp_logger);
        rMainWindow->connect(rMainWindow, SIGNAL(sig_quit_all(void)), rMainWindow, SLOT(deleteLater(void)));
        rMainWindow->setCoreApplication(GuiMain);
        rMainWindow->getWindow()->show();
-       
-       emu = new EMU(rMainWindow, rMainWindow->getGraphicsView(), using_flags);
-       using_flags->set_emu(emu);
-       using_flags->set_osd(emu->get_osd());
-       csp_logger->set_osd(emu->get_osd());
-       csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "InitInstance() OK.");
-       
+                       
+       // main loop
+       rMainWindow->LaunchEmuThread();
+#if defined(USE_JOYSTICK)
+       rMainWindow->LaunchJoyThread();
+#endif 
+       GLDrawClass *pgl = rMainWindow->getGraphicsView();
+       pgl->set_emu_launched();
+       pgl->setFixedSize(pgl->width(), pgl->height());
        rMainWindow->retranselateUi_Depended_OSD();
-
        QObject::connect(emu->get_osd(), SIGNAL(sig_update_device_node_name(int, const _TCHAR *)),
                                         rMainWindow, SLOT(do_update_device_node_name(int, const _TCHAR *)));
        for(int i = 0; i < (CSP_LOG_TYPE_VM_DEVICE_END - CSP_LOG_TYPE_VM_DEVICE_0 + 1); i++) {
                rMainWindow->do_update_device_node_name(i, using_flags->get_vm_node_name(i));
        }
-                       
-#ifdef SUPPORT_DRAG_DROP
-       // open command line path
-       //      if(szCmdLine[0]) {
-       //      if(szCmdLine[0] == _T('"')) {
-       //              int len = strlen(szCmdLine);
-       //              szCmdLine[len - 1] = _T('\0');
-       //              szCmdLine++;
-       //      }
-       //      _TCHAR path[_MAX_PATH];
-       //      get_long_full_path_name(szCmdLine, path);
-       //      open_any_file(path);
-       //}
-#endif
-       
-       // set priority
-       
-       // main loop
-       GLDrawClass *pgl = rMainWindow->getGraphicsView();
-       pgl->setEmuPtr(emu);
-       pgl->setFixedSize(pgl->width(), pgl->height());
+       csp_logger->set_osd(emu->get_osd());
+       csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "InitInstance() OK.");
        
-#if defined(USE_JOYSTICK)
-       rMainWindow->LaunchJoyThread();
-#endif 
-       rMainWindow->LaunchEmuThread();
        QObject::connect(GuiMain, SIGNAL(lastWindowClosed()),
                                         rMainWindow, SLOT(on_actionExit_triggered()));
+
        GuiMain->exec();
        return 0;
 }
@@ -639,7 +1398,7 @@ int MainLoop(int argc, char *argv[], config_t *cfg)
 void Ui_MainWindow::do_update_inner_fd(int drv, QStringList base, class Action_Control **action_select_media_list,
                                       QStringList lst, int num, bool use_d88_menus)
 {
-#if defined(USE_FD1)
+#if defined(USE_FLOPPY_DISK)
        if(use_d88_menus) {
                for(int ii = 0; ii < using_flags->get_max_d88_banks(); ii++) {
                        if(ii < emu->d88_file[drv].bank_num) {
@@ -661,7 +1420,7 @@ void Ui_MainWindow::do_update_inner_fd(int drv, QStringList base, class Action_C
 void Ui_MainWindow::do_update_inner_bubble(int drv, QStringList base, class Action_Control **action_select_media_list,
                                       QStringList lst, int num, bool use_d88_menus)
 {
-#if defined(USE_BUBBLE1)       
+#if defined(USE_BUBBLE       
        if(use_d88_menus) {
                for(int ii = 0; ii < using_flags->get_max_b77_banks(); ii++) {
                        if(ii < emu->b77_file[drv].bank_num) {
@@ -680,20 +1439,82 @@ void Ui_MainWindow::do_update_inner_bubble(int drv, QStringList base, class Acti
 #endif 
 }
 
+int Ui_MainWindow::GetBubbleBankNum(int drv)
+{
+#if MAX_BUBBLE
+       if((emu != NULL) && (drv >= 0) && (drv < MAX_BUBBLE)) {
+               return emu->b77_file[drv].bank_num;
+       }
+#endif
+       return 0;
+}
+
+int Ui_MainWindow::GetBubbleCurrentBankNum(int drv)
+{
+#if MAX_BUBBLE
+       if((emu != NULL) && (drv >= 0) && (drv < MAX_BUBBLE)) {
+               return emu->b77_file[drv].cur_bank;
+       }
+#endif
+       return 0;
+}
+
+bool Ui_MainWindow::GetBubbleCasetteIsProtected(int drv)
+{
+#if MAX_BUBBLE
+       if(emu != NULL) {
+               if((drv >= 0) && (drv < MAX_BUBBLE)) {
+                       return emu->is_bubble_casette_protected(drv);
+               }
+       }
+#endif
+       return false;
+}
+
+QString Ui_MainWindow::GetBubbleB77FileName(int drv)
+{
+       QString ans = QString::fromUtf8("");
+#if MAX_BUBBLE
+       if(emu != NULL) {
+               if((drv < MAX_BUBBLE) && (drv >= 0)) {
+                       ans = QString::fromLocal8Bit(emu->b77_file[drv].path);
+               }
+       }
+#endif
+       return ans;
+}
+
+QString Ui_MainWindow::GetBubbleB77BubbleName(int drv, int num)
+{
+       QString ans = QString::fromUtf8("");
+#if MAX_BUBBLE
+       if(emu != NULL) {
+               if((drv < MAX_BUBBLE) && (drv >= 0)) {
+                       if((num >= 0) && (num < MAX_B77_BANKS)) {
+                               ans = QString::fromLocal8Bit(emu->b77_file[drv].bubble_name[num]);
+                       }
+               }
+       }
+#endif
+       return ans;
+}
+
 #ifdef USE_DEBUGGER
 #include <../debugger/qt_debugger.h>
 
 void Ui_MainWindow::OnOpenDebugger(int no)
 {
-       if((no < 0) || (no > 3)) return;
+       if((no < 0) || (no > 7)) return;
        //emu->open_debugger(no);
        VM *vm = emu->get_vm();
 
-       if(emu->now_debugging)  this->OnCloseDebugger();
+       if((emu->now_debugging ) || (emu->hDebugger != NULL)) /* OnCloseDebugger(); */ return;
+       
        if(!(emu->now_debugging && emu->debugger_thread_param.cpu_index == no)) {
                //emu->close_debugger();
                if(vm->get_cpu(no) != NULL && vm->get_cpu(no)->get_debugger() != NULL) {
-                       
+                       QString windowName = QString::fromUtf8(vm->get_cpu(no)->get_device_name());
+                       windowName = QString::fromUtf8("Debugger ") + windowName;
                        emu->hDebugger = new CSP_Debugger(this);
                        QString objNameStr = QString("EmuDebugThread");
                        emu->hDebugger->setObjectName(objNameStr);
@@ -702,7 +1523,7 @@ void Ui_MainWindow::OnOpenDebugger(int no)
                        emu->hDebugger->debugger_thread_param.cpu_index = no;
                        emu->stop_record_sound();
                        emu->stop_record_video();
-                       emu->now_debugging = true;
+                       //emu->now_debugging = true;
                        connect(this, SIGNAL(quit_debugger_thread()), emu->hDebugger, SLOT(doExit()));
                        connect(this, SIGNAL(destroyed()), emu->hDebugger, SLOT(do_destroy_thread()));
                        //connect(this, SIGNAL(quit_debugger_thread()), emu->hDebugger, SLOT(close()));
@@ -710,6 +1531,7 @@ void Ui_MainWindow::OnOpenDebugger(int no)
                        connect(emu->hDebugger, SIGNAL(sig_put_string(QString)), emu->hDebugger, SLOT(put_string(QString)));
                        emu->hDebugger->show();
                        emu->hDebugger->run();
+                       emu->hDebugger->setWindowTitle(windowName);
                }
        }
 }
@@ -723,9 +1545,96 @@ void Ui_MainWindow::OnCloseDebugger(void )
                        emit quit_debugger_thread();
                        //emu->hDebugger->wait();
                }
-               delete emu->hDebugger;
-               emu->hDebugger = NULL;
-               emu->now_debugging = false;
        }
+       if(emu != NULL) {
+               if(emu->hDebugger != NULL) {
+                       delete emu->hDebugger;
+                       emu->hDebugger = NULL;
+               }
+               emu->now_debugging = false;
+       }
+}
+#endif
+
+QString Ui_MainWindow::get_system_version()
+{
+       QString guiver = get_gui_version();
+       QString aviover;
+       QString vm_gitver;
+       QString common_vmver;
+       QString osdver;
+       QString libcommon_ver;
+       QString libfmgen_ver;
+       QString build_date;
+       
+       QString outstr;
+       
+       aviover.clear();
+       common_vmver.clear();
+       vm_gitver.clear();
+       osdver.clear();
+       libcommon_ver.clear();
+       
+       if(hSaveMovieThread != NULL) {
+               aviover = hSaveMovieThread->get_avio_version();
+       }
+       if(emu != NULL) {
+               if(emu->get_osd() != NULL) {
+                       _TCHAR *cvp = emu->get_osd()->get_lib_common_vm_version();
+                       _TCHAR *gvp = emu->get_osd()->get_lib_common_vm_git_version();
+                       _TCHAR *ovp = emu->get_osd()->get_lib_osd_version();
+                       if(cvp != NULL) {
+                               common_vmver = QString::fromUtf8(cvp);
+                       }
+                       if(gvp != NULL) {
+                               vm_gitver = QString::fromUtf8(gvp);
+                       }
+                       if(ovp != NULL) {
+                               osdver = QString::fromUtf8(ovp);
+                       }
+               }
+       }
+       
+       const _TCHAR *pp = get_lib_common_version();
+       if(pp != NULL) {
+               libcommon_ver = QString::fromUtf8(pp);
+       }
+       libfmgen_ver = QString::fromUtf8(FM::get_libfmgen_version());
+       
+       outstr.clear();
+       if(!(common_vmver.isEmpty())) {
+               outstr.append(common_vmver);
+               outstr.append("<BR>\n");
+       }
+       if(!(libcommon_ver.isEmpty())) {
+               outstr.append(libcommon_ver);
+               outstr.append("<BR>\n");
+       }
+       if(!(libfmgen_ver.isEmpty())) {
+               outstr.append(libfmgen_ver);
+               outstr.append("<BR>\n");
+       }
+       if(!(guiver.isEmpty())) {
+               outstr.append(guiver);
+               outstr.append("<BR>\n");
+       }
+       if(!(aviover.isEmpty())) {
+               outstr.append(aviover);
+               outstr.append("<BR>\n");
+       }
+       if(!(vm_gitver.isEmpty())) {
+               outstr.append("Build Version: ");
+               outstr.append(vm_gitver);
+               outstr.append("<BR>\n");
+       }
+       return outstr;
 }
+
+QString Ui_MainWindow::get_build_date()
+{
+#if defined(__BUILD_DATE)
+       return QString::fromUtf8(__BUILD_DATE);
+#else
+       return QString::fromUtf8("");
 #endif
+}