OSDN Git Service

1abb065c90b93b2477c655077b416bbec22dd302
[csp-qt/common_source_project-fm7.git] / source / src / qt / common / qt_utils.cpp
1 /*
2         Skelton for retropc emulator
3         Author : Takeda.Toshiya
4         Port to Qt : K.Ohta <whatisthis.sowhat _at_ gmail.com>
5         Date   : 2006.08.18 -
6
7         [ win32 main ] -> [ agar main ]
8 */
9
10 #include <stdio.h>
11 #include <string>
12 #include <vector>
13 #include <QApplication>
14 #include <QString>
15 #include <QTextCodec>
16 #include <QImage>
17 #include <QImageReader>
18 #include <QDateTime>
19 #include <QDir>
20 #include <QTranslator>
21 #include <QProcessEnvironment>
22
23 #include "common.h"
24 #include "fileio.h"
25 #include "emu.h"
26 #include "menuclasses.h"
27 #include "mainwidget.h"
28 #include "commonclasses.h"
29 #include "qt_main.h"
30 #include "emu_thread.h"
31 #include "joy_thread.h"
32 #include "draw_thread.h"
33
34 #include "qt_gldraw.h"
35 #include "../gui/gl2/qt_glutil_gl2_0.h"
36 #include "csp_logger.h"
37 #include "dock_disks.h"
38 #include "menu_disk.h"
39 #include "menu_bubble.h"
40 #include "menu_flags_ext.h"
41 #include "dialog_movie.h"
42 #include "../avio/movie_saver.h"
43 // emulation core
44
45 EMU* emu;
46 QApplication *GuiMain = NULL;
47
48 // Start to define MainWindow.
49 class META_MainWindow *rMainWindow;
50
51
52 // buttons
53 #ifdef MAX_BUTTONS
54 #define MAX_FONT_SIZE 32
55 #endif
56
57 // menu
58 extern std::string cpp_homedir;
59 extern DLL_PREFIX_I std::string cpp_confdir;
60 extern std::string my_procname;
61 std::string sRssDir;
62 bool now_menuloop = false;
63 static int close_notified = 0;
64 // timing control
65
66 // screen
67 unsigned int desktop_width;
68 unsigned int desktop_height;
69 //int desktop_bpp;
70 int prev_window_mode = 0;
71 bool now_fullscreen = false;
72
73 int window_mode_count;
74
75 void Ui_MainWindow::do_set_mouse_enable(bool flag)
76 {
77 #ifdef USE_MOUSE
78         if(emu == NULL) return;
79         emu->lock_vm();
80         if(flag) {
81                 graphicsView->grabMouse();
82                 emu->enable_mouse();
83         } else {
84                 graphicsView->releaseMouse();
85                 emu->disable_mouse();
86         }
87         emu->unlock_vm();
88 #endif  
89 }
90
91 void Ui_MainWindow::do_toggle_mouse(void)
92 {
93 #ifdef USE_MOUSE
94         if(emu == NULL) return;
95         emu->lock_vm();
96         bool flag = emu->is_mouse_enabled();
97         if(!flag) {
98                 graphicsView->grabMouse();
99                 emu->enable_mouse();
100         } else {
101                 graphicsView->releaseMouse();
102                 emu->disable_mouse();
103         }
104         emu->unlock_vm();
105 #endif  
106 }
107
108 void Ui_MainWindow::rise_movie_dialog(void)
109 {
110         CSP_DialogMovie *dlg = new CSP_DialogMovie(hSaveMovieThread, using_flags);
111         dlg->setWindowTitle(QApplication::translate("CSP_DialogMovie", "Configure movie encodings", 0));
112         dlg->show();
113 }
114 void Ui_MainWindow::LaunchEmuThread(void)
115 {
116         QString objNameStr;
117         GLDrawClass *glv = this->getGraphicsView();
118
119         int drvs;
120         
121         hRunEmu = new EmuThreadClass(rMainWindow, using_flags);
122         connect(hRunEmu, SIGNAL(message_changed(QString)), this, SLOT(message_status_bar(QString)));
123         connect(hRunEmu, SIGNAL(sig_is_enable_mouse(bool)), glv, SLOT(do_set_mouse_enabled(bool)));
124         connect(glv, SIGNAL(sig_key_down(uint32_t, uint32_t, bool)), hRunEmu, SLOT(do_key_down(uint32_t, uint32_t, bool)));
125         connect(glv, SIGNAL(sig_key_up(uint32_t, uint32_t)),hRunEmu, SLOT(do_key_up(uint32_t, uint32_t)));
126         connect(this, SIGNAL(sig_quit_widgets()), glv, SLOT(do_stop_run_vm()));
127
128         
129         //connect(hRunEmu, SIGNAL(sig_finished()), this, SLOT(delete_emu_thread()));
130         connect(this, SIGNAL(sig_vm_reset()), hRunEmu, SLOT(do_reset()));
131         connect(this, SIGNAL(sig_vm_specialreset()), hRunEmu, SLOT(do_special_reset()));
132
133         connect(this, SIGNAL(sig_emu_update_config()), hRunEmu, SLOT(do_update_config()));
134         connect(this, SIGNAL(sig_emu_update_volume_level(int, int)), hRunEmu, SLOT(do_update_volume_level(int, int)));
135         connect(this, SIGNAL(sig_emu_update_volume_balance(int, int)), hRunEmu, SLOT(do_update_volume_balance(int, int)));
136         connect(this, SIGNAL(sig_emu_start_rec_sound()), hRunEmu, SLOT(do_start_record_sound()));
137         connect(this, SIGNAL(sig_emu_stop_rec_sound()), hRunEmu, SLOT(do_stop_record_sound()));
138         connect(this, SIGNAL(sig_emu_set_display_size(int, int, int, int)), hRunEmu, SLOT(do_set_display_size(int, int, int, int)));
139         
140         if(using_flags->is_use_state()) {
141                 for(int i = 0; i < 10; i++) {
142                         connect(actionLoad_State[i], SIGNAL(sig_load_state(QString)), hRunEmu, SLOT(do_load_state(QString))); // OK?
143                         connect(actionSave_State[i], SIGNAL(sig_save_state(QString)), hRunEmu, SLOT(do_save_state(QString))); // OK?
144                 }
145         }
146 #if defined(USE_FLOPPY_DISK)
147         connect(this, SIGNAL(sig_write_protect_disk(int, bool)), hRunEmu, SLOT(do_write_protect_disk(int, bool)));
148         connect(this, SIGNAL(sig_open_disk(int, QString, int)), hRunEmu, SLOT(do_open_disk(int, QString, int)));
149         connect(this, SIGNAL(sig_close_disk(int)), hRunEmu, SLOT(do_close_disk(int)));
150         connect(hRunEmu, SIGNAL(sig_update_recent_disk(int)), this, SLOT(do_update_recent_disk(int)));
151         //connect(hRunEmu, SIGNAL(sig_change_osd_fd(int, QString)), this, SLOT(do_change_osd_fd(int, QString)));
152         drvs = USE_FLOPPY_DISK;
153         for(int ii = 0; ii < drvs; ii++) {
154                 menu_fds[ii]->setEmu(emu);
155                 connect(menu_fds[ii], SIGNAL(sig_update_inner_fd(int ,QStringList , class Action_Control **, QStringList , int, bool)),
156                                 this, SLOT(do_update_inner_fd(int ,QStringList , class Action_Control **, QStringList , int, bool)));
157         }
158 #endif
159 #if defined(USE_HARD_DISK)
160         connect(this, SIGNAL(sig_open_hard_disk(int, QString)), hRunEmu, SLOT(do_open_hard_disk(int, QString)));
161         connect(this, SIGNAL(sig_close_hard_disk(int)), hRunEmu, SLOT(do_close_hard_disk(int)));
162         connect(hRunEmu, SIGNAL(sig_update_recent_hard_disk(int)), this, SLOT(do_update_recent_hard_disk(int)));
163         //connect(hRunEmu, SIGNAL(sig_change_osd_fd(int, QString)), this, SLOT(do_change_osd_fd(int, QString)));
164 #endif
165 #if defined(USE_TAPE)
166         connect(this, SIGNAL(sig_play_tape(int, QString)), hRunEmu, SLOT(do_play_tape(int, QString)));
167         connect(this, SIGNAL(sig_rec_tape(int, QString)),  hRunEmu, SLOT(do_rec_tape(int, QString)));
168         connect(this, SIGNAL(sig_close_tape(int)),   hRunEmu, SLOT(do_close_tape(int)));
169         //connect(hRunEmu, SIGNAL(sig_change_osd_cmt(QString)), this, SLOT(do_change_osd_cmt(QString)));
170 # if defined(USE_TAPE_BUTTON)
171         connect(this, SIGNAL(sig_cmt_push_play(int)), hRunEmu, SLOT(do_cmt_push_play(int)));
172         connect(this, SIGNAL(sig_cmt_push_stop(int)), hRunEmu, SLOT(do_cmt_push_stop(int)));
173         connect(this, SIGNAL(sig_cmt_push_fast_forward(int)), hRunEmu, SLOT(do_cmt_push_fast_forward(int)));
174         connect(this, SIGNAL(sig_cmt_push_fast_rewind(int)),  hRunEmu, SLOT(do_cmt_push_fast_rewind(int)));
175         connect(this, SIGNAL(sig_cmt_push_apss_forward(int)), hRunEmu, SLOT(do_cmt_push_apss_forward(int)));
176         connect(this, SIGNAL(sig_cmt_push_apss_rewind(int)),  hRunEmu, SLOT(do_cmt_push_apss_rewind(int)));
177 # endif
178 #endif
179 #if defined(USE_QUICK_DISK)
180         connect(this, SIGNAL(sig_write_protect_quickdisk(int, bool)), hRunEmu, SLOT(do_write_protect_quickdisk(int, bool)));
181         connect(this, SIGNAL(sig_open_quickdisk(int, QString)), hRunEmu, SLOT(do_open_quickdisk(int, QString)));
182         connect(this, SIGNAL(sig_close_quickdisk(int)), hRunEmu, SLOT(do_close_quickdisk(int)));
183         //connect(hRunEmu, SIGNAL(sig_change_osd_qd(int, QString)), this, SLOT(do_change_osd_qd(int, QString)));
184 #endif
185 #if defined(USE_CART)
186         connect(this, SIGNAL(sig_open_cart(int, QString)), hRunEmu, SLOT(do_open_cart(int, QString)));
187         connect(this, SIGNAL(sig_close_cart(int)), hRunEmu, SLOT(do_close_cart(int)));
188 #endif
189 #if defined(USE_COMPACT_DISC)
190         connect(this, SIGNAL(sig_open_cdrom(int, QString)), hRunEmu, SLOT(do_open_cdrom(int, QString)));
191         connect(this, SIGNAL(sig_close_cdrom(int)), hRunEmu, SLOT(do_eject_cdrom(int)));
192         //connect(hRunEmu, SIGNAL(sig_change_osd_cdrom(QString)), this, SLOT(do_change_osd_cdrom(QString)));
193         // ToDo: multiple CDs
194 #endif  
195 #if defined(USE_LASER_DISC)
196         connect(this, SIGNAL(sig_open_laserdisc(int, QString)), hRunEmu, SLOT(do_open_laser_disc(int, QString)));
197         connect(this, SIGNAL(sig_close_laserdisc(int)), hRunEmu, SLOT(do_close_laser_disc(int)));
198         // ToDo: multiple LDs
199 #endif
200 #if defined(USE_BINARY_FILE)
201         connect(this, SIGNAL(sig_load_binary(int, QString)), hRunEmu, SLOT(do_load_binary(int, QString)));
202         connect(this, SIGNAL(sig_save_binary(int, QString)), hRunEmu, SLOT(do_save_binary(int, QString)));
203 #endif
204 #if defined(USE_BUBBLE)
205         connect(this, SIGNAL(sig_write_protect_bubble(int, bool)), hRunEmu, SLOT(do_write_protect_bubble_casette(int, bool)));
206         connect(this, SIGNAL(sig_open_bubble(int, QString, int)), hRunEmu, SLOT(do_open_bubble_casette(int, QString, int)));
207         connect(this, SIGNAL(sig_close_bubble(int)), hRunEmu, SLOT(do_close_bubble_casette(int)));
208         connect(hRunEmu, SIGNAL(sig_update_recent_bubble(int)), this, SLOT(do_update_recent_bubble(int)));
209         //connect(hRunEmu, SIGNAL(sig_change_osd_bubble(int, QString)), this, SLOT(do_change_osd_bubble(int, QString)));
210         drvs = USE_BUBBLE;
211         for(int ii = 0; ii < drvs; ii++) {
212                 menu_bubbles[ii]->setEmu(emu);
213                 connect(menu_bubbles[ii],
214                                 SIGNAL(sig_update_inner_bubble(int ,QStringList , class Action_Control **, QStringList , int, bool)),
215                                 this,
216                                 SLOT(do_update_inner_bubble(int ,QStringList , class Action_Control **, QStringList , int, bool)));
217         }
218 #endif
219         
220         connect(this, SIGNAL(quit_emu_thread()), hRunEmu, SLOT(doExit()));
221         connect(hRunEmu, SIGNAL(sig_mouse_enable(bool)),
222                         this, SLOT(do_set_mouse_enable(bool)));
223
224         
225 #ifdef USE_TAPE_BUTTON
226         hRunEmu->set_tape_play(false);
227 #endif
228 #if defined(USE_KEY_LOCKED) || defined(USE_LED_DEVICE)
229         connect(hRunEmu, SIGNAL(sig_send_data_led(quint32)), this, SLOT(do_recv_data_led(quint32)));
230 #endif
231 #ifdef USE_AUTO_KEY
232         connect(this, SIGNAL(sig_start_auto_key(QString)), hRunEmu, SLOT(do_start_auto_key(QString)));
233         connect(this, SIGNAL(sig_stop_auto_key()), hRunEmu, SLOT(do_stop_auto_key()));
234         connect(this, SIGNAL(sig_set_roma_kana(bool)), hRunEmu, SLOT(set_romakana(bool)));
235 #endif  
236         //connect(actionExit_Emulator, SIGNAL(triggered()), hRunEmu, SLOT(doExit()));
237         csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "EmuThread : Start.");
238         objNameStr = QString("EmuThreadClass");
239         hRunEmu->setObjectName(objNameStr);
240         
241         hDrawEmu = new DrawThreadClass(emu->get_osd(), csp_logger, this);
242         emu->set_parent_handler(hRunEmu, hDrawEmu);
243         
244 #ifdef ONE_BOARD_MICRO_COMPUTER
245         QImageReader *reader = new QImageReader(":/background.png");
246         QImage *result = new QImage(reader->read()); // this acts as a default if the size is not matched
247         QImage result2 = result->convertToFormat(QImage::Format_ARGB32);
248         glv->updateBitmap(&result2);
249         emu->get_osd()->upload_bitmap(&result2);
250         delete result;
251         delete reader;
252         emu->get_osd()->set_buttons();
253 #endif
254         csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "DrawThread : Start.");
255         connect(hDrawEmu, SIGNAL(sig_draw_frames(int)), hRunEmu, SLOT(print_framerate(int)));
256         //connect(emu->get_osd(), SIGNAL(sig_draw_frames(int)), hRunEmu, SLOT(print_framerate(int)));
257         connect(hRunEmu, SIGNAL(window_title_changed(QString)), this, SLOT(do_set_window_title(QString)));
258         connect(hDrawEmu, SIGNAL(message_changed(QString)), this, SLOT(message_status_bar(QString)));
259         connect(actionCapture_Screen, SIGNAL(triggered()), glv, SLOT(do_save_frame_screen()));
260
261         /*if(using_flags->get_config_ptr()->use_separate_thread_draw) {
262                 connect(hRunEmu, SIGNAL(sig_draw_thread(bool)), hDrawEmu, SLOT(doDraw(bool)), Qt::QueuedConnection);
263                 connect(hRunEmu, SIGNAL(sig_set_draw_fps(double)), hDrawEmu, SLOT(do_set_frames_per_second(double)), Qt::QueuedConnection);
264                 connect(hRunEmu, SIGNAL(sig_draw_one_turn(bool)), hDrawEmu, SLOT(do_draw_one_turn(bool)), Qt::QueuedConnection);
265                 } else*/ {
266                 connect(hRunEmu, SIGNAL(sig_draw_thread(bool)), hDrawEmu, SLOT(doDraw(bool)));
267                 connect(hRunEmu, SIGNAL(sig_set_draw_fps(double)), hDrawEmu, SLOT(do_set_frames_per_second(double)));
268                 connect(hRunEmu, SIGNAL(sig_draw_one_turn(bool)), hDrawEmu, SLOT(do_draw_one_turn(bool)));
269         }
270         //connect(hRunEmu, SIGNAL(sig_draw_thread(bool)), emu->get_osd(), SLOT(do_draw(bool)));
271         //connect(hRunEmu, SIGNAL(quit_draw_thread()), hDrawEmu, SLOT(doExit()));
272         connect(this, SIGNAL(quit_draw_thread()), hDrawEmu, SLOT(doExit()));
273
274         connect(glv, SIGNAL(do_notify_move_mouse(int, int)),
275                         hRunEmu, SLOT(moved_mouse(int, int)));
276         connect(glv, SIGNAL(do_notify_button_pressed(Qt::MouseButton)),
277                 hRunEmu, SLOT(button_pressed_mouse(Qt::MouseButton)));
278         connect(glv, SIGNAL(do_notify_button_released(Qt::MouseButton)),
279                         hRunEmu, SLOT(button_released_mouse(Qt::MouseButton)));
280 #ifdef USE_MOUSE
281         connect(glv, SIGNAL(sig_toggle_mouse(void)),
282                         this, SLOT(do_toggle_mouse(void)));
283 #endif
284         connect(hRunEmu, SIGNAL(sig_resize_screen(int, int)),
285                         glv, SLOT(resizeGL(int, int)));
286         connect(hRunEmu, SIGNAL(sig_resize_osd(int)), driveData, SLOT(setScreenWidth(int)));
287         
288         connect(glv, SIGNAL(sig_resize_uibar(int, int)),
289                         this, SLOT(resize_statusbar(int, int)));
290         connect(hRunEmu, SIGNAL(sig_resize_uibar(int, int)),
291                         this, SLOT(resize_statusbar(int, int)));
292
293         connect(emu->get_osd(), SIGNAL(sig_req_encueue_video(int, int, int)),
294                         hDrawEmu, SLOT(do_req_encueue_video(int, int, int)));
295         connect(hRunEmu, SIGNAL(sig_finished()), glv, SLOT(releaseKeyCode(void)));
296         connect(hRunEmu, SIGNAL(sig_finished()), this, SLOT(delete_emu_thread()));
297         objNameStr = QString("EmuDrawThread");
298         hDrawEmu->setObjectName(objNameStr);
299
300         if(using_flags->get_config_ptr()->use_separate_thread_draw) hDrawEmu->start();
301
302         csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "DrawThread : Launch done.");
303
304         hSaveMovieThread = new MOVIE_SAVER(640, 400,  30, emu->get_osd(), using_flags->get_config_ptr());
305         
306         connect(actionStart_Record_Movie->binds, SIGNAL(sig_start_record_movie(int)), hRunEmu, SLOT(do_start_record_video(int)));
307         connect(this, SIGNAL(sig_start_saving_movie()),
308                         actionStart_Record_Movie->binds, SLOT(do_save_as_movie()));
309         connect(actionStart_Record_Movie, SIGNAL(triggered()), this, SLOT(do_start_saving_movie()));
310
311         connect(actionStop_Record_Movie->binds, SIGNAL(sig_stop_record_movie()), hRunEmu, SLOT(do_stop_record_video()));
312         connect(this, SIGNAL(sig_stop_saving_movie()), actionStop_Record_Movie->binds, SLOT(do_stop_saving_movie()));
313         connect(hSaveMovieThread, SIGNAL(sig_set_state_saving_movie(bool)), this, SLOT(do_set_state_saving_movie(bool)));
314         connect(actionStop_Record_Movie, SIGNAL(triggered()), this, SLOT(do_stop_saving_movie()));
315
316         connect(emu->get_osd(), SIGNAL(sig_save_as_movie(QString, int, int)),
317                         hSaveMovieThread, SLOT(do_open(QString, int, int)));
318         connect(emu->get_osd(), SIGNAL(sig_stop_saving_movie()), hSaveMovieThread, SLOT(do_close()));
319         
320         actionStop_Record_Movie->setIcon(QIcon(":/icon_process_stop.png"));
321         actionStop_Record_Movie->setVisible(false);
322         
323         connect(this, SIGNAL(sig_movie_set_width(int)), hSaveMovieThread, SLOT(do_set_width(int)));
324         connect(this, SIGNAL(sig_movie_set_height(int)), hSaveMovieThread, SLOT(do_set_height(int)));
325  
326         connect(emu->get_osd(), SIGNAL(sig_movie_set_width(int)), hSaveMovieThread, SLOT(do_set_width(int)));
327         connect(emu->get_osd(), SIGNAL(sig_movie_set_height(int)), hSaveMovieThread, SLOT(do_set_height(int)));
328    
329         connect(emu->get_osd(), SIGNAL(sig_enqueue_audio(int16_t*, int)), hSaveMovieThread, SLOT(enqueue_audio(int16_t *, int)));
330         connect(emu->get_osd(), SIGNAL(sig_enqueue_video(int, int, int, QImage *)),
331                         hSaveMovieThread, SLOT(enqueue_video(int, int, int, QImage *)), Qt::DirectConnection);
332         connect(glv->extfunc, SIGNAL(sig_push_image_to_movie(int, int, int, QImage *)),
333                         hSaveMovieThread, SLOT(enqueue_video(int, int, int, QImage *)));
334         connect(this, SIGNAL(sig_quit_movie_thread()), hSaveMovieThread, SLOT(do_exit()));
335
336         objNameStr = QString("EmuMovieThread");
337         hSaveMovieThread->setObjectName(objNameStr);
338         hSaveMovieThread->start();
339         csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "MovieThread : Launch done.");
340
341         connect(action_SetupMovie, SIGNAL(triggered()), this, SLOT(rise_movie_dialog()));
342         connect(hRunEmu, SIGNAL(sig_change_osd(int, int, QString)), driveData, SLOT(updateMessage(int, int, QString)));
343         connect(hRunEmu, SIGNAL(sig_change_access_lamp(int, int, QString)), driveData, SLOT(updateLabel(int, int, QString)));
344         connect(hRunEmu, SIGNAL(sig_set_access_lamp(int, bool)), graphicsView, SLOT(do_display_osd_leds(int, bool)));
345
346         hRunEmu->start();
347         csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "EmuThread : Launch done.");
348         this->set_screen_aspect(using_flags->get_config_ptr()->window_stretch_type);
349         emit sig_movie_set_width(SCREEN_WIDTH);
350         emit sig_movie_set_height(SCREEN_HEIGHT);
351 }
352
353 void Ui_MainWindow::LaunchJoyThread(void)
354 {
355 #if defined(USE_JOYSTICK)
356         hRunJoy = new JoyThreadClass(emu, emu->get_osd(), using_flags, using_flags->get_config_ptr(), csp_logger);
357         connect(this, SIGNAL(quit_joy_thread()), hRunJoy, SLOT(doExit()));
358         hRunJoy->setObjectName("JoyThread");
359         hRunJoy->start();
360 #endif  
361 }
362
363 void Ui_MainWindow::StopJoyThread(void)
364 {
365 #if defined(USE_JOYSTICK)
366         emit quit_joy_thread();
367 #endif  
368 }
369
370 void Ui_MainWindow::delete_joy_thread(void)
371 {
372         //    delete hRunJoyThread;
373         //  delete hRunJoy;
374 }
375
376 void Ui_MainWindow::on_actionExit_triggered()
377 {
378         OnMainWindowClosed();
379 }
380
381 void Ui_MainWindow::OnWindowRedraw(void)
382 {
383         if(emu) {
384                 //emu->update_screen();
385         }
386 }
387
388 void Ui_MainWindow::OnWindowMove(void)
389 {
390         if(emu) {
391                 emu->suspend();
392         }
393 }
394
395
396 #ifdef USE_NOTIFY_POWER_OFF
397 bool Ui_MainWindow::GetPowerState(void)
398 {
399         if(close_notified == 0) return true;
400         return false;
401 }
402 #endif
403
404 #include <string>
405
406 void Ui_MainWindow::OnMainWindowClosed(void)
407 {
408         // notify power off
409 #ifdef USE_NOTIFY_POWER_OFF
410         if(emu) {
411                 if(!close_notified) {
412                         emu->lock_vm();
413                         emu->notify_power_off();
414                         emu->unlock_vm();
415                         close_notified = 1;
416                         return; 
417                 }
418         }
419 #endif
420         if(statusUpdateTimer != NULL) statusUpdateTimer->stop();
421 #if defined(USE_KEY_LOCKED) || defined(USE_LED_DEVICE)
422         if(ledUpdateTimer != NULL) ledUpdateTimer->stop();
423 #endif
424         emit quit_draw_thread();
425         emit quit_joy_thread();
426         emit quit_emu_thread();
427         emit sig_quit_movie_thread();
428         emit sig_quit_widgets();
429         
430         if(hSaveMovieThread != NULL) {
431                 hSaveMovieThread->wait();
432                 delete hSaveMovieThread;
433                 hSaveMovieThread = NULL;
434         }
435    
436         if(hDrawEmu != NULL) {
437                 hDrawEmu->wait();
438                 delete hDrawEmu;
439                 hDrawEmu = NULL;
440         }
441         if(hRunEmu != NULL) {
442                 OnCloseDebugger();
443                 hRunEmu->quit();
444                 hRunEmu->wait();
445                 delete hRunEmu;
446 #if 0
447                 save_config(create_local_path(_T("%s.ini"), _T(CONFIG_NAME)));
448 #else
449                 {
450                         char tmps[128];
451                         std::string localstr;
452                         snprintf(tmps, sizeof(tmps), _T("%s.ini"), _T(CONFIG_NAME));
453                         localstr = tmps;
454                         localstr = cpp_confdir + localstr;
455                         save_config(localstr.c_str());
456                 }
457 #endif
458         }
459 #if defined(USE_JOYSTICK)
460         if(hRunJoy != NULL) {
461                 hRunJoy->wait();
462                 delete hRunJoy;
463                 hRunJoy = NULL;
464         }
465 #endif
466         do_release_emu_resources();
467         hRunEmu = NULL;
468
469         // release window
470         if(now_fullscreen) {
471                 //ChangeDisplaySettings(NULL, 0);
472         }
473         now_fullscreen = false;
474         return;
475 }
476
477 extern "C" {
478
479 void LostFocus(QWidget *widget)
480 {
481         if(emu) {
482                 emu->key_lost_focus();
483         }
484 }
485  
486 }  // extern "C"
487
488 void Ui_MainWindow::do_release_emu_resources(void)
489 {
490         if(emu) {
491                 delete emu;
492                 emu = NULL;
493         }
494 }
495
496 extern void DLL_PREFIX_I get_long_full_path_name(_TCHAR* src, _TCHAR* dst);
497 extern _TCHAR* DLL_PREFIX_I get_parent_dir(_TCHAR* file);
498 extern void get_short_filename(_TCHAR *dst, _TCHAR *file, int maxlen);
499
500 #if defined(Q_OS_CYGWIN)        
501 #include <sys/stat.h>
502 #endif
503 static void my_util_mkdir(std::string n)
504 {
505 #if !defined(Q_OS_CYGWIN)       
506                 QDir dir = QDir::current();
507                 dir.mkdir( QString::fromStdString(n));
508 #else
509                 struct stat st;
510                 if(stat(n.c_str(), &st) != 0) {
511                         _mkdir(n.c_str()); // Not found
512                 }
513 #endif   
514 }       
515
516 static void setup_logs(void)
517 {
518         std::string delim;
519         char    *p;
520
521         my_procname = "emu";
522         my_procname = my_procname + CONFIG_NAME;
523 #if defined(Q_OS_WIN)
524         delim = "\\";
525 #else
526         delim = "/";
527 #endif
528 #if !defined(Q_OS_WIN)
529         p = SDL_getenv("HOME");
530         if(p == NULL) {
531                 p = SDL_getenv("PWD");
532                 if(p == NULL) {
533                         cpp_homedir = ".";
534                 } else {
535                         cpp_homedir = p;
536                 }
537                 std::string tmpstr;
538                 tmpstr = "Warning : Can't get HOME directory...Making conf on " +  cpp_homedir + delim;
539                 perror(tmpstr.c_str());
540         } else {
541                 cpp_homedir = p;
542         }
543 #else
544         cpp_homedir = ".";
545 #endif  
546         cpp_homedir = cpp_homedir + delim;
547
548 #if !defined(CSP_OS_WINDOWS)
549         cpp_confdir = cpp_homedir + ".config" + delim;
550         my_util_mkdir(cpp_confdir);
551 #else
552         cpp_confdir = cpp_homedir;
553 #endif
554
555         cpp_confdir = cpp_confdir + "CommonSourceCodeProject" + delim;
556         my_util_mkdir(cpp_confdir);
557         
558         cpp_confdir = cpp_confdir + my_procname + delim;
559         my_util_mkdir(cpp_confdir);
560    //AG_MkPath(cpp_confdir.c_str());
561    /* Gettext */
562 #ifndef RSSDIR
563 #if defined(_USE_AGAR) || defined(_USE_QT)
564         sRssDir = "/usr/local/share/";
565 #else
566         sRssDir = "." + delim;
567 #endif
568         sRssDir = sRssDir + "CommonSourceCodeProject" + delim + my_procname;
569 #else
570         sRssDir = RSSDIR;
571 #endif
572 }
573
574 #include <QString>
575 #include <QCommandLineParser>
576 CSP_Logger *csp_logger;
577 QStringList virtualMediaList; // {TYPE, POSITION}
578 QCommandLineOption *_opt_fds[8];
579 QCommandLineOption *_opt_hdds[8];
580 QCommandLineOption *_opt_cmts[2];
581 QCommandLineOption *_opt_lds[2];
582 QCommandLineOption *_opt_cds[2];
583 QCommandLineOption *_opt_binaries[8];
584 QCommandLineOption *_opt_bubbles[8];
585 QCommandLineOption *_opt_qds[8];
586 QCommandLineOption *_opt_carts[8];
587 QCommandLineOption *_opt_homedir;
588 QCommandLineOption *_opt_cfgfile;
589 QCommandLineOption *_opt_cfgdir;
590 QCommandLineOption *_opt_resdir;
591 QCommandLineOption *_opt_opengl;
592 QCommandLineOption *_opt_envver;
593 QCommandLineOption *_opt_dump_envver;
594 QCommandLineOption *_opt_dipsw_on;
595 QCommandLineOption *_opt_dipsw_off;
596 QProcessEnvironment _envvers;
597 bool _b_dump_envver;
598 std::string config_fullpath;
599
600 void SetFDOptions(QCommandLineParser *cmdparser)
601 {
602 #if defined(USE_FLOPPY_DISK)
603         for(int i = 0; i < USE_FLOPPY_DISK; i++) {
604                 QString sfdType1 = QString::fromUtf8("fd%1").arg(i);
605                 QString sfdType2 = QString::fromUtf8("vFd%1").arg(i);
606                 QString sfdType3 = QString::fromUtf8("vFloppyDisk%1").arg(i);
607                 QStringList _cl;
608                 _cl.append(sfdType1);
609                 _cl.append(sfdType2);
610                 _cl.append(sfdType3);
611                 _opt_fds[i] = new QCommandLineOption(_cl,QCoreApplication::translate("main", "Set virtual floppy disk %1.").arg(i) , "[D88_SLOT@]fullpath");
612                 cmdparser->addOption(*_opt_fds[i]);
613                 _cl.clear();
614         }
615 #endif
616 }
617
618 void SetHDDOptions(QCommandLineParser *cmdparser)
619 {
620 #if defined(USE_HARD_DISK)
621         for(int i = 0; i < USE_HARD_DISK; i++) {
622                 QString sfdType1 = QString::fromUtf8("hd%1").arg(i);
623                 QString sfdType2 = QString::fromUtf8("vHd%1").arg(i);
624                 QString sfdType3 = QString::fromUtf8("vHardDisk%1").arg(i);
625                 QString sfdType4 = QString::fromUtf8("vHardDrive%1").arg(i);
626                 QStringList _cl;
627                 _cl.append(sfdType1);
628                 _cl.append(sfdType2);
629                 _cl.append(sfdType3);
630                 _cl.append(sfdType4);
631                 _opt_hdds[i] = new QCommandLineOption(_cl,QCoreApplication::translate("main", "Set virtual hard drive %1.").arg(i) , "[D88_SLOT@]fullpath");
632                 cmdparser->addOption(*_opt_hdds[i]);
633                 _cl.clear();
634         }
635 #endif
636 }
637
638 void SetBinaryOptions(QCommandLineParser *cmdparser)
639 {
640 #if defined(USE_BINARY_FILE)
641         for(int i = 0; i < USE_BINARY_FILE; i++) {
642                 QString sfdType1 = QString::fromUtf8("bin%1").arg(i);
643                 QString sfdType2 = QString::fromUtf8("vBinary%1").arg(i);
644                 QStringList _cl;
645                 _cl.append(sfdType1);
646                 _cl.append(sfdType2);
647                 _opt_binaries[i] = new QCommandLineOption(_cl,QCoreApplication::translate("main", "Set virtual binary image %1.").arg(i) , "fullpath");
648                 cmdparser->addOption(*_opt_binaries[i]);
649                 _cl.clear();
650         }
651 #endif
652 }
653
654 void SetCartOptions(QCommandLineParser *cmdparser)
655 {
656 #if defined(USE_CART)
657         for(int i = 0; i < USE_CART; i++) {
658                 QString sfdType1 = QString::fromUtf8("cart%1").arg(i);
659                 QString sfdType2 = QString::fromUtf8("vCart%1").arg(i);
660                 QString sfdType3 = QString::fromUtf8("vCartridge%1").arg(i);
661                 QStringList _cl;
662                 _cl.append(sfdType1);
663                 _cl.append(sfdType2);
664                 _cl.append(sfdType3);
665                 _opt_carts[i] = new QCommandLineOption(_cl,QCoreApplication::translate("main", "Set virtual cartridge %1 (mostly ROM).").arg(i) , "fullpath");
666                 cmdparser->addOption(*_opt_carts[i]);
667                 _cl.clear();
668         }
669 #endif
670 }
671 void SetBubbleOptions(QCommandLineParser *cmdparser)
672 {
673 #if defined(USE_BUBBLE)
674         for(int i = 0; i < USE_BUBBLE; i++) {
675                 QString sfdType1 = QString::fromUtf8("bub%1").arg(i);
676                 QString sfdType2 = QString::fromUtf8("vBubble%1").arg(i);
677                 QStringList _cl;
678                 _cl.append(sfdType1);
679                 _cl.append(sfdType2);
680                 _opt_bubbles[i] = new QCommandLineOption(_cl,QCoreApplication::translate("main", "Set virtual bubble cartridge %1.").arg(i) , "[B88_SLOT@]fullpath");
681                 cmdparser->addOption(*_opt_bubbles[i]);
682         }
683 #endif
684 }
685
686 void SetLDOptions(QCommandLineParser *cmdparser)
687 {
688 #if defined(USE_LASER_DISC)
689         for(int i = 0; i < USE_LASER_DISC; i++) {
690                 QString sfdType1 = QString::fromUtf8("ld%1").arg(i);
691                 QString sfdType2 = QString::fromUtf8("vLaserDisc%1").arg(i);
692                 QStringList _cl;
693                 _cl.append(sfdType1);
694                 _cl.append(sfdType2);
695                 _opt_lds[i] = new QCommandLineOption(_cl, QCoreApplication::translate("main", "Set virtual laser disc %1 (mostly movie file).").arg(i) , "fullpath");
696                 cmdparser->addOption(*_opt_lds[i]);
697                 _cl.clear();
698         }
699 #endif
700 }
701 void SetCDOptions(QCommandLineParser *cmdparser)
702 {
703 #if defined(USE_COMPACT_DISC)
704         for(int i = 0; i < USE_COMPACT_DISC; i++) {
705                 QString sfdType1 = QString::fromUtf8("cd%1").arg(i);
706                 QString sfdType2 = QString::fromUtf8("vCompactDisc%1").arg(i);
707                 QStringList _cl;
708                 _cl.append(sfdType1);
709                 _cl.append(sfdType2);
710                 _opt_cds[i] = new QCommandLineOption(_cl,QCoreApplication::translate("main", "Set virtual compact disc %1.").arg(i) , "fullpath");
711                 cmdparser->addOption(*_opt_cds[i]);
712                 _cl.clear();
713         }
714 #endif
715 }
716
717 void SetCmtOptions(QCommandLineParser *cmdparser)
718 {
719 #if defined(USE_TAPE)
720         for(int i = 0; i < USE_TAPE; i++) {
721                 QString sfdType1 = QString::fromUtf8("cmt%1").arg(i);
722                 QString sfdType2 = QString::fromUtf8("tape%1").arg(i);
723                 QString sfdType3 = QString::fromUtf8("vCmt%1").arg(i);
724                 QString sfdType4 = QString::fromUtf8("vTape%1").arg(i);
725                 QStringList _cl;
726                 _cl.append(sfdType1);
727                 _cl.append(sfdType2);
728                 _cl.append(sfdType3);
729                 _cl.append(sfdType4);
730                 _opt_cmts[i] = new QCommandLineOption(_cl, QCoreApplication::translate("main", "Set virtual casette tape %1.").arg(i) , "fullpath");
731                 cmdparser->addOption(*_opt_cmts[i]);
732                 _cl.clear();
733         }
734 #endif
735 }
736
737 void SetQuickDiskOptions(QCommandLineParser *cmdparser)
738 {
739 #if defined(USE_QUICK_DISK)
740         for(int i = 0; i < USE_QUICK_DISK; i++) {
741                 QString sfdType1 = QString::fromUtf8("qd%1").arg(i);
742                 QString sfdType2 = QString::fromUtf8("vQuickDisk%1").arg(i);
743
744                 QStringList _cl;
745                 _cl.append(sfdType1);
746                 _cl.append(sfdType2);
747                 _opt_qds[i] = new QCommandLineOption(_cl, QCoreApplication::translate("main", "Set virtual quick disk %1.").arg(i) , "fullpath");
748                 cmdparser->addOption(*_opt_qds[i]);
749                 _cl.clear();
750         }
751 #endif
752 }
753
754
755 void SetProcCmdFD(QCommandLineParser *cmdparser, QStringList *_l)
756 {
757 #if defined(USE_FLOPPY_DISK)
758         for(int i = 0; i < USE_FLOPPY_DISK; i++) {
759                 if(_opt_fds[i] != NULL) {
760                         if(cmdparser->isSet(*_opt_fds[i])) {
761                                 QString sfdType = QString::fromUtf8("vFloppyDisk%1").arg(i);
762                                 QString medianame = cmdparser->value(*_opt_fds[i]);
763                                 _l->append(sfdType);
764                                 _l->append(medianame);
765                         }
766                 }
767         }
768 #endif
769 }
770
771 void SetProcCmdHDD(QCommandLineParser *cmdparser, QStringList *_l)
772 {
773 #if defined(USE_HARD_DISK)
774         for(int i = 0; i < USE_HARD_DISK; i++) {
775                 if(_opt_hdds[i] != NULL) {
776                         if(cmdparser->isSet(*_opt_hdds[i])) {
777                                 QString sfdType = QString::fromUtf8("vHardDisk%1").arg(i);
778                                 QString medianame = cmdparser->value(*_opt_hdds[i]);
779                                 _l->append(sfdType);
780                                 _l->append(medianame);
781                         }
782                 }
783         }
784 #endif
785 }
786
787 void SetProcCmdQuickDisk(QCommandLineParser *cmdparser, QStringList *_l)
788 {
789 #if defined(USE_QUICK_DISK)
790         for(int i = 0; i < USE_QUICK_DISK; i++) {
791                 if(_opt_qds[i] != NULL) {
792                         if(cmdparser->isSet(*_opt_qds[i])) {
793                                 QString sfdType = QString::fromUtf8("vQuickDisk%1").arg(i);
794                                 QString medianame = cmdparser->value(*_opt_qds[i]);
795                                 _l->append(sfdType);
796                                 _l->append(medianame);
797                         }
798                 }
799         }
800 #endif
801 }
802
803 void SetProcCmdCmt(QCommandLineParser *cmdparser, QStringList *_l)
804 {
805 #if defined(USE_TAPE)
806         for(int i = 0; i < USE_TAPE; i++) {
807                 if(_opt_cmts[i] != NULL) {
808                         if(cmdparser->isSet(*_opt_cmts[i])) {
809                                 QString sfdType = QString::fromUtf8("vCmt%1").arg(i);
810                                 QString medianame = cmdparser->value(*_opt_cmts[i]);
811                                 _l->append(sfdType);
812                                 _l->append(medianame);
813                         }
814                 }
815         }
816 #endif
817 }
818
819 void SetProcCmdBinary(QCommandLineParser *cmdparser, QStringList *_l)
820 {
821 #if defined(USE_BINARY_FILE)
822         for(int i = 0; i < USE_BINARY_FILE; i++) {
823                 if(_opt_binaries[i] != NULL) {
824                         if(cmdparser->isSet(*_opt_binaries[i])) {
825                                 QString sfdType = QString::fromUtf8("vBinary%1").arg(i);
826                                 QString medianame = cmdparser->value(*_opt_binaries[i]);
827                                 _l->append(sfdType);
828                                 _l->append(medianame);
829                         }
830                 }
831         }
832 #endif
833 }
834
835 void SetProcCmdBubble(QCommandLineParser *cmdparser, QStringList *_l)
836 {
837 #if defined(USE_BUBBLE)
838         for(int i = 0; i < USE_BUBBLE; i++) {
839                 if(_opt_bubbles[i] != NULL) {
840                         if(cmdparser->isSet(*_opt_bubbles[i])) {
841                                 QString sfdType = QString::fromUtf8("vBubble%1").arg(i);
842                                 QString medianame = cmdparser->value(*_opt_bubbles[i]);
843                                 _l->append(sfdType);
844                                 _l->append(medianame);
845                         }
846                 }
847         }
848 #endif
849 }
850
851 void SetProcCmdCart(QCommandLineParser *cmdparser, QStringList *_l)
852 {
853 #if defined(USE_CART)
854         for(int i = 0; i < USE_CART; i++) {
855                 if(_opt_carts[i] != NULL) {
856                         if(cmdparser->isSet(*_opt_carts[i])) {
857                                 QString sfdType = QString::fromUtf8("vCart%1").arg(i);
858                                 QString medianame = cmdparser->value(*_opt_carts[i]);
859                                 _l->append(sfdType);
860                                 _l->append(medianame);
861                         }
862                 }
863         }
864 #endif
865 }
866
867 void SetProcCmdLD(QCommandLineParser *cmdparser, QStringList *_l)
868 {
869 #if defined(USE_LASER_DISC)
870         for(int i = 0; i < USE_LASER_DISC; i++) {
871                 if(_opt_lds[i] != NULL) {
872                         if(cmdparser->isSet(*_opt_lds[i])) {
873                                 QString sfdType = QString::fromUtf8("vLD%1").arg(i);
874                                 QString medianame = cmdparser->value(*_opt_lds[i]);
875                                 _l->append(sfdType);
876                                 _l->append(medianame);
877                         }
878                 }
879         }
880 #endif
881 }
882
883 void SetProcCmdCD(QCommandLineParser *cmdparser, QStringList *_l)
884 {
885 #if defined(USE_COMPACT_DISC)
886         for(int i = 0; i < USE_COMPACT_DISC; i++) {
887                 if(_opt_cds[i] != NULL) {
888                         if(cmdparser->isSet(*_opt_cds[i])) {
889                                 QString sfdType = QString::fromUtf8("vCD%1").arg(i);
890                                 QString medianame = cmdparser->value(*_opt_cds[i]);
891                                 _l->append(sfdType);
892                                 _l->append(medianame);
893                         }
894                 }
895         }
896 #endif
897 }
898
899
900 void SetOptions(QCommandLineParser *cmdparser)
901 {
902         QString emudesc = QString::fromUtf8("Emulator for ");
903         emudesc = emudesc + QString::fromUtf8(DEVICE_NAME);
904     cmdparser->setApplicationDescription(emudesc);
905     cmdparser->addHelpOption();
906     //cmdparser->addVersionOption();
907         QStringList _cl;
908     _cl.append("d");
909     _cl.append("homedir");
910     _opt_homedir = new QCommandLineOption(_cl, QCoreApplication::translate("main", "Custom home directory."), "homedir");
911     _cl.clear();
912    
913     _cl.append("c");
914     _cl.append("cfgfile");
915     _opt_cfgfile = new QCommandLineOption(_cl, QCoreApplication::translate("main", "Custom config file (without path)."), "cfgfile");
916     _cl.clear();
917    
918     _opt_cfgdir = new QCommandLineOption("cfgdir", QCoreApplication::translate("main", "Custom config directory."), "cfgdir");
919
920     _cl.append("r");
921     _cl.append("res");
922     _opt_resdir = new QCommandLineOption(_cl, QCoreApplication::translate("main", "Custom resource directory (ROMs, WAVs, etc)."), "resdir");
923     _cl.clear();
924
925     _cl.append("on");
926     _cl.append("dipsw-on");
927     _opt_dipsw_on = new QCommandLineOption(_cl, QCoreApplication::translate("main", "Turn on <onbit> of dip switch."), "onbit");
928     _cl.clear();
929    
930     _cl.append("off");
931     _cl.append("dipsw-off");
932     _opt_dipsw_off = new QCommandLineOption(_cl, QCoreApplication::translate("main", "Turn off <offbit> of dip switch."), "offbit");
933     _cl.clear();
934         
935     _cl.append("g");
936     _cl.append("gl");
937     _cl.append("opengl");
938     _cl.append("render");
939     _opt_opengl = new QCommandLineOption(_cl, QCoreApplication::translate("main", "Force set using renderer type."), "{ GL | GL2 | GLES}");
940     _cl.clear();
941         
942     _cl.append("v");
943     _cl.append("env");
944     _cl.append("envver");
945     _opt_envver = new QCommandLineOption(_cl, QCoreApplication::translate("main", "Set / Delete environment variable."), "{NAME[=VAL] | -NAME}");
946     _cl.clear();
947
948     _cl.append("dump-env");
949     _cl.append("dump-envver");
950     _opt_dump_envver = new QCommandLineOption(_cl, QCoreApplication::translate("main", "Dump environment variables."), "");
951     _cl.clear();
952         
953         for(int i = 0; i < 8; i++) {
954                 _opt_fds[i] = NULL;
955                 _opt_hdds[i] = NULL;
956                 _opt_qds[i] = NULL;
957                 _opt_bubbles[i] = NULL;
958                 _opt_binaries[i] = NULL;
959                 _opt_carts[i] = NULL;
960         }
961         for(int i = 0; i < 2; i++) {
962                 _opt_cmts[i] = NULL;
963                 _opt_lds[i] = NULL;
964                 _opt_cds[i] = NULL;
965         }               
966                 
967     cmdparser->addOption(*_opt_opengl);
968     cmdparser->addOption(*_opt_homedir);
969     cmdparser->addOption(*_opt_cfgfile);
970     cmdparser->addOption(*_opt_cfgdir);
971     cmdparser->addOption(*_opt_resdir);
972     cmdparser->addOption(*_opt_dipsw_on);
973     cmdparser->addOption(*_opt_dipsw_off);
974
975         SetFDOptions(cmdparser);
976         SetHDDOptions(cmdparser);
977         //SetBinaryOptions(cmdparser); // Temporally disabled.
978         SetCmtOptions(cmdparser);
979         SetCartOptions(cmdparser);
980         SetBubbleOptions(cmdparser); // Temporally disabled.
981         SetQuickDiskOptions(cmdparser);
982         SetLDOptions(cmdparser); // Temporally disabled.
983         SetCDOptions(cmdparser);
984         
985     cmdparser->addOption(*_opt_envver);
986     cmdparser->addOption(*_opt_dump_envver);
987 }
988
989 void ProcessCmdLine(QCommandLineParser *cmdparser, QStringList *_l)
990 {
991         char homedir[PATH_MAX];
992         std::string delim;
993 #if defined(Q_OS_WIN)
994         delim = "\\";
995 #else
996         delim = "/";
997 #endif
998         
999         SetProcCmdFD(cmdparser, _l);
1000         SetProcCmdHDD(cmdparser, _l);
1001         SetProcCmdQuickDisk(cmdparser, _l);
1002         SetProcCmdCmt(cmdparser, _l);
1003         SetProcCmdCart(cmdparser, _l);
1004         SetProcCmdBinary(cmdparser, _l);
1005         SetProcCmdBubble(cmdparser, _l);
1006         SetProcCmdLD(cmdparser, _l);
1007         SetProcCmdCD(cmdparser, _l);
1008
1009         memset(homedir, 0x00, PATH_MAX);
1010         if(cmdparser->isSet(*_opt_homedir)) {
1011                 strncpy(homedir, cmdparser->value(*_opt_homedir).toLocal8Bit().constData(), PATH_MAX - 1);
1012                 cpp_homedir = homedir;
1013                 size_t _len = cpp_homedir.length() - 1;
1014                 size_t _pos = cpp_homedir.rfind(delim);
1015                 if((_pos < _len) ||
1016                    (_pos == std::string::npos)) {
1017                         cpp_homedir.append(delim);
1018                 }
1019         } else {
1020                 cpp_homedir.copy(homedir, PATH_MAX - 1, 0);
1021         }
1022
1023         if(cmdparser->isSet(*_opt_cfgdir)) {
1024                 char tmps[PATH_MAX];
1025                 std::string tmpstr;
1026                 memset(tmps, 0x00, PATH_MAX);
1027                 strncpy(tmps, cmdparser->value(*_opt_cfgdir).toLocal8Bit().constData(), PATH_MAX - 1);
1028                 cpp_confdir = tmps;
1029                 size_t _len = cpp_confdir.length() - 1;
1030                 size_t _pos = cpp_confdir.rfind(delim);
1031                 if((_pos < _len) ||
1032                    (_pos == std::string::npos)) {
1033                         cpp_confdir.append(delim);
1034                 }
1035         }
1036         
1037         {
1038                 char tmps[128];
1039                 std::string localstr;
1040                 memset(tmps, 0x00, 128);
1041                 if(cmdparser->isSet(*_opt_cfgfile)) {
1042                         strncpy(tmps, cmdparser->value(*_opt_cfgfile).toLocal8Bit().constData(), 127);
1043                 }
1044                 if(strlen(tmps) <= 0){
1045                         snprintf(tmps, sizeof(tmps), _T("%s.ini"), _T(CONFIG_NAME));
1046                 }
1047                 localstr = tmps;
1048                 localstr = cpp_confdir + localstr;
1049                 load_config(localstr.c_str());
1050                 config_fullpath = localstr;
1051         }
1052         if(cmdparser->isSet(*_opt_resdir)) {
1053                 char tmps[PATH_MAX];
1054                 std::string tmpstr;
1055                 memset(tmps, 0x00, PATH_MAX);
1056                 strncpy(tmps, cmdparser->value(*_opt_resdir).toLocal8Bit().constData(), PATH_MAX - 1);
1057                 sRssDir = tmps;
1058                 size_t _len = sRssDir.length() - 1;
1059                 size_t _pos = sRssDir.rfind(delim);
1060                 if((_pos < _len) ||
1061                    (_pos == std::string::npos)) {
1062                         sRssDir.append(delim);
1063                 }
1064         }
1065         if(cmdparser->isSet(*_opt_opengl)) {
1066                 char tmps[128] = {0};
1067                 strncpy(tmps, cmdparser->value(*_opt_opengl).toLocal8Bit().constData(), 128 - 1);
1068                 if(strlen(tmps) > 0) {
1069                         QString render = QString::fromLocal8Bit(tmps).toUpper();
1070                         if((render == QString::fromUtf8("GL2")) ||
1071                            (render == QString::fromUtf8("GLV2"))) {
1072                                 config.render_platform = CONFIG_RENDER_PLATFORM_OPENGL_MAIN;
1073                                 config.render_major_version = 2;
1074                                 config.render_minor_version = 0;
1075                                 GuiMain->setAttribute(Qt::AA_UseDesktopOpenGL, true);
1076                                 GuiMain->setAttribute(Qt::AA_UseOpenGLES, false);
1077                         } else if((render == QString::fromUtf8("GL3")) ||
1078                                           (render == QString::fromUtf8("GLV3")) ||
1079                                           (render == QString::fromUtf8("OPENGLV3")) ||
1080                                           (render == QString::fromUtf8("OPENGL")) ||
1081                                           (render == QString::fromUtf8("GL"))) {
1082                                 config.render_platform = CONFIG_RENDER_PLATFORM_OPENGL_MAIN;
1083                                 config.render_major_version = 3;
1084                                 config.render_minor_version = 0;
1085                                 GuiMain->setAttribute(Qt::AA_UseDesktopOpenGL, true);
1086                                 GuiMain->setAttribute(Qt::AA_UseOpenGLES, false);
1087                         } else if((render == QString::fromUtf8("GLES2")) ||
1088                                          (render == QString::fromUtf8("GLESV2")) ||
1089                                          (render == QString::fromUtf8("GLES3")) ||
1090                                          (render == QString::fromUtf8("GLESV3")) ||
1091                                          (render == QString::fromUtf8("GLES"))) {
1092                                 config.render_platform = CONFIG_RENDER_PLATFORM_OPENGL_ES;
1093                                 config.render_major_version = 2;
1094                                 config.render_minor_version = 1;
1095                                 GuiMain->setAttribute(Qt::AA_UseDesktopOpenGL, false);
1096                                 GuiMain->setAttribute(Qt::AA_UseOpenGLES, true);
1097                         }
1098                 }
1099         }
1100         if(cmdparser->isSet(*_opt_envver)) {
1101                 QStringList nList = cmdparser->values(*_opt_envver);
1102                 QString tv;
1103                 //QProcessEnvironment ev = QProcessEnvironment::systemEnvironment();
1104                 QProcessEnvironment ev = _envvers;
1105                 if(nList.size() > 0) {
1106                         for(int i = 0; i < nList.size(); i++) {
1107                                 tv = nList.at(i);
1108                                 if(tv.indexOf(QString::fromUtf8("-")) == 0) {
1109                                         // Delete var
1110                                         int n1 = tv.indexOf(QString::fromUtf8("="));
1111                                         if(n1 > 0) {
1112                                                 tv = tv.left(n1).right(n1 - 1);
1113                                         } else {
1114                                                 tv = tv.right(tv.length() - 1);
1115                                         }
1116                                         printf("DEBUG: DEL ENV:%s\n", tv.toLocal8Bit().constData());
1117                                         ev.remove(tv);
1118                                 } else if(tv.indexOf(QString::fromUtf8("=")) > 0) {
1119                                         // Delete var
1120                                         int n1 = tv.indexOf(QString::fromUtf8("="));
1121                                         QString skey;
1122                                         QString sval;
1123                                         skey = tv.left(n1);
1124                                         if((tv.length() - n1) < 1) {
1125                                                 sval = QString::fromUtf8("");
1126                                         } else {
1127                                                 sval = tv.right(tv.length() - n1 - 1);
1128                                         }
1129                                         printf("DEBUG: SET ENV:%s to %s\n", skey.toLocal8Bit().constData(), sval.toLocal8Bit().constData());
1130                                         if(skey.length() > 0) ev.insert(skey, sval);
1131                                 } else if(tv.indexOf(QString::fromUtf8("=")) < 0) {
1132                                         printf("DEBUG: SET ENV:%s to (NULL)\n", tv.toLocal8Bit().constData());
1133                                         if(tv.length() > 0) ev.insert(tv, QString::fromUtf8(""));
1134                                 }
1135                         }
1136                         _envvers.swap(ev);
1137                 }
1138         }
1139         _b_dump_envver = false;
1140         if(cmdparser->isSet(*_opt_dump_envver)) {
1141                 _b_dump_envver = true;
1142         }
1143         uint32_t dipsw_onbits = 0x0000000;
1144         uint32_t dipsw_offmask = 0xffffffff;
1145         if(cmdparser->isSet(*_opt_dipsw_off)) {
1146                 QStringList bitList = cmdparser->values(*_opt_dipsw_off);
1147                 QString tv;
1148                 bool num_ok;
1149                 for(int i = 0; i < bitList.size(); i++) {
1150                         tv = bitList.at(i);
1151                         int _bit = tv.toInt(&num_ok);
1152                         if(num_ok) {
1153                                 if((_bit >= 0) && (_bit < 32)) {
1154                                         dipsw_offmask &= (uint32_t)(~(1 << _bit));
1155                                 }
1156                         }
1157                 }
1158         }
1159         if(cmdparser->isSet(*_opt_dipsw_on)) {
1160                 QStringList bitList = cmdparser->values(*_opt_dipsw_on);
1161                 QString tv;
1162                 bool num_ok;
1163                 for(int i = 0; i < bitList.size(); i++) {
1164                         tv = bitList.at(i);
1165                         int _bit = tv.toInt(&num_ok);
1166                         if(num_ok) {
1167                                 if((_bit >= 0) && (_bit < 32)) {
1168                                         dipsw_onbits |= (uint32_t)(1 << _bit);
1169                                 }
1170                         }
1171                 }
1172         }
1173         config.dipswitch &= dipsw_offmask;
1174         config.dipswitch |= dipsw_onbits;
1175
1176 }
1177
1178 void OpeningMessage(std::string archstr)
1179 {
1180         csp_logger->set_emu_vm_name(DEVICE_NAME); // Write to syslog, console
1181         csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Start Common Source Project '%s'", my_procname.c_str());
1182         csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "(C) Toshiya Takeda / Qt Version K.Ohta");
1183         csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Architecture: %s", archstr.c_str());
1184         csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Use -h or --help for help.");
1185         
1186         //csp_logger->debug_log(AGAR_LOG_INFO, " -? is print help(s).");
1187         csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Home = %s, Resource directory = %s",
1188                                                   cpp_homedir.c_str(),
1189                                                   sRssDir.c_str()); // Debug
1190         
1191         csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Config dir = %s, config_file = %s",
1192                                                   cpp_confdir.c_str(),
1193                                                   config_fullpath.c_str()); // Debug
1194         
1195         csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "DIPSW VALUE IS 0x%08x", config.dipswitch);
1196         if(virtualMediaList.size() >= 2) {
1197                 for(int i = 0; i < virtualMediaList.size(); i += 2) {
1198                         csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Virtual media %d, type %s, name %s",
1199                                                                   i / 2,
1200                                                                   virtualMediaList.at(i).toLocal8Bit().constData(),
1201                                                                   virtualMediaList.at(i + 1).toLocal8Bit().constData());
1202                 }
1203         }
1204 }
1205
1206 void SetupSDL(void)
1207 {
1208         QStringList _el = _envvers.toStringList();
1209         if(_el.size() > 0) {
1210                 for(int i = 0; i < _el.size(); i++) {
1211                         QString _s = _el.at(i);
1212                         if(_s.startsWith("SDL_")) {
1213                                 QString skey, svar;
1214                                 int _nl;
1215                                 _nl = _s.indexOf('=');
1216                                 if(_nl >= 0) {
1217                                         skey = _s.left(_nl);
1218                                         svar = _s.right(_s.length() - _nl);
1219                                 } else {
1220                                         skey = _s;
1221                                         svar = QString::fromUtf8("");
1222                                 }
1223                                 SDL_setenv(skey.toLocal8Bit().constData(), svar.toLocal8Bit().constData(), 1);
1224                                 csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Note: SDL ENVIROMENT : %s to %s.",
1225                                                                           skey.toLocal8Bit().constData(),
1226                                                                           svar.toLocal8Bit().constData());
1227                         }
1228                 }
1229         }
1230 #if defined(USE_SDL2)
1231         SDL_Init(SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER);
1232 #else
1233         SDL_Init(SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_VIDEO);
1234 #endif
1235         csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Audio and JOYSTICK subsystem was initialised.");
1236 }
1237
1238 void SetupLogger(std::string emustr, int _size)
1239 {
1240
1241         csp_logger = new CSP_Logger(config.log_to_syslog, config.log_to_console, emustr.c_str()); // Write to syslog, console
1242         csp_logger->set_log_stdout(CSP_LOG_DEBUG, true);
1243         csp_logger->set_log_stdout(CSP_LOG_INFO, true);
1244         csp_logger->set_log_stdout(CSP_LOG_WARN, true);
1245         
1246         csp_logger->set_state_log(0, config.state_log_to_recording);
1247         csp_logger->set_state_log(1, config.state_log_to_syslog);
1248         csp_logger->set_state_log(2, config.state_log_to_console);
1249         
1250         for(int ii = 0; ii < _size; ii++) {
1251                 for(int jj = 0; jj < 8; jj++) {
1252                         csp_logger->set_device_node_log(ii, 1, jj, config.dev_log_to_syslog[ii][jj]);
1253                         csp_logger->set_device_node_log(ii, 2, jj, config.dev_log_to_console[ii][jj]);
1254                         csp_logger->set_device_node_log(ii, 0, jj, config.dev_log_recording[ii][jj]);
1255                 }
1256         }
1257 }
1258
1259 int MainLoop(int argc, char *argv[])
1260 {
1261
1262         std::string archstr;
1263         std::string emustr("emu");
1264         std::string cfgstr(CONFIG_NAME);
1265         std::string delim;
1266         QString emudesc;
1267
1268         setup_logs();
1269 #if defined(Q_OS_WIN)
1270         delim = "\\";
1271 #else
1272         delim = "/";
1273 #endif
1274         
1275         GuiMain = new QApplication(argc, argv);
1276         GuiMain->setObjectName(QString::fromUtf8("Gui_Main"));
1277         _envvers = QProcessEnvironment::systemEnvironment();
1278         
1279     QCommandLineParser cmdparser;
1280
1281         virtualMediaList.clear();
1282         SetOptions(&cmdparser);
1283
1284         cmdparser.process(QCoreApplication::arguments());
1285
1286         ProcessCmdLine(&cmdparser, &virtualMediaList);
1287
1288         emustr = emustr + cfgstr;
1289
1290         SetupLogger(emustr, CSP_LOG_TYPE_VM_DEVICE_END - CSP_LOG_TYPE_VM_DEVICE_0 + 1);
1291
1292         
1293         archstr = "Generic";
1294 #if defined(__x86_64__)
1295         archstr = "amd64";
1296 #endif
1297 #if defined(__i386__)
1298         archstr = "ia32";
1299 #endif
1300         OpeningMessage(archstr);
1301         SetupSDL();
1302         /*
1303          * Into Qt's Loop.
1304          */
1305         USING_FLAGS_EXT *using_flags = new USING_FLAGS_EXT(&config);
1306         // initialize emulation core
1307
1308         //SetupTranslators();
1309         QTranslator local_translator;
1310         QLocale s_locale;
1311         if(local_translator.load(s_locale, QLatin1String("csp_qt_machine"), QLatin1String("_"), QLatin1String(":/"))) {
1312                 GuiMain->installTranslator(&local_translator);
1313         }
1314         QTranslator s_translator;
1315         if(s_translator.load(s_locale, QLatin1String("csp_qt_gui"), QLatin1String("_"), QLatin1String(":/"))) {
1316                 GuiMain->installTranslator(&s_translator);
1317         }
1318         QTranslator common_translator;
1319         if(common_translator.load(s_locale, QLatin1String("csp_qt_common"), QLatin1String("_"), QLatin1String(":/"))) {
1320                 GuiMain->installTranslator(&common_translator);
1321         }
1322         QTranslator debugger_translator;
1323         if(debugger_translator.load(s_locale, QLatin1String("csp_qt_debugger"), QLatin1String("_"), QLatin1String(":/"))) {
1324                 GuiMain->installTranslator(&debugger_translator);
1325         }
1326         //QProcessEnvironment::systemEnvironment() = _envvers;
1327         if(_b_dump_envver) {
1328                 //QProcessEnvironment ev = QProcessEnvironment::systemEnvironment();
1329                 QProcessEnvironment ev = _envvers;
1330                 QStringList el = _envvers.toStringList();
1331                 if(el.size() > 0) {
1332                         csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Environment Variables:");
1333                         for(int i = 0; i < el.size(); i++) {
1334                                 csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "#%d : %s", i, el.at(i).toLocal8Bit().constData());
1335                         }
1336                 }
1337         }
1338         
1339         rMainWindow = new META_MainWindow(using_flags, csp_logger);
1340         rMainWindow->connect(rMainWindow, SIGNAL(sig_quit_all(void)), rMainWindow, SLOT(deleteLater(void)));
1341         rMainWindow->setCoreApplication(GuiMain);
1342         rMainWindow->getWindow()->show();
1343                         
1344         // main loop
1345         rMainWindow->LaunchEmuThread();
1346 #if defined(USE_JOYSTICK)
1347         rMainWindow->LaunchJoyThread();
1348 #endif  
1349         GLDrawClass *pgl = rMainWindow->getGraphicsView();
1350         pgl->set_emu_launched();
1351         pgl->setFixedSize(pgl->width(), pgl->height());
1352         rMainWindow->retranselateUi_Depended_OSD();
1353         QObject::connect(emu->get_osd(), SIGNAL(sig_update_device_node_name(int, const _TCHAR *)),
1354                                          rMainWindow, SLOT(do_update_device_node_name(int, const _TCHAR *)));
1355         for(int i = 0; i < (CSP_LOG_TYPE_VM_DEVICE_END - CSP_LOG_TYPE_VM_DEVICE_0 + 1); i++) {
1356                 rMainWindow->do_update_device_node_name(i, using_flags->get_vm_node_name(i));
1357         }
1358         csp_logger->set_osd(emu->get_osd());
1359         csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "InitInstance() OK.");
1360         
1361         QObject::connect(GuiMain, SIGNAL(lastWindowClosed()),
1362                                          rMainWindow, SLOT(on_actionExit_triggered()));
1363
1364         GuiMain->exec();
1365         return 0;
1366 }
1367
1368 void Ui_MainWindow::do_update_inner_fd(int drv, QStringList base, class Action_Control **action_select_media_list,
1369                                        QStringList lst, int num, bool use_d88_menus)
1370 {
1371 #if defined(USE_FLOPPY_DISK)
1372         if(use_d88_menus) {
1373                 for(int ii = 0; ii < using_flags->get_max_d88_banks(); ii++) {
1374                         if(ii < emu->d88_file[drv].bank_num) {
1375                                 base << lst.value(ii);
1376                                 action_select_media_list[ii]->setText(lst.value(ii));
1377                                 action_select_media_list[ii]->setVisible(true);
1378                                 if(ii == num) action_select_media_list[ii]->setChecked(true);
1379                         } else {
1380                                 if(action_select_media_list[ii] != NULL) {
1381                                         action_select_media_list[ii]->setText(QString::fromUtf8(""));
1382                                         action_select_media_list[ii]->setVisible(false);
1383                                 }
1384                         }
1385                 }
1386         }
1387 #endif  
1388 }
1389
1390 void Ui_MainWindow::do_update_inner_bubble(int drv, QStringList base, class Action_Control **action_select_media_list,
1391                                        QStringList lst, int num, bool use_d88_menus)
1392 {
1393 #if defined(USE_BUBBLE) 
1394         if(use_d88_menus) {
1395                 for(int ii = 0; ii < using_flags->get_max_b77_banks(); ii++) {
1396                         if(ii < emu->b77_file[drv].bank_num) {
1397                                 base << lst.value(ii);
1398                                 action_select_media_list[ii]->setText(lst.value(ii));
1399                                 action_select_media_list[ii]->setVisible(true);
1400                                 if(ii == num) action_select_media_list[ii]->setChecked(true);
1401                         } else {
1402                                 if(action_select_media_list[ii] != NULL) {
1403                                         action_select_media_list[ii]->setText(QString::fromUtf8(""));
1404                                         action_select_media_list[ii]->setVisible(false);
1405                                 }
1406                         }
1407                 }
1408         }
1409 #endif  
1410 }
1411
1412 int Ui_MainWindow::GetBubbleBankNum(int drv)
1413 {
1414 #if MAX_BUBBLE
1415         if((emu != NULL) && (drv >= 0) && (drv < MAX_BUBBLE)) {
1416                 return emu->b77_file[drv].bank_num;
1417         }
1418 #endif
1419         return 0;
1420 }
1421
1422 int Ui_MainWindow::GetBubbleCurrentBankNum(int drv)
1423 {
1424 #if MAX_BUBBLE
1425         if((emu != NULL) && (drv >= 0) && (drv < MAX_BUBBLE)) {
1426                 return emu->b77_file[drv].cur_bank;
1427         }
1428 #endif
1429         return 0;
1430 }
1431
1432 bool Ui_MainWindow::GetBubbleCasetteIsProtected(int drv)
1433 {
1434 #if MAX_BUBBLE
1435         if(emu != NULL) {
1436                 if((drv >= 0) && (drv < MAX_BUBBLE)) {
1437                         return emu->is_bubble_casette_protected(drv);
1438                 }
1439         }
1440 #endif
1441         return false;
1442 }
1443
1444 QString Ui_MainWindow::GetBubbleB77FileName(int drv)
1445 {
1446         QString ans = QString::fromUtf8("");
1447 #if MAX_BUBBLE
1448         if(emu != NULL) {
1449                 if((drv < MAX_BUBBLE) && (drv >= 0)) {
1450                         ans = QString::fromLocal8Bit(emu->b77_file[drv].path);
1451                 }
1452         }
1453 #endif
1454         return ans;
1455 }
1456
1457 QString Ui_MainWindow::GetBubbleB77BubbleName(int drv, int num)
1458 {
1459         QString ans = QString::fromUtf8("");
1460 #if MAX_BUBBLE
1461         if(emu != NULL) {
1462                 if((drv < MAX_BUBBLE) && (drv >= 0)) {
1463                         if((num >= 0) && (num < MAX_B77_BANKS)) {
1464                                 ans = QString::fromLocal8Bit(emu->b77_file[drv].bubble_name[num]);
1465                         }
1466                 }
1467         }
1468 #endif
1469         return ans;
1470 }
1471
1472 #ifdef USE_DEBUGGER
1473 #include <../debugger/qt_debugger.h>
1474
1475 void Ui_MainWindow::OnOpenDebugger(int no)
1476 {
1477         if((no < 0) || (no > 7)) return;
1478         //emu->open_debugger(no);
1479         VM *vm = emu->get_vm();
1480
1481         if((emu->now_debugging ) || (emu->hDebugger != NULL)) /* OnCloseDebugger(); */ return;
1482         
1483         if(!(emu->now_debugging && emu->debugger_thread_param.cpu_index == no)) {
1484                 //emu->close_debugger();
1485                 if(vm->get_cpu(no) != NULL && vm->get_cpu(no)->get_debugger() != NULL) {
1486                         QString windowName = QString::fromUtf8(vm->get_cpu(no)->get_device_name());
1487                         windowName = QString::fromUtf8("Debugger ") + windowName;
1488                         emu->hDebugger = new CSP_Debugger(this);
1489                         QString objNameStr = QString("EmuDebugThread");
1490                         emu->hDebugger->setObjectName(objNameStr);
1491                         emu->hDebugger->debugger_thread_param.osd = emu->get_osd();
1492                         emu->hDebugger->debugger_thread_param.vm = vm;
1493                         emu->hDebugger->debugger_thread_param.cpu_index = no;
1494                         emu->stop_record_sound();
1495                         emu->stop_record_video();
1496                         //emu->now_debugging = true;
1497                         connect(this, SIGNAL(quit_debugger_thread()), emu->hDebugger, SLOT(doExit()));
1498                         connect(this, SIGNAL(destroyed()), emu->hDebugger, SLOT(do_destroy_thread()));
1499                         //connect(this, SIGNAL(quit_debugger_thread()), emu->hDebugger, SLOT(close()));
1500                         connect(emu->hDebugger, SIGNAL(sig_finished()), this, SLOT(OnCloseDebugger()));
1501                         connect(emu->hDebugger, SIGNAL(sig_put_string(QString)), emu->hDebugger, SLOT(put_string(QString)));
1502                         emu->hDebugger->show();
1503                         emu->hDebugger->run();
1504                         emu->hDebugger->setWindowTitle(windowName);
1505                 }
1506         }
1507 }
1508
1509 void Ui_MainWindow::OnCloseDebugger(void )
1510 {
1511
1512 //      emu->close_debugger();
1513         if(emu->now_debugging) {
1514                 if(emu->hDebugger->debugger_thread_param.running) {
1515                         emit quit_debugger_thread();
1516                         //emu->hDebugger->wait();
1517                 }
1518         }
1519         if(emu != NULL) {
1520                 if(emu->hDebugger != NULL) {
1521                         delete emu->hDebugger;
1522                         emu->hDebugger = NULL;
1523                 }
1524                 emu->now_debugging = false;
1525         }
1526 }
1527 #endif
1528