OSDN Git Service

[VM][FM7] Add Japanese communication board (日本語通信カード) .
[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 <QString>
14 #include <QTextCodec>
15 #include <QImage>
16 #include <QImageReader>
17 #include <QDateTime>
18 #include <QDir>
19
20 #include "common.h"
21 #include "fileio.h"
22 #include "emu.h"
23 #include "menuclasses.h"
24 #include "mainwidget.h"
25 #include "commonclasses.h"
26 #include "qt_main.h"
27 #include "emu_thread.h"
28 #include "joy_thread.h"
29 #include "draw_thread.h"
30
31 #include "qt_gldraw.h"
32 #include "qt_glutil_gl2_0.h"
33 #include "csp_logger.h"
34 #include "dock_disks.h"
35 #include "menu_disk.h"
36 #include "menu_bubble.h"
37 #include "menu_flags_ext.h"
38 #include "dialog_movie.h"
39 #include "../avio/movie_saver.h"
40 // emulation core
41
42 EMU* emu;
43 QApplication *GuiMain = NULL;
44
45 // Start to define MainWindow.
46 class META_MainWindow *rMainWindow;
47
48
49 // buttons
50 #ifdef MAX_BUTTONS
51 #define MAX_FONT_SIZE 32
52 #endif
53
54 // menu
55 extern std::string cpp_homedir;
56 extern DLL_PREFIX_I std::string cpp_confdir;
57 extern std::string my_procname;
58 std::string sRssDir;
59 bool now_menuloop = false;
60 static int close_notified = 0;
61 // timing control
62
63 // screen
64 unsigned int desktop_width;
65 unsigned int desktop_height;
66 //int desktop_bpp;
67 int prev_window_mode = 0;
68 bool now_fullscreen = false;
69
70 int window_mode_count;
71
72 void Ui_MainWindow::do_set_mouse_enable(bool flag)
73 {
74 #ifdef USE_MOUSE
75         if(emu == NULL) return;
76         emu->lock_vm();
77         if(flag) {
78                 graphicsView->grabMouse();
79                 emu->enable_mouse();
80         } else {
81                 graphicsView->releaseMouse();
82                 emu->disable_mouse();
83         }
84         emu->unlock_vm();
85 #endif  
86 }
87
88 void Ui_MainWindow::do_toggle_mouse(void)
89 {
90 #ifdef USE_MOUSE
91         if(emu == NULL) return;
92         emu->lock_vm();
93         bool flag = emu->is_mouse_enabled();
94         if(!flag) {
95                 graphicsView->grabMouse();
96                 emu->enable_mouse();
97         } else {
98                 graphicsView->releaseMouse();
99                 emu->disable_mouse();
100         }
101         emu->unlock_vm();
102 #endif  
103 }
104
105 void Ui_MainWindow::rise_movie_dialog(void)
106 {
107         CSP_DialogMovie *dlg = new CSP_DialogMovie(hSaveMovieThread, using_flags);
108         dlg->setWindowTitle(QApplication::translate("CSP_DialogMovie", "Configure movie encodings", 0));
109         dlg->show();
110 }
111 void Ui_MainWindow::LaunchEmuThread(void)
112 {
113         QString objNameStr;
114         GLDrawClass *glv = this->getGraphicsView();
115
116         int drvs;
117         
118         hRunEmu = new EmuThreadClass(rMainWindow, using_flags);
119         connect(hRunEmu, SIGNAL(message_changed(QString)), this, SLOT(message_status_bar(QString)));
120         connect(hRunEmu, SIGNAL(sig_is_enable_mouse(bool)), glv, SLOT(do_set_mouse_enabled(bool)));
121         connect(glv, SIGNAL(sig_key_down(uint32_t, uint32_t, bool)), hRunEmu, SLOT(do_key_down(uint32_t, uint32_t, bool)));
122         connect(glv, SIGNAL(sig_key_up(uint32_t, uint32_t)),hRunEmu, SLOT(do_key_up(uint32_t, uint32_t)));
123         connect(this, SIGNAL(sig_quit_widgets()), glv, SLOT(do_stop_run_vm()));
124
125         
126         //connect(hRunEmu, SIGNAL(sig_finished()), this, SLOT(delete_emu_thread()));
127         connect(this, SIGNAL(sig_vm_reset()), hRunEmu, SLOT(do_reset()));
128         connect(this, SIGNAL(sig_vm_specialreset()), hRunEmu, SLOT(do_special_reset()));
129
130         connect(this, SIGNAL(sig_emu_update_config()), hRunEmu, SLOT(do_update_config()));
131         connect(this, SIGNAL(sig_emu_update_volume_level(int, int)), hRunEmu, SLOT(do_update_volume_level(int, int)));
132         connect(this, SIGNAL(sig_emu_update_volume_balance(int, int)), hRunEmu, SLOT(do_update_volume_balance(int, int)));
133         connect(this, SIGNAL(sig_emu_start_rec_sound()), hRunEmu, SLOT(do_start_record_sound()));
134         connect(this, SIGNAL(sig_emu_stop_rec_sound()), hRunEmu, SLOT(do_stop_record_sound()));
135         connect(this, SIGNAL(sig_emu_set_display_size(int, int, int, int)), hRunEmu, SLOT(do_set_display_size(int, int, int, int)));
136         
137         if(using_flags->is_use_state()) {
138                 for(int i = 0; i < 10; i++) {
139                         connect(actionLoad_State[i], SIGNAL(sig_load_state(QString)), hRunEmu, SLOT(do_load_state(QString))); // OK?
140                         connect(actionSave_State[i], SIGNAL(sig_save_state(QString)), hRunEmu, SLOT(do_save_state(QString))); // OK?
141                 }
142         }
143 #if defined(USE_FD1) || defined(USE_FD2) || defined(USE_FD3) || defined(USE_FD4) || \
144     defined(USE_FD5) || defined(USE_FD6) || defined(USE_FD7) || defined(USE_FD8)
145         connect(this, SIGNAL(sig_write_protect_disk(int, bool)), hRunEmu, SLOT(do_write_protect_disk(int, bool)));
146         connect(this, SIGNAL(sig_open_disk(int, QString, int)), hRunEmu, SLOT(do_open_disk(int, QString, int)));
147         connect(this, SIGNAL(sig_close_disk(int)), hRunEmu, SLOT(do_close_disk(int)));
148         connect(hRunEmu, SIGNAL(sig_update_recent_disk(int)), this, SLOT(do_update_recent_disk(int)));
149         //connect(hRunEmu, SIGNAL(sig_change_osd_fd(int, QString)), this, SLOT(do_change_osd_fd(int, QString)));
150         drvs = 0;
151 # if defined(USE_FD1)
152         drvs = 1;
153 # endif
154 # if defined(USE_FD2)
155         drvs = 2;
156 # endif
157 # if defined(USE_FD3)
158         drvs = 3;
159 # endif
160 # if defined(USE_FD4)
161         drvs = 4;
162 # endif
163 # if defined(USE_FD5)
164         drvs = 5;
165 # endif
166 # if defined(USE_FD6)
167         drvs = 6;
168 # endif
169 # if defined(USE_FD7)
170         drvs = 7;
171 # endif
172 # if defined(USE_FD8)
173         drvs = 8;
174 # endif
175         for(int ii = 0; ii < drvs; ii++) {
176                 menu_fds[ii]->setEmu(emu);
177                 connect(menu_fds[ii], SIGNAL(sig_update_inner_fd(int ,QStringList , class Action_Control **, QStringList , int, bool)),
178                                 this, SLOT(do_update_inner_fd(int ,QStringList , class Action_Control **, QStringList , int, bool)));
179         }
180 #endif
181 #if defined(USE_TAPE1)
182         connect(this, SIGNAL(sig_play_tape(int, QString)), hRunEmu, SLOT(do_play_tape(int, QString)));
183         connect(this, SIGNAL(sig_rec_tape(int, QString)),  hRunEmu, SLOT(do_rec_tape(int, QString)));
184         connect(this, SIGNAL(sig_close_tape(int)),   hRunEmu, SLOT(do_close_tape(int)));
185         //connect(hRunEmu, SIGNAL(sig_change_osd_cmt(QString)), this, SLOT(do_change_osd_cmt(QString)));
186 # if defined(USE_TAPE_BUTTON)
187         connect(this, SIGNAL(sig_cmt_push_play(int)), hRunEmu, SLOT(do_cmt_push_play(int)));
188         connect(this, SIGNAL(sig_cmt_push_stop(int)), hRunEmu, SLOT(do_cmt_push_stop(int)));
189         connect(this, SIGNAL(sig_cmt_push_fast_forward(int)), hRunEmu, SLOT(do_cmt_push_fast_forward(int)));
190         connect(this, SIGNAL(sig_cmt_push_fast_rewind(int)),  hRunEmu, SLOT(do_cmt_push_fast_rewind(int)));
191         connect(this, SIGNAL(sig_cmt_push_apss_forward(int)), hRunEmu, SLOT(do_cmt_push_apss_forward(int)));
192         connect(this, SIGNAL(sig_cmt_push_apss_rewind(int)),  hRunEmu, SLOT(do_cmt_push_apss_rewind(int)));
193 # endif
194 #endif
195 #if defined(USE_QD1)
196         connect(this, SIGNAL(sig_write_protect_quickdisk(int, bool)), hRunEmu, SLOT(do_write_protect_quickdisk(int, bool)));
197         connect(this, SIGNAL(sig_open_quickdisk(int, QString)), hRunEmu, SLOT(do_open_quickdisk(int, QString)));
198         connect(this, SIGNAL(sig_close_quickdisk(int)), hRunEmu, SLOT(do_close_quickdisk(int)));
199         //connect(hRunEmu, SIGNAL(sig_change_osd_qd(int, QString)), this, SLOT(do_change_osd_qd(int, QString)));
200 #endif
201 #if defined(USE_CART1)
202         connect(this, SIGNAL(sig_open_cart(int, QString)), hRunEmu, SLOT(do_open_cart(int, QString)));
203         connect(this, SIGNAL(sig_close_cart(int)), hRunEmu, SLOT(do_close_cart(int)));
204 #endif
205 #if defined(USE_COMPACT_DISC)
206         connect(this, SIGNAL(sig_open_cdrom(QString)), hRunEmu, SLOT(do_open_cdrom(QString)));
207         connect(this, SIGNAL(sig_close_cdrom()), hRunEmu, SLOT(do_eject_cdrom()));
208         //connect(hRunEmu, SIGNAL(sig_change_osd_cdrom(QString)), this, SLOT(do_change_osd_cdrom(QString)));
209 #endif  
210 #if defined(USE_LASER_DISC)
211         connect(this, SIGNAL(sig_open_laserdisc(QString)), hRunEmu, SLOT(do_open_laser_disc(QString)));
212         connect(this, SIGNAL(sig_close_laserdisc(void)), hRunEmu, SLOT(do_close_laser_disc(void)));
213 #endif
214 #if defined(USE_BINARY_FILE1)
215         connect(this, SIGNAL(sig_load_binary(int, QString)), hRunEmu, SLOT(do_load_binary(int, QString)));
216         connect(this, SIGNAL(sig_save_binary(int, QString)), hRunEmu, SLOT(do_save_binary(int, QString)));
217 #endif
218 #if defined(USE_BUBBLE1)
219         connect(this, SIGNAL(sig_write_protect_bubble(int, bool)), hRunEmu, SLOT(do_write_protect_bubble_casette(int, bool)));
220         connect(this, SIGNAL(sig_open_bubble(int, QString, int)), hRunEmu, SLOT(do_open_bubble_casette(int, QString, int)));
221         connect(this, SIGNAL(sig_close_bubble(int)), hRunEmu, SLOT(do_close_bubble_casette(int)));
222         connect(hRunEmu, SIGNAL(sig_update_recent_bubble(int)), this, SLOT(do_update_recent_bubble(int)));
223         //connect(hRunEmu, SIGNAL(sig_change_osd_bubble(int, QString)), this, SLOT(do_change_osd_bubble(int, QString)));
224         drvs = 0;
225 # if defined(USE_BUBBLE1)
226         drvs = 1;
227 # endif
228 # if defined(USE_BUBBLE2)
229         drvs = 2;
230 # endif
231         for(int ii = 0; ii < drvs; ii++) {
232                 menu_bubbles[ii]->setEmu(emu);
233                 connect(menu_bubbles[ii],
234                                 SIGNAL(sig_update_inner_bubble(int ,QStringList , class Action_Control **, QStringList , int, bool)),
235                                 this,
236                                 SLOT(do_update_inner_bubble(int ,QStringList , class Action_Control **, QStringList , int, bool)));
237         }
238 #endif
239         
240         connect(this, SIGNAL(quit_emu_thread()), hRunEmu, SLOT(doExit()));
241         connect(hRunEmu, SIGNAL(sig_mouse_enable(bool)),
242                         this, SLOT(do_set_mouse_enable(bool)));
243
244         
245 #ifdef USE_TAPE_BUTTON
246         hRunEmu->set_tape_play(false);
247 #endif
248 #if defined(USE_KEY_LOCKED) || defined(USE_EXTRA_LEDS)
249         connect(hRunEmu, SIGNAL(sig_send_data_led(quint32)), this, SLOT(do_recv_data_led(quint32)));
250 #endif
251 #ifdef USE_AUTO_KEY
252         connect(this, SIGNAL(sig_start_auto_key(QString)), hRunEmu, SLOT(do_start_auto_key(QString)));
253         connect(this, SIGNAL(sig_stop_auto_key()), hRunEmu, SLOT(do_stop_auto_key()));
254 #endif  
255         //connect(actionExit_Emulator, SIGNAL(triggered()), hRunEmu, SLOT(doExit()));
256         csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "EmuThread : Start.");
257         objNameStr = QString("EmuThreadClass");
258         hRunEmu->setObjectName(objNameStr);
259         
260         hDrawEmu = new DrawThreadClass(emu->get_osd(), csp_logger, this);
261         emu->set_parent_handler(hRunEmu, hDrawEmu);
262         
263 #ifdef ONE_BOARD_MICRO_COMPUTER
264         QImageReader *reader = new QImageReader(":/background.png");
265         QImage *result = new QImage(reader->read()); // this acts as a default if the size is not matched
266         QImage result2 = result->convertToFormat(QImage::Format_ARGB32);
267         glv->updateBitmap(&result2);
268         emu->get_osd()->upload_bitmap(&result2);
269         delete result;
270         delete reader;
271         emu->get_osd()->set_buttons();
272 #endif
273         csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "DrawThread : Start.");
274         connect(hDrawEmu, SIGNAL(sig_draw_frames(int)), hRunEmu, SLOT(print_framerate(int)));
275         //connect(emu->get_osd(), SIGNAL(sig_draw_frames(int)), hRunEmu, SLOT(print_framerate(int)));
276         connect(hRunEmu, SIGNAL(window_title_changed(QString)), this, SLOT(do_set_window_title(QString)));
277         connect(hDrawEmu, SIGNAL(message_changed(QString)), this, SLOT(message_status_bar(QString)));
278         connect(actionCapture_Screen, SIGNAL(triggered()), glv, SLOT(do_save_frame_screen()));
279                 
280         connect(hRunEmu, SIGNAL(sig_draw_thread(bool)), hDrawEmu, SLOT(doDraw(bool)), Qt::QueuedConnection);
281         //connect(hRunEmu, SIGNAL(sig_draw_thread(bool)), emu->get_osd(), SLOT(do_draw(bool)));
282         //connect(hRunEmu, SIGNAL(quit_draw_thread()), hDrawEmu, SLOT(doExit()));
283         connect(this, SIGNAL(quit_draw_thread()), hDrawEmu, SLOT(doExit()));
284
285         connect(glv, SIGNAL(do_notify_move_mouse(int, int)),
286                         hRunEmu, SLOT(moved_mouse(int, int)));
287         connect(glv, SIGNAL(do_notify_button_pressed(Qt::MouseButton)),
288                 hRunEmu, SLOT(button_pressed_mouse(Qt::MouseButton)));
289         connect(glv, SIGNAL(do_notify_button_released(Qt::MouseButton)),
290                         hRunEmu, SLOT(button_released_mouse(Qt::MouseButton)));
291 #ifdef USE_MOUSE
292         connect(glv, SIGNAL(sig_toggle_mouse(void)),
293                         this, SLOT(do_toggle_mouse(void)));
294 #endif
295         connect(hRunEmu, SIGNAL(sig_resize_screen(int, int)),
296                         glv, SLOT(resizeGL(int, int)));
297         connect(hRunEmu, SIGNAL(sig_resize_osd(int)), driveData, SLOT(setScreenWidth(int)));
298         
299         connect(glv, SIGNAL(sig_resize_uibar(int, int)),
300                         this, SLOT(resize_statusbar(int, int)));
301         connect(hRunEmu, SIGNAL(sig_resize_uibar(int, int)),
302                         this, SLOT(resize_statusbar(int, int)));
303
304         connect(emu->get_osd(), SIGNAL(sig_req_encueue_video(int, int, int)),
305                         hDrawEmu, SLOT(do_req_encueue_video(int, int, int)));
306         connect(hRunEmu, SIGNAL(sig_finished()), glv, SLOT(releaseKeyCode(void)));
307         connect(hRunEmu, SIGNAL(sig_finished()), this, SLOT(delete_emu_thread()));
308         objNameStr = QString("EmuDrawThread");
309         hDrawEmu->setObjectName(objNameStr);
310         hDrawEmu->start();
311         csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "DrawThread : Launch done.");
312
313         hSaveMovieThread = new MOVIE_SAVER(640, 400,  30, emu->get_osd(), using_flags->get_config_ptr());
314         
315         connect(actionStart_Record_Movie->binds, SIGNAL(sig_start_record_movie(int)), hRunEmu, SLOT(do_start_record_video(int)));
316         connect(this, SIGNAL(sig_start_saving_movie()),
317                         actionStart_Record_Movie->binds, SLOT(do_save_as_movie()));
318         connect(actionStart_Record_Movie, SIGNAL(triggered()), this, SLOT(do_start_saving_movie()));
319
320         connect(actionStop_Record_Movie->binds, SIGNAL(sig_stop_record_movie()), hRunEmu, SLOT(do_stop_record_video()));
321         connect(this, SIGNAL(sig_stop_saving_movie()), actionStop_Record_Movie->binds, SLOT(do_stop_saving_movie()));
322         connect(hSaveMovieThread, SIGNAL(sig_set_state_saving_movie(bool)), this, SLOT(do_set_state_saving_movie(bool)));
323         connect(actionStop_Record_Movie, SIGNAL(triggered()), this, SLOT(do_stop_saving_movie()));
324
325         connect(emu->get_osd(), SIGNAL(sig_save_as_movie(QString, int, int)),
326                         hSaveMovieThread, SLOT(do_open(QString, int, int)));
327         connect(emu->get_osd(), SIGNAL(sig_stop_saving_movie()), hSaveMovieThread, SLOT(do_close()));
328         
329         actionStop_Record_Movie->setIcon(QIcon(":/icon_process_stop.png"));
330         actionStop_Record_Movie->setVisible(false);
331         
332         connect(this, SIGNAL(sig_movie_set_width(int)), hSaveMovieThread, SLOT(do_set_width(int)));
333         connect(this, SIGNAL(sig_movie_set_height(int)), hSaveMovieThread, SLOT(do_set_height(int)));
334  
335         connect(emu->get_osd(), SIGNAL(sig_movie_set_width(int)), hSaveMovieThread, SLOT(do_set_width(int)));
336         connect(emu->get_osd(), SIGNAL(sig_movie_set_height(int)), hSaveMovieThread, SLOT(do_set_height(int)));
337    
338         connect(emu->get_osd(), SIGNAL(sig_enqueue_audio(int16_t*, int)), hSaveMovieThread, SLOT(enqueue_audio(int16_t *, int)));
339         connect(emu->get_osd(), SIGNAL(sig_enqueue_video(int, int, int, QImage *)),
340                         hSaveMovieThread, SLOT(enqueue_video(int, int, int, QImage *)), Qt::DirectConnection);
341         connect(glv->extfunc, SIGNAL(sig_push_image_to_movie(int, int, int, QImage *)),
342                         hSaveMovieThread, SLOT(enqueue_video(int, int, int, QImage *)));
343         connect(this, SIGNAL(sig_quit_movie_thread()), hSaveMovieThread, SLOT(do_exit()));
344
345         objNameStr = QString("EmuMovieThread");
346         hSaveMovieThread->setObjectName(objNameStr);
347         hSaveMovieThread->start();
348         csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "MovieThread : Launch done.");
349
350         connect(action_SetupMovie, SIGNAL(triggered()), this, SLOT(rise_movie_dialog()));
351         connect(hRunEmu, SIGNAL(sig_change_osd(int, int, QString)), driveData, SLOT(updateMessage(int, int, QString)));
352         connect(hRunEmu, SIGNAL(sig_change_access_lamp(int, int, QString)), driveData, SLOT(updateLabel(int, int, QString)));
353         connect(hRunEmu, SIGNAL(sig_set_access_lamp(int, bool)), graphicsView, SLOT(do_display_osd_leds(int, bool)));
354
355         hRunEmu->start();
356         csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "EmuThread : Launch done.");
357         this->set_screen_aspect(using_flags->get_config_ptr()->window_stretch_type);
358         emit sig_movie_set_width(SCREEN_WIDTH);
359         emit sig_movie_set_height(SCREEN_HEIGHT);
360 }
361
362 void Ui_MainWindow::LaunchJoyThread(void)
363 {
364 #if defined(USE_JOYSTICK)
365         hRunJoy = new JoyThreadClass(emu, emu->get_osd(), using_flags, using_flags->get_config_ptr(), csp_logger);
366         connect(this, SIGNAL(quit_joy_thread()), hRunJoy, SLOT(doExit()));
367         hRunJoy->setObjectName("JoyThread");
368         hRunJoy->start();
369 #endif  
370 }
371
372 void Ui_MainWindow::StopJoyThread(void)
373 {
374 #if defined(USE_JOYSTICK)
375         emit quit_joy_thread();
376 #endif  
377 }
378
379 void Ui_MainWindow::delete_joy_thread(void)
380 {
381         //    delete hRunJoyThread;
382         //  delete hRunJoy;
383 }
384
385 void Ui_MainWindow::on_actionExit_triggered()
386 {
387         OnMainWindowClosed();
388 }
389
390 void Ui_MainWindow::OnWindowRedraw(void)
391 {
392         if(emu) {
393                 //emu->update_screen();
394         }
395 }
396
397 void Ui_MainWindow::OnWindowMove(void)
398 {
399         if(emu) {
400                 emu->suspend();
401         }
402 }
403
404
405 #ifdef USE_NOTIFY_POWER_OFF
406 bool Ui_MainWindow::GetPowerState(void)
407 {
408         if(close_notified == 0) return true;
409         return false;
410 }
411 #endif
412
413 void Ui_MainWindow::OnMainWindowClosed(void)
414 {
415         // notify power off
416 #ifdef USE_NOTIFY_POWER_OFF
417         if(emu) {
418                 if(!close_notified) {
419                         emu->lock_vm();
420                         emu->notify_power_off();
421                         emu->unlock_vm();
422                         close_notified = 1;
423                         return; 
424                 }
425         }
426 #endif
427         if(statusUpdateTimer != NULL) statusUpdateTimer->stop();
428 #if defined(USE_KEY_LOCKED) || defined(USE_EXTRA_LEDS)
429         if(ledUpdateTimer != NULL) ledUpdateTimer->stop();
430 #endif
431         emit quit_draw_thread();
432         emit quit_joy_thread();
433         emit quit_emu_thread();
434         emit sig_quit_movie_thread();
435         emit sig_quit_widgets();
436         
437         if(hSaveMovieThread != NULL) {
438                 hSaveMovieThread->wait();
439                 delete hSaveMovieThread;
440                 hSaveMovieThread = NULL;
441         }
442    
443         if(hDrawEmu != NULL) {
444                 hDrawEmu->wait();
445                 delete hDrawEmu;
446                 hDrawEmu = NULL;
447         }
448         if(hRunEmu != NULL) {
449                 hRunEmu->quit();
450                 hRunEmu->wait();
451                 delete hRunEmu;
452                 save_config(create_local_path(_T("%s.ini"), _T(CONFIG_NAME)));
453         }
454 #if defined(USE_JOYSTICK)
455         if(hRunJoy != NULL) {
456                 hRunJoy->wait();
457                 delete hRunJoy;
458                 hRunJoy = NULL;
459         }
460 #endif
461         do_release_emu_resources();
462         hRunEmu = NULL;
463
464         // release window
465         if(now_fullscreen) {
466                 //ChangeDisplaySettings(NULL, 0);
467         }
468         now_fullscreen = false;
469         return;
470 }
471
472 extern "C" {
473
474 void LostFocus(QWidget *widget)
475 {
476         if(emu) {
477                 emu->key_lost_focus();
478         }
479 }
480  
481 }  // extern "C"
482
483 void Ui_MainWindow::do_release_emu_resources(void)
484 {
485         if(emu) {
486                 delete emu;
487                 emu = NULL;
488         }
489 }
490
491 extern void DLL_PREFIX_I get_long_full_path_name(_TCHAR* src, _TCHAR* dst);
492 extern _TCHAR* DLL_PREFIX_I get_parent_dir(_TCHAR* file);
493 extern void get_short_filename(_TCHAR *dst, _TCHAR *file, int maxlen);
494
495 static void setup_logs(void)
496 {
497         std::string delim;
498         char    *p;
499
500         my_procname = "emu";
501         my_procname = my_procname + CONFIG_NAME;
502 #if defined(Q_OS_WIN)
503         delim = "\\";
504 #else
505         delim = "/";
506 #endif
507 #if !defined(Q_OS_WIN)
508         p = SDL_getenv("HOME");
509         if(p == NULL) {
510                 p = SDL_getenv("PWD");
511                 if(p == NULL) {
512                         cpp_homedir = ".";
513                 } else {
514                         cpp_homedir = p;
515                 }
516                 std::string tmpstr;
517                 tmpstr = "Warning : Can't get HOME directory...Making conf on " +  cpp_homedir + delim;
518                 perror(tmpstr.c_str());
519         } else {
520                 cpp_homedir = p;
521         }
522 #else
523         cpp_homedir = ".";
524 #endif  
525         cpp_homedir = cpp_homedir + delim;
526 #ifdef _WINDOWS
527         cpp_confdir = cpp_homedir + my_procname + delim;
528 #else
529         cpp_confdir = cpp_homedir + ".config" + delim + my_procname + delim;
530 #endif
531         
532 #if !defined(Q_OS_CYGWIN)       
533         {
534                 QDir dir;
535                 dir.mkdir( QString::fromStdString(cpp_confdir));
536         }
537 #endif   
538    //AG_MkPath(cpp_confdir.c_str());
539    /* Gettext */
540 #ifndef RSSDIR
541 #if defined(_USE_AGAR) || defined(_USE_QT)
542         sRssDir = "/usr/local/share/";
543 #else
544         sRssDir = "." + delim;
545 #endif
546         sRssDir = sRssDir + "CommonSourceCodeProject" + delim + my_procname;
547 #else
548         sRssDir = RSSDIR;
549 #endif
550 }
551
552 CSP_Logger *csp_logger;
553
554 int MainLoop(int argc, char *argv[])
555 {
556         char homedir[PATH_MAX];
557         std::string archstr;
558         std::string emustr("emu");
559         std::string cfgstr(CONFIG_NAME);
560         setup_logs();
561         cpp_homedir.copy(homedir, PATH_MAX - 1, 0);
562
563         load_config(create_local_path(_T("%s.ini"), _T(CONFIG_NAME)));
564         
565         emustr = emustr + cfgstr;
566
567         csp_logger = new CSP_Logger(config.log_to_syslog, config.log_to_console, emustr.c_str()); // Write to syslog, console
568         csp_logger->set_log_stdout(CSP_LOG_DEBUG, true);
569         csp_logger->set_log_stdout(CSP_LOG_INFO, true);
570         csp_logger->set_log_stdout(CSP_LOG_WARN, true);
571         
572         archstr = "Generic";
573 #if defined(__x86_64__)
574         archstr = "amd64";
575 #endif
576 #if defined(__i386__)
577         archstr = "ia32";
578 #endif
579         csp_logger->set_emu_vm_name(DEVICE_NAME); // Write to syslog, console
580         csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Start Common Source Project '%s'", my_procname.c_str());
581         csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "(C) Toshiya Takeda / Qt Version K.Ohta");
582         csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Architecture: %s", archstr.c_str());
583         
584         //csp_logger->debug_log(AGAR_LOG_INFO, " -? is print help(s).");
585         csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Moduledir = %s home = %s", cpp_confdir.c_str(), cpp_homedir.c_str()); // Debug
586         /*
587          * Into Qt's Loop.
588          */
589 #if defined(USE_SDL2)
590         SDL_Init(SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER);
591 #else
592         SDL_Init(SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_VIDEO);
593 #endif
594         csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Audio and JOYSTICK subsystem was initialised.");
595         GuiMain = new QApplication(argc, argv);
596         GuiMain->setObjectName(QString::fromUtf8("Gui_Main"));
597         for(int ii = 0; ii < (CSP_LOG_TYPE_VM_DEVICE_END - CSP_LOG_TYPE_VM_DEVICE_0 + 1); ii++) {
598                 for(int jj = 0; jj < 8; jj++) {
599                         csp_logger->set_device_node_log(ii, 1, jj, config.dev_log_to_syslog[ii][jj]);
600                         csp_logger->set_device_node_log(ii, 2, jj, config.dev_log_to_console[ii][jj]);
601                         csp_logger->set_device_node_log(ii, 0, jj, config.dev_log_recording[ii][jj]);
602                 }
603         }
604         USING_FLAGS_EXT *using_flags = new USING_FLAGS_EXT(&config);
605         // initialize emulation core
606
607         QTranslator local_translator;
608         QLocale s_locale;
609         if(local_translator.load(s_locale, QLatin1String("csp_qt_machine"), QLatin1String("_"), QLatin1String(":/"))) {
610                 GuiMain->installTranslator(&local_translator);
611         }
612         QTranslator s_translator;
613         if(s_translator.load(s_locale, QLatin1String("csp_qt_gui"), QLatin1String("_"), QLatin1String(":/"))) {
614                 GuiMain->installTranslator(&s_translator);
615         }
616         
617         rMainWindow = new META_MainWindow(using_flags, csp_logger);
618         rMainWindow->connect(rMainWindow, SIGNAL(sig_quit_all(void)), rMainWindow, SLOT(deleteLater(void)));
619         rMainWindow->setCoreApplication(GuiMain);
620         rMainWindow->getWindow()->show();
621                         
622         // main loop
623         rMainWindow->LaunchEmuThread();
624 #if defined(USE_JOYSTICK)
625         rMainWindow->LaunchJoyThread();
626 #endif  
627         GLDrawClass *pgl = rMainWindow->getGraphicsView();
628         pgl->set_emu_launched();
629         pgl->setFixedSize(pgl->width(), pgl->height());
630         rMainWindow->retranselateUi_Depended_OSD();
631         QObject::connect(emu->get_osd(), SIGNAL(sig_update_device_node_name(int, const _TCHAR *)),
632                                          rMainWindow, SLOT(do_update_device_node_name(int, const _TCHAR *)));
633         for(int i = 0; i < (CSP_LOG_TYPE_VM_DEVICE_END - CSP_LOG_TYPE_VM_DEVICE_0 + 1); i++) {
634                 rMainWindow->do_update_device_node_name(i, using_flags->get_vm_node_name(i));
635         }
636         csp_logger->set_osd(emu->get_osd());
637         csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "InitInstance() OK.");
638         
639         QObject::connect(GuiMain, SIGNAL(lastWindowClosed()),
640                                          rMainWindow, SLOT(on_actionExit_triggered()));
641
642         GuiMain->exec();
643         return 0;
644 }
645
646 void Ui_MainWindow::do_update_inner_fd(int drv, QStringList base, class Action_Control **action_select_media_list,
647                                        QStringList lst, int num, bool use_d88_menus)
648 {
649 #if defined(USE_FD1)
650         if(use_d88_menus) {
651                 for(int ii = 0; ii < using_flags->get_max_d88_banks(); ii++) {
652                         if(ii < emu->d88_file[drv].bank_num) {
653                                 base << lst.value(ii);
654                                 action_select_media_list[ii]->setText(lst.value(ii));
655                                 action_select_media_list[ii]->setVisible(true);
656                                 if(ii == num) action_select_media_list[ii]->setChecked(true);
657                         } else {
658                                 if(action_select_media_list[ii] != NULL) {
659                                         action_select_media_list[ii]->setText(QString::fromUtf8(""));
660                                         action_select_media_list[ii]->setVisible(false);
661                                 }
662                         }
663                 }
664         }
665 #endif  
666 }
667
668 void Ui_MainWindow::do_update_inner_bubble(int drv, QStringList base, class Action_Control **action_select_media_list,
669                                        QStringList lst, int num, bool use_d88_menus)
670 {
671 #if defined(USE_BUBBLE1)        
672         if(use_d88_menus) {
673                 for(int ii = 0; ii < using_flags->get_max_b77_banks(); ii++) {
674                         if(ii < emu->b77_file[drv].bank_num) {
675                                 base << lst.value(ii);
676                                 action_select_media_list[ii]->setText(lst.value(ii));
677                                 action_select_media_list[ii]->setVisible(true);
678                                 if(ii == num) action_select_media_list[ii]->setChecked(true);
679                         } else {
680                                 if(action_select_media_list[ii] != NULL) {
681                                         action_select_media_list[ii]->setText(QString::fromUtf8(""));
682                                         action_select_media_list[ii]->setVisible(false);
683                                 }
684                         }
685                 }
686         }
687 #endif  
688 }
689
690 #ifdef USE_DEBUGGER
691 #include <../debugger/qt_debugger.h>
692
693 void Ui_MainWindow::OnOpenDebugger(int no)
694 {
695         if((no < 0) || (no > 7)) return;
696         //emu->open_debugger(no);
697         VM *vm = emu->get_vm();
698
699         if(emu->now_debugging)  this->OnCloseDebugger();
700         if(!(emu->now_debugging && emu->debugger_thread_param.cpu_index == no)) {
701                 //emu->close_debugger();
702                 if(vm->get_cpu(no) != NULL && vm->get_cpu(no)->get_debugger() != NULL) {
703                         
704                         emu->hDebugger = new CSP_Debugger(this);
705                         QString objNameStr = QString("EmuDebugThread");
706                         emu->hDebugger->setObjectName(objNameStr);
707                         emu->hDebugger->debugger_thread_param.osd = emu->get_osd();
708                         emu->hDebugger->debugger_thread_param.vm = vm;
709                         emu->hDebugger->debugger_thread_param.cpu_index = no;
710                         emu->stop_record_sound();
711                         emu->stop_record_video();
712                         emu->now_debugging = true;
713                         connect(this, SIGNAL(quit_debugger_thread()), emu->hDebugger, SLOT(doExit()));
714                         connect(this, SIGNAL(destroyed()), emu->hDebugger, SLOT(do_destroy_thread()));
715                         //connect(this, SIGNAL(quit_debugger_thread()), emu->hDebugger, SLOT(close()));
716                         connect(emu->hDebugger, SIGNAL(sig_finished()), this, SLOT(OnCloseDebugger()));
717                         connect(emu->hDebugger, SIGNAL(sig_put_string(QString)), emu->hDebugger, SLOT(put_string(QString)));
718                         emu->hDebugger->show();
719                         emu->hDebugger->run();
720                 }
721         }
722 }
723
724 void Ui_MainWindow::OnCloseDebugger(void )
725 {
726
727 //      emu->close_debugger();
728         if(emu->now_debugging) {
729                 if(emu->hDebugger->debugger_thread_param.running) {
730                         emit quit_debugger_thread();
731                         //emu->hDebugger->wait();
732                 }
733                 delete emu->hDebugger;
734                 emu->hDebugger = NULL;
735                 emu->now_debugging = false;
736         }
737 }
738 #endif
739 extern config_t config;
740
741 #include <QApplication>
742 #include <qapplication.h>
743 #if defined(Q_OS_WIN)
744 //DLL_PREFIX_I void CSP_DebugHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg);
745 DLL_PREFIX_I void _resource_init(void);
746 DLL_PREFIX_I void _resource_free(void);
747 #else
748 extern void CSP_DebugHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg);
749 extern void _resource_init(void);
750 extern void _resource_free(void);
751 #endif
752 void CSP_DebugHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
753 {
754         QString msg_type;
755     switch (type) {
756     case QtDebugMsg:
757                 msg_type = QString::fromUtf8("[Qt:DEBUG]");
758         break;
759     case QtInfoMsg:
760                 msg_type = QString::fromUtf8("[Qt:INFO]");
761         break;
762     case QtWarningMsg:
763                 msg_type = QString::fromUtf8("[Qt:WARN]");
764         break;
765     case QtCriticalMsg:
766                 msg_type = QString::fromUtf8("[Qt:CRITICAL]");
767         break;
768     case QtFatalMsg:
769                 msg_type = QString::fromUtf8("[Qt:FATAL]");
770                 break;
771     }
772         QString msgString = qFormatLogMessage(type, context, msg);
773         QString nmsg_l1 = msg_type;
774         QString nmsg_l2 = msg_type;
775         nmsg_l2.append(" ");
776         nmsg_l2.append(msgString);
777         nmsg_l1.append(" In line ");
778         nmsg_l1.append(context.line);
779         nmsg_l1.append(" of ");
780         nmsg_l1.append(context.line);
781         nmsg_l1.append(" (Function: ");
782         nmsg_l1.append(context.function);
783         nmsg_l1.append(" )");
784
785         if(csp_logger != NULL) {
786                 csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GUI, nmsg_l1.toLocal8Bit().constData());
787                 csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GUI, nmsg_l2.toLocal8Bit().constData());
788         } else {
789                 fprintf(stderr,"%s\n", nmsg_l1.toLocal8Bit().constData());
790                 fprintf(stderr, "%s\n", nmsg_l2.toLocal8Bit().constData());
791         }               
792 }
793
794 int main(int argc, char *argv[])
795 {
796         int nErrorCode;
797         /*
798          * Get current DIR
799          */
800         csp_logger = NULL;
801 /*
802  * アプリケーション初期化
803  */
804         _resource_init();
805         qSetMessagePattern(QString::fromUtf8("[%{type}] %{message} \n   at line %{line} of %{file} : function %{function}\nBacktrace:\n %{backtrace separator=\"\n \" }"));
806         qInstallMessageHandler(CSP_DebugHandler);
807         nErrorCode = MainLoop(argc, argv);
808         _resource_free();
809         if(csp_logger != NULL) delete csp_logger;
810         
811         return nErrorCode;
812 }
813
814 #if defined(Q_OS_WIN) 
815 int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
816 {
817    char *arg[1] = {""};
818    main(1, arg);
819 }
820 #endif