2 Skelton for retropc emulator
3 Author : Takeda.Toshiya
4 Port to Qt : K.Ohta <whatisthis.sowhat _at_ gmail.com>
7 [ win32 main ] -> [ agar main ]
15 #include <QApplication>
19 #include <QImageReader>
23 #include <QTranslator>
24 #include <QProcessEnvironment>
25 #include <QCommandLineParser>
33 #include "menuclasses.h"
34 #include "mainwidget.h"
35 #include "commonclasses.h"
37 #include "emu_thread.h"
38 #include "joy_thread.h"
39 #include "draw_thread.h"
41 #include "qt_gldraw.h"
42 #include "../gui/gl2/qt_glutil_gl2_0.h"
43 #include "csp_logger.h"
45 #include "dock_disks.h"
47 #include "menu_binary.h"
48 #include "menu_bubble.h"
49 #include "menu_cart.h"
51 #include "menu_compactdisc.h"
52 #include "menu_disk.h"
53 #include "menu_harddisk.h"
54 #include "menu_laserdisc.h"
55 #include "menu_quickdisk.h"
58 #include "menu_flags_ext.h"
59 #include "dialog_movie.h"
60 #include "../avio/movie_saver.h"
62 #include "../../vm/vm_limits.h"
63 #include "../../vm/fmgen/fmgen.h"
65 //QApplication *GuiMain = NULL;
66 extern config_t config;
68 // Start to define MainWindow.
69 class META_MainWindow *rMainWindow;
75 extern DLL_PREFIX_I std::string cpp_homedir;
76 extern DLL_PREFIX_I std::string cpp_confdir;
77 extern DLL_PREFIX_I std::string my_procname;
78 extern DLL_PREFIX_I std::string sRssDir;
80 void Ui_MainWindow::do_set_mouse_enable(bool flag)
83 if(hRunEmu == nullptr) return;
84 EMU_TEMPLATE *p_emu = hRunEmu->get_emu();
85 if(p_emu == nullptr) return;
89 graphicsView->grabMouse();
90 p_emu->enable_mouse();
92 graphicsView->releaseMouse();
93 p_emu->disable_mouse();
99 void Ui_MainWindow::do_toggle_mouse(void)
102 if(hRunEmu == nullptr) return;
103 EMU_TEMPLATE *p_emu = hRunEmu->get_emu();
104 if(p_emu == nullptr) return;
105 if(graphicsView == nullptr) return;
108 bool flag = p_emu->is_mouse_enabled();
110 graphicsView->grabMouse();
111 p_emu->enable_mouse();
113 graphicsView->releaseMouse();
114 p_emu->disable_mouse();
120 void Ui_MainWindow::rise_movie_dialog(void)
122 CSP_DialogMovie *dlg = new CSP_DialogMovie(hSaveMovieThread, using_flags);
123 dlg->setWindowTitle(QApplication::translate("CSP_DialogMovie", "Configure movie encodings", 0));
127 void Ui_MainWindow::LaunchEmuThread(EmuThreadClassBase *m)
130 GLDrawClass *glv = this->getGraphicsView();
135 if(hRunEmu == nullptr) return;
136 EMU_TEMPLATE* p_emu = hRunEmu->get_emu();
137 if(p_emu == nullptr) return;
139 OSD_BASE* p_osd = p_emu->get_osd();
140 if(p_osd == nullptr) return;
142 connect(hRunEmu, SIGNAL(message_changed(QString)), this, SLOT(message_status_bar(QString)), Qt::QueuedConnection);
143 connect(hRunEmu, SIGNAL(sig_is_enable_mouse(bool)), this, SLOT(do_set_mouse_enable(bool)));
144 connect(glv, SIGNAL(sig_key_down(uint32_t, uint32_t, bool)), hRunEmu, SLOT(do_key_down(uint32_t, uint32_t, bool)));
145 connect(glv, SIGNAL(sig_key_up(uint32_t, uint32_t)),hRunEmu, SLOT(do_key_up(uint32_t, uint32_t)));
146 connect(this, SIGNAL(sig_quit_widgets()), glv, SLOT(do_stop_run_vm()));
148 if(action_ResetFixedCpu != nullptr) {
149 connect(action_ResetFixedCpu, SIGNAL(triggered()),
150 hRunEmu, SLOT(do_set_emu_thread_to_fixed_cpu_from_action()));
153 for(int i = 0 ; i < 128 ; i++) {
154 if(action_SetFixedCpu[i] == nullptr) break;
155 connect(action_SetFixedCpu[i], SIGNAL(triggered()),
156 hRunEmu, SLOT(do_set_emu_thread_to_fixed_cpu_from_action()));
158 connect(this, SIGNAL(sig_vm_reset()), hRunEmu, SLOT(do_reset()));
160 for(int i = 0 ; i < using_flags->get_use_special_reset_num() ; i++) {
161 if(actionSpecial_Reset[i] != nullptr) {
162 connect(actionSpecial_Reset[i], SIGNAL(triggered()), hRunEmu, SLOT(do_special_reset()));
166 connect(this, SIGNAL(sig_emu_update_config()), hRunEmu, SLOT(do_update_config()));
167 connect(this, SIGNAL(sig_emu_update_volume_level(int, int)), hRunEmu, SLOT(do_update_volume_level(int, int)));
168 connect(this, SIGNAL(sig_emu_update_volume_balance(int, int)), hRunEmu, SLOT(do_update_volume_balance(int, int)));
169 connect(this, SIGNAL(sig_emu_start_rec_sound()), hRunEmu, SLOT(do_start_record_sound()));
170 connect(this, SIGNAL(sig_emu_stop_rec_sound()), hRunEmu, SLOT(do_stop_record_sound()));
171 connect(this, SIGNAL(sig_emu_set_display_size(int, int, int, int)), hRunEmu, SLOT(do_set_display_size(int, int, int, int)));
172 connect(this, SIGNAL(sig_emu_thread_to_fixed_cpu(int)), hRunEmu, SLOT(do_set_emu_thread_to_fixed_cpu(int)));
174 if(using_flags->is_use_state()) {
175 for(int i = 0; i < 10; i++) {
176 connect(actionLoad_State[i], SIGNAL(triggered()), hRunEmu, SLOT(do_load_state())); // OK?
177 connect(actionSave_State[i], SIGNAL(triggered()), hRunEmu, SLOT(do_save_state())); // OK?
180 #if defined(USE_FLOPPY_DISK)
181 // connect(this, SIGNAL(sig_write_protect_floppy_disk(int, bool)),
182 // hRunEmu, SLOT(do_write_protect_floppy_disk(int, bool)),
183 // Qt::QueuedConnection);
184 connect(this, SIGNAL(sig_open_floppy_disk(int, QString, int)),
185 hRunEmu, SLOT(do_open_floppy_disk(int, QString, int)),
186 Qt::QueuedConnection);
187 connect(this, SIGNAL(sig_close_floppy_disk_ui(int)),
188 hRunEmu, SLOT(do_close_floppy_disk_ui(int)),
189 Qt::QueuedConnection);
190 //connect(hRunEmu, SIGNAL(sig_change_osd_fd(int, QString)), this, SLOT(do_change_osd_fd(int, QString)));
192 // ToDo: eject from EMU_THREAD:: .
193 connect(p_osd, SIGNAL(sig_ui_floppy_insert_history(int, QString, quint64)),
194 this, SLOT(do_ui_floppy_insert_history(int, QString, quint64)),
195 Qt::QueuedConnection);
196 connect(p_osd, SIGNAL(sig_ui_floppy_write_protect(int, quint64)),
197 this, SLOT(do_ui_write_protect_floppy_disk(int, quint64)),
198 Qt::QueuedConnection);
199 connect(p_osd, SIGNAL(sig_ui_floppy_close(int)),
200 this, SLOT(do_ui_eject_floppy_disk(int)),
201 Qt::QueuedConnection);
203 drvs = USE_FLOPPY_DISK;
204 for(int ii = 0; ii < drvs; ii++) {
205 if(menu_fds[ii] != nullptr) {
206 menu_fds[ii]->connect_via_emu_thread(hRunEmu);
207 connect(menu_fds[ii], SIGNAL(sig_set_inner_slot(int, int)),
208 hRunEmu, SLOT(do_select_floppy_disk_d88(int, int)),
209 Qt::QueuedConnection);
213 #if defined(USE_HARD_DISK)
214 for(int ii = 0; ii < USE_HARD_DISK; ii++) {
215 if(ii >= USE_HARD_DISK_TMP) break;
216 Menu_HDDClass *mp = menu_hdds[ii];
218 mp->connect_via_emu_thread(hRunEmu);
221 connect(this, SIGNAL(sig_open_hard_disk(int, QString)),
222 hRunEmu, SLOT(do_open_hard_disk(int, QString)),
223 Qt::QueuedConnection);
224 // connect(this, SIGNAL(sig_close_hard_disk_ui(int)),
225 // hRunEmu, SLOT(do_close_hard_disk_ui(int)),
226 // Qt::QueuedConnection);
228 connect(p_osd, SIGNAL(sig_ui_hard_disk_insert_history(int, QString)),
229 this, SLOT(do_ui_hard_disk_insert_history(int, QString)),
230 Qt::QueuedConnection);
231 connect(p_osd, SIGNAL(sig_ui_hard_disk_close(int)),
232 this, SLOT(do_ui_eject_hard_disk(int)),
233 Qt::QueuedConnection);
236 #if defined(USE_TAPE)
237 for(int ii = 0; ii < USE_TAPE; ii++) {
238 if(ii >= USE_TAPE_TMP) break;
239 Menu_CMTClass *mp = menu_CMT[ii];
241 mp->connect_via_emu_thread(hRunEmu);
244 connect(this, SIGNAL(sig_play_tape(int, QString)), hRunEmu, SLOT(do_play_tape(int, QString)));
245 connect(this, SIGNAL(sig_rec_tape(int, QString)), hRunEmu, SLOT(do_rec_tape(int, QString)));
247 connect(p_osd, SIGNAL(sig_ui_tape_play_insert_history(int, QString)),
248 this, SLOT(do_ui_tape_play_insert_history(int, QString)),
249 Qt::QueuedConnection);
250 connect(p_osd, SIGNAL(sig_ui_tape_record_insert_history(int, QString)),
251 this, SLOT(do_ui_tape_record_insert_history(int, QString)),
252 Qt::QueuedConnection);
253 connect(p_osd, SIGNAL(sig_ui_tape_write_protect(int, quint64)),
254 this, SLOT(do_ui_write_protect_tape(int, quint64)),
255 Qt::QueuedConnection);
256 connect(p_osd, SIGNAL(sig_ui_tape_eject(int)),
257 this, SLOT(do_ui_eject_tape(int)),
258 Qt::QueuedConnection);
260 #if defined(USE_QUICK_DISK)
261 for(int ii = 0; ii < USE_QUICK_DISK; ii++) {
262 if(ii >= USE_QUICK_DISK) break;
263 Menu_QDClass *mp = menu_QDs[ii];
265 mp->connect_via_emu_thread(hRunEmu);
269 connect(this, SIGNAL(sig_write_protect_quick_disk(int, bool)),
270 hRunEmu, SLOT(do_write_protect_quick_disk(int, bool)),
271 Qt::QueuedConnection);
272 connect(this, SIGNAL(sig_open_quick_disk(int, QString)),
273 hRunEmu, SLOT(do_open_quick_disk(int, QString)),
274 Qt::QueuedConnection);
275 connect(this, SIGNAL(sig_close_quick_disk_ui(int)),
276 hRunEmu, SLOT(do_close_quick_disk_ui(int)),
277 Qt::QueuedConnection);
279 connect(p_osd, SIGNAL(sig_ui_quick_disk_write_protect(int, quint64)),
280 this, SLOT(do_ui_quick_disk_write_protect(int, quint64)),
281 Qt::QueuedConnection);
282 connect(p_osd, SIGNAL(sig_ui_quick_disk_insert_history(int, QString)),
283 this, SLOT(do_ui_quick_disk_insert_history(int, QString)),
284 Qt::QueuedConnection);
285 connect(p_osd, SIGNAL(sig_ui_quick_disk_close(int)),
286 this, SLOT(do_ui_eject_quick_disk(int)),
287 Qt::QueuedConnection);
290 #if defined(USE_CART)
291 for(int ii = 0; ii < USE_CART; ii++) {
292 if(ii >= USE_CART_TMP) break;
293 Menu_CartClass *mp = menu_Cart[ii];
295 mp->connect_via_emu_thread(hRunEmu);
298 connect(this, SIGNAL(sig_open_cartridge(int, QString)), hRunEmu, SLOT(do_open_cartridge(int, QString)));
299 connect(this, SIGNAL(sig_eject_cartridge_ui(int)), hRunEmu, SLOT(do_close_cartridge_ui(int)));
301 connect(p_osd, SIGNAL(sig_ui_cartridge_insert_history(int, QString)),
302 this, SLOT(do_ui_cartridge_insert_history(int, QString)),
303 Qt::QueuedConnection);
304 connect(p_osd, SIGNAL(sig_ui_cartridge_eject(int)),
305 this, SLOT(do_ui_eject_cartridge(int)),
306 Qt::QueuedConnection);
308 #if defined(USE_COMPACT_DISC)
309 for(int ii = 0; ii < USE_COMPACT_DISC; ii++) {
310 if(ii >= USE_COMPACT_DISC_TMP) break;
311 Menu_CompactDiscClass *mp = menu_CDROM[ii];
313 mp->connect_via_emu_thread(hRunEmu);
316 connect(this, SIGNAL(sig_open_compact_disc(int, QString)),
317 hRunEmu, SLOT(do_open_compact_disc(int, QString)),
318 Qt::QueuedConnection);
319 connect(this, SIGNAL(sig_eject_compact_disc_ui(int)),
320 hRunEmu, SLOT(do_eject_compact_disc_ui(int)),
321 Qt::QueuedConnection);
323 connect(p_osd, SIGNAL(sig_ui_compact_disc_insert_history(int, QString)),
324 this, SLOT(do_ui_compact_disc_insert_history(int, QString)),
325 Qt::QueuedConnection);
326 connect(p_osd, SIGNAL(sig_ui_compact_disc_eject(int)),
327 this, SLOT(do_ui_eject_compact_disc(int)),
328 Qt::QueuedConnection);
330 #if defined(USE_LASER_DISC)
331 for(int ii = 0; ii < USE_LASER_DISC; ii++) {
332 if(ii >= USE_LASER_DISC_TMP) break;
333 Menu_LaserdiscClass *mp = menu_Laserdisc[ii];
335 mp->connect_via_emu_thread(hRunEmu);
338 connect(this, SIGNAL(sig_open_laser_disc(int, QString)),
339 hRunEmu, SLOT(do_open_laser_disc(int, QString)),
340 Qt::QueuedConnection);
341 connect(this, SIGNAL(sig_close_laser_disc_ui(int)),
342 hRunEmu, SLOT(do_close_laser_disc_ui(int)),
343 Qt::QueuedConnection);
345 connect(p_osd, SIGNAL(sig_ui_laser_disc_insert_history(int, QString)),
346 this, SLOT(do_ui_laser_disc_insert_history(int, QString)),
347 Qt::QueuedConnection);
348 connect(p_osd, SIGNAL(sig_ui_laser_disc_eject(int)),
349 this, SLOT(do_ui_eject_laser_disc(int)),
350 Qt::QueuedConnection);
352 // ToDo: multiple LDs
354 #if defined(USE_BINARY_FILE)
355 connect(this, SIGNAL(sig_load_binary(int, QString)), hRunEmu, SLOT(do_load_binary(int, QString)));
356 connect(this, SIGNAL(sig_save_binary(int, QString)), hRunEmu, SLOT(do_save_binary(int, QString)));
358 #if defined(USE_BUBBLE)
359 for(int ii = 0; ii < USE_BUBBLE; ii++) {
360 if(ii >= USE_BUBBLE_TMP) break;
361 Menu_BubbleClass *mp = menu_bubbles[ii];
363 mp->connect_via_emu_thread(hRunEmu);
364 connect(mp, SIGNAL(sig_set_inner_slot(int, int)),
365 hRunEmu, SLOT(do_select_bubble_casette_b77(int, int)),
366 Qt::QueuedConnection);
369 connect(this, SIGNAL(sig_open_bubble(int, QString, int)),
370 hRunEmu, SLOT(do_open_bubble_casette(int, QString, int)),
371 Qt::QueuedConnection);
372 connect(this, SIGNAL(sig_close_bubble_ui(int)),
373 hRunEmu, SLOT(do_close_bubble_casette_ui(int)),
374 Qt::QueuedConnection);
376 connect(p_osd, SIGNAL(sig_ui_bubble_insert_history(int, QString, quint64)),
377 this, SLOT(do_ui_bubble_insert_history(int, QString, quint64)),
378 Qt::QueuedConnection);
379 connect(p_osd, SIGNAL(sig_ui_bubble_write_protect(int, quint64)),
380 this, SLOT(do_ui_bubble_write_protect(int, quint64)),
381 Qt::QueuedConnection);
382 connect(p_osd, SIGNAL(sig_ui_bubble_closed(int)),
383 this, SLOT(do_ui_eject_bubble_casette(int)),
384 Qt::QueuedConnection);
388 hRunEmu->set_tape_play(false);
389 #if defined(USE_KEY_LOCKED) || defined(USE_LED_DEVICE)
390 connect(hRunEmu, SIGNAL(sig_send_data_led(quint32)), this, SLOT(do_recv_data_led(quint32)), Qt::QueuedConnection);
393 connect(this, SIGNAL(sig_start_auto_key(QString)), hRunEmu, SLOT(do_start_auto_key(QString)), Qt::QueuedConnection);
394 connect(this, SIGNAL(sig_stop_auto_key()), hRunEmu, SLOT(do_stop_auto_key()), Qt::QueuedConnection);
395 connect(this, SIGNAL(sig_set_roma_kana(bool)), hRunEmu, SLOT(do_set_roma_kana(bool)), Qt::QueuedConnection);
398 csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "EmuThread : Start.");
399 objNameStr = QString("EmuThreadClass");
400 hRunEmu->setObjectName(objNameStr);
402 hDrawEmu = new DrawThreadClass((OSD*)p_osd, csp_logger, this);
403 p_emu->set_parent_handler((EmuThreadClass*)hRunEmu, hDrawEmu);
405 #ifdef ONE_BOARD_MICRO_COMPUTER
406 QImageReader *reader = new QImageReader(":/background.png");
407 QImage *result = new QImage(reader->read()); // this acts as a default if the size is not matched
408 QImage result2 = result->convertToFormat(QImage::Format_ARGB32);
409 glv->updateBitmap(&result2);
410 p_osd->upload_bitmap(&result2);
413 p_osd->set_buttons();
416 csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "DrawThread : Start.");
418 //connect(hDrawEmu, SIGNAL(sig_draw_frames(int)), hRunEmu, SLOT(do_print_framerate(int)), Qt::DirectConnection);
419 connect((OSD*)p_osd, SIGNAL(sig_draw_frames(int)), hRunEmu, SLOT(do_print_framerate(int)));
420 connect(hDrawEmu, SIGNAL(message_changed(QString)), this, SLOT(message_status_bar(QString)));
421 connect(this, SIGNAL(quit_draw_thread()), hDrawEmu, SLOT(doExit()));
422 connect(hDrawEmu, SIGNAL(finished()), hDrawEmu, SLOT(deleteLater()));
424 connect(hRunEmu, SIGNAL(window_title_changed(QString)), this, SLOT(do_set_window_title(QString)), Qt::QueuedConnection);
425 connect(this, SIGNAL(sig_quit_emu_thread()), hRunEmu, SLOT(doExit()), Qt::QueuedConnection);
426 connect(hRunEmu, SIGNAL(sig_mouse_enable(bool)),
427 this, SLOT(do_set_mouse_enable(bool)), Qt::QueuedConnection);
428 /*if(config.use_separate_thread_draw) {
429 connect(hRunEmu, SIGNAL(sig_draw_thread(bool)), hDrawEmu, SLOT(doDraw(bool)));
430 connect(hRunEmu, SIGNAL(sig_set_draw_fps(double)), hDrawEmu, SLOT(do_set_frames_per_second(double)));
431 connect(hRunEmu, SIGNAL(sig_draw_one_turn(bool)), hDrawEmu, SLOT(do_draw_one_turn(bool)));
433 connect(hRunEmu, SIGNAL(sig_draw_thread(bool)), hDrawEmu, SLOT(doDraw(bool)));
434 connect(hRunEmu, SIGNAL(sig_set_draw_fps(double)), hDrawEmu, SLOT(do_set_frames_per_second(double)));
435 connect(hRunEmu, SIGNAL(sig_draw_one_turn(bool)), hDrawEmu, SLOT(do_draw_one_turn(bool)));
437 //connect(hRunEmu, SIGNAL(sig_draw_thread(bool)), (OSD*)p_osd, SLOT(do_draw(bool)));
438 connect(hRunEmu, SIGNAL(quit_draw_thread()), hDrawEmu, SLOT(doExit()));
440 connect(glv, SIGNAL(sig_notify_move_mouse(double, double, double, double)),
441 hRunEmu, SLOT(do_move_mouse(double, double, double, double)), Qt::QueuedConnection);
442 connect(glv, SIGNAL(do_notify_button_pressed(Qt::MouseButton)),
443 hRunEmu, SLOT(do_press_button_mouse(Qt::MouseButton)));
444 connect(glv, SIGNAL(do_notify_button_released(Qt::MouseButton)),
445 hRunEmu, SLOT(do_release_button_mouse(Qt::MouseButton)));
447 connect(actionCapture_Screen, SIGNAL(triggered()), glv, SLOT(do_save_frame_screen()));
448 connect(this, SIGNAL(sig_emu_launched()), glv, SLOT(set_emu_launched()));
451 connect(glv, SIGNAL(sig_toggle_mouse(void)),
452 this, SLOT(do_toggle_mouse(void)), Qt::QueuedConnection);
453 connect(glv, SIGNAL(sig_toggle_grab_mouse()), this, SLOT(do_toggle_mouse()), Qt::QueuedConnection);
455 connect(hRunEmu, SIGNAL(sig_resize_screen(int, int)),
456 glv, SLOT(resizeGL(int, int)), Qt::QueuedConnection);
457 connect(hRunEmu, SIGNAL(sig_resize_osd(int)), driveData, SLOT(setScreenWidth(int)), Qt::QueuedConnection);
458 connect(hRunEmu, SIGNAL(sig_change_osd(int, int, QString)), driveData, SLOT(updateMessage(int, int, QString)), Qt::QueuedConnection);
460 connect(glv, SIGNAL(sig_resize_uibar(int, int)),
461 this, SLOT(resize_statusbar(int, int)), Qt::QueuedConnection);
462 connect(hRunEmu, SIGNAL(sig_resize_uibar(int, int)),
463 this, SLOT(resize_statusbar(int, int)), Qt::QueuedConnection);
465 connect((OSD*)p_osd, SIGNAL(sig_req_encueue_video(int, int, int)),
466 hDrawEmu, SLOT(do_req_encueue_video(int, int, int)));
468 objNameStr = QString("EmuDrawThread");
469 hDrawEmu->setObjectName(objNameStr);
471 csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "DrawThread : Launch done.");
473 hSaveMovieThread = new MOVIE_SAVER(640, 400, 30, (OSD*)p_osd, &config);
476 // connect(this, SIGNAL(sig_start_saving_movie()), hRunEmu, SLOT(do_start_record_video()));
477 connect(actionStart_Record_Movie, SIGNAL(triggered()), hRunEmu, SLOT(do_start_record_video()));
478 connect(actionStop_Record_Movie, SIGNAL(triggered()), hRunEmu, SLOT(do_stop_record_video()));
480 connect(hSaveMovieThread, SIGNAL(sig_set_state_saving_movie(bool)), this, SLOT(do_set_state_saving_movie(bool)));
482 connect((OSD*)p_osd, SIGNAL(sig_save_as_movie(QString, int, int)),
483 hSaveMovieThread, SLOT(do_open(QString, int, int)));
484 connect((OSD*)p_osd, SIGNAL(sig_stop_saving_movie()), hSaveMovieThread, SLOT(do_close()));
486 actionStop_Record_Movie->setIcon(QIcon(":/icon_process_stop.png"));
487 actionStop_Record_Movie->setVisible(false);
489 connect(this, SIGNAL(sig_movie_set_width(int)), hSaveMovieThread, SLOT(do_set_width(int)));
490 connect(this, SIGNAL(sig_movie_set_height(int)), hSaveMovieThread, SLOT(do_set_height(int)));
492 connect((OSD*)p_osd, SIGNAL(sig_movie_set_width(int)), hSaveMovieThread, SLOT(do_set_width(int)));
493 connect((OSD*)p_osd, SIGNAL(sig_movie_set_height(int)), hSaveMovieThread, SLOT(do_set_height(int)));
495 connect((OSD*)p_osd, SIGNAL(sig_enqueue_audio(int16_t*, int)), hSaveMovieThread, SLOT(enqueue_audio(int16_t *, int)));
496 connect((OSD*)p_osd, SIGNAL(sig_enqueue_video(int, int, int, QImage *)),
497 hSaveMovieThread, SLOT(enqueue_video(int, int, int, QImage *)), Qt::DirectConnection);
498 connect(glv->extfunc, SIGNAL(sig_push_image_to_movie(int, int, int, QImage *)),
499 hSaveMovieThread, SLOT(enqueue_video(int, int, int, QImage *)));
500 connect(this, SIGNAL(sig_quit_movie_thread()), hSaveMovieThread, SLOT(do_exit()));
502 objNameStr = QString("EmuMovieThread");
503 hSaveMovieThread->setObjectName(objNameStr);
504 hSaveMovieThread->start();
505 csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "MovieThread : Launch done.");
507 connect(action_SetupMovie, SIGNAL(triggered()), this, SLOT(rise_movie_dialog()));
508 connect(hRunEmu, SIGNAL(sig_change_access_lamp(int, int, QString)), driveData, SLOT(updateLabel(int, int, QString)), Qt::QueuedConnection);
509 connect(hRunEmu, SIGNAL(sig_set_access_lamp(int, bool)), graphicsView, SLOT(do_display_osd_leds(int, bool)), Qt::QueuedConnection);
510 connect(hRunEmu, SIGNAL(sig_change_virtual_media(int, int, QString)), driveData, SLOT(updateMediaFileName(int, int, QString)), Qt::QueuedConnection);
511 connect((OSD*)p_osd, SIGNAL(sig_change_virtual_media(int, int, QString)), driveData, SLOT(updateMediaFileName(int, int, QString)));
512 connect((OSD*)p_osd, SIGNAL(sig_enable_mouse()), glv, SLOT(do_enable_mouse()));
513 connect((OSD*)p_osd, SIGNAL(sig_disable_mouse()), glv, SLOT(do_disable_mouse()));
515 connect(this, SIGNAL(sig_unblock_task()), hRunEmu, SLOT(do_unblock()));
516 connect(this, SIGNAL(sig_block_task()), hRunEmu, SLOT(do_block()));
517 connect(this, SIGNAL(sig_start_emu_thread()), hRunEmu, SLOT(do_start_emu_thread()));
518 connect(this, SIGNAL(sig_start_draw_thread()), hDrawEmu, SLOT(do_start_draw_thread()));
521 // hRunEmu->start(QThread::HighestPriority);
522 this->set_screen_aspect(config.window_stretch_type);
523 emit sig_movie_set_width(SCREEN_WIDTH);
524 emit sig_movie_set_height(SCREEN_HEIGHT);
525 // hRunEmu->start(QThread::HighestPriority);
526 csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "EmuThread : Launch done.");
529 void Ui_MainWindow::do_create_d88_media(int drv, quint8 media_type, QString name)
531 if(hRunEmu == nullptr) return;
532 EMU_TEMPLATE *p_emu = hRunEmu->get_emu();
533 if(p_emu == nullptr) return;
535 if(!(name.isEmpty()) && (drv >= 0)) {
536 #if defined(USE_FLOPPY_DISK)
537 if(drv < USE_FLOPPY_DISK) {
538 const _TCHAR* path = (const _TCHAR *)(name.toLocal8Bit().data());
539 if(p_emu->create_blank_floppy_disk(path, media_type)) {
540 emit sig_open_floppy_disk(drv, name, 0);
547 void Ui_MainWindow::do_create_hard_disk(int drv, int sector_size, int sectors, int surfaces, int cylinders, QString name)
549 if(hRunEmu == nullptr) return;
550 EMU_TEMPLATE *p_emu = hRunEmu->get_emu();
551 if(p_emu == nullptr) return;
553 if(!(name.isEmpty()) && (drv >= 0)) {
554 #if defined(USE_HARD_DISK)
555 if(drv < USE_HARD_DISK) {
556 const _TCHAR* path = (const _TCHAR *)(name.toLocal8Bit().data());
557 if(p_emu->create_blank_hard_disk(path, sector_size, sectors, surfaces, cylinders)) {
558 emit sig_open_hard_disk(drv, name);
565 void Ui_MainWindow::LaunchJoyThread(void)
567 #if defined(USE_JOYSTICK)
568 if(hRunEmu == nullptr) return;
569 EMU_TEMPLATE *p_emu = hRunEmu->get_emu();
570 if(p_emu == nullptr) return;
572 hRunJoy = new JoyThreadClass(p_emu, using_flags, &config);
573 connect(this, SIGNAL(quit_joy_thread()), hRunJoy, SLOT(doExit()));
574 connect(hRunJoy, SIGNAL(finished()), hRunJoy, SLOT(deleteLater()));
576 hRunJoy->setObjectName("JoyThread");
581 void Ui_MainWindow::StopJoyThread(void)
583 #if defined(USE_JOYSTICK)
584 emit quit_joy_thread();
588 void Ui_MainWindow::delete_joy_thread(void)
590 // delete hRunJoyThread;
594 void Ui_MainWindow::on_actionExit_triggered()
596 OnMainWindowClosed();
599 void Ui_MainWindow::OnWindowRedraw(void)
601 if(hRunEmu == nullptr) return;
602 EMU_TEMPLATE *p_emu = hRunEmu->get_emu();
603 if(p_emu == nullptr) return;
605 //emu->update_screen();
609 void Ui_MainWindow::OnWindowMove(void)
611 if(hRunEmu == nullptr) return;
612 EMU_TEMPLATE *p_emu = hRunEmu->get_emu();
613 if(p_emu == nullptr) return;
624 void Ui_MainWindow::OnMainWindowClosed(void)
627 emit sig_notify_power_off();
628 if(statusUpdateTimer != NULL) statusUpdateTimer->stop();
629 #if defined(USE_KEY_LOCKED) || defined(USE_LED_DEVICE)
630 if(ledUpdateTimer != NULL) ledUpdateTimer->stop();
632 emit quit_draw_thread();
633 emit quit_joy_thread();
634 emit sig_quit_emu_thread();
635 emit sig_quit_movie_thread();
636 emit sig_quit_widgets();
638 if(hSaveMovieThread != nullptr) {
639 // When recording movie, stopping will spend a lot of seconds.
640 if(!(hSaveMovieThread->wait(60 * 1000))) { // 60 Sec
641 hSaveMovieThread->terminate();
642 QThread::msleep(1000);
644 delete hSaveMovieThread;
645 hSaveMovieThread = NULL;
648 // if(hDrawEmu != nullptr) {
649 // if(!(hDrawEmu->wait(1000))) {
650 // hDrawEmu->terminate();
653 // hDrawEmu = nullptr;
655 if(hRunEmu != nullptr) {
657 if(hRunEmu->get_emu() != nullptr) {
658 OSD* op = (OSD*)(hRunEmu->get_emu()->get_osd());
661 op->moveToThread(this->thread());
665 if(!(hRunEmu->wait(2000))) {
666 hRunEmu->terminate();
667 QThread::msleep(100);
672 save_config(create_local_path(_T("%s.ini"), _T(CONFIG_NAME)));
675 char tmps[128] = {0};
676 std::string localstr;
677 //snprintf(tmps, sizeof(tmps), _T("%s.ini"), _T(CONFIG_NAME));
678 my_stprintf_s(tmps, sizeof(tmps) - 1, _T("%s.ini"), _T(CONFIG_NAME));
680 localstr = cpp_confdir + localstr;
681 save_config(localstr.c_str());
685 #if defined(USE_JOYSTICK)
686 // if(hRunJoy != nullptr) {
687 // if(!(hRunJoy->wait(1000))) {
688 // hRunJoy->terminate();
691 // hRunJoy = nullptr;
694 // do_release_emu_resources();
702 void Ui_MainWindow::do_release_emu_resources(void)
704 emit sig_quit_emu_thread();
707 extern void DLL_PREFIX_I get_long_full_path_name(_TCHAR* src, _TCHAR* dst);
708 extern _TCHAR* DLL_PREFIX_I get_parent_dir(_TCHAR* file);
709 extern void get_short_filename(_TCHAR *dst, _TCHAR *file, int maxlen);
711 #if defined(Q_OS_CYGWIN)
712 #include <sys/stat.h>
714 static void my_util_mkdir(std::string n)
716 #if !defined(Q_OS_CYGWIN)
717 QDir dir = QDir::current();
718 dir.mkdir( QString::fromStdString(n));
721 if(stat(n.c_str(), &st) != 0) {
722 _mkdir(n.c_str()); // Not found
727 static void setup_logs(void)
733 my_procname = my_procname + CONFIG_NAME;
734 #if defined(Q_OS_WIN)
739 #if !defined(Q_OS_WIN)
740 p = SDL_getenv("HOME");
742 p = SDL_getenv("PWD");
749 tmpstr = "Warning : Can't get HOME directory...Making conf on " + cpp_homedir + delim;
750 perror(tmpstr.c_str());
757 cpp_homedir = cpp_homedir + delim;
759 #if !defined(CSP_OS_WINDOWS)
760 cpp_confdir = cpp_homedir + ".config" + delim;
761 my_util_mkdir(cpp_confdir);
763 cpp_confdir = cpp_homedir;
766 cpp_confdir = cpp_confdir + "CommonSourceCodeProject" + delim;
767 my_util_mkdir(cpp_confdir);
769 cpp_confdir = cpp_confdir + my_procname + delim;
770 my_util_mkdir(cpp_confdir);
771 //AG_MkPath(cpp_confdir.c_str());
774 #if defined(_USE_AGAR) || defined(_USE_QT)
775 sRssDir = "/usr/local/share/";
777 sRssDir = "." + delim;
779 sRssDir = sRssDir + "CommonSourceCodeProject" + delim + my_procname;
785 extern QProcessEnvironment _envvars;
786 extern bool _b_dump_envvar;
787 extern std::string config_fullpath;
790 extern DLL_PREFIX QList<QCommandLineOption> SetOptions_Sub(QCommandLineParser *parser);
792 QCommandLineOption SetOptionsList(unsigned int drive, QStringList src, const QString desc, const QString name, const QString defaultValue)
796 QString _apd = QString::number(drive);
797 for(auto _n = src.begin(); _n != src.end(); ++_n) {
798 new_s.append((*_n) + _apd);
800 QCommandLineOption dst(new_s, desc, name, defaultValue);
804 QList<QCommandLineOption> SetOptions(QCommandLineParser *cmdparser, QStringList& aliases)
806 QString emudesc = QString::fromUtf8("Emulator for ");
807 emudesc = emudesc + QString::fromUtf8(DEVICE_NAME);
808 cmdparser->setApplicationDescription(emudesc);
809 cmdparser->addHelpOption();
810 //cmdparser->addVersionOption();
813 QList<QCommandLineOption> _ret;
815 SetOptions_Sub(cmdparser);
818 const QString _alias_bin = (const QString)(QString::fromUtf8("vBinary"));
819 const QString _alias_sbin = (const QString)(QString::fromUtf8("vSaveBinary"));
820 const QString _alias_bubble = (const QString)(QString::fromUtf8("vBubble"));
821 const QString _alias_cd = (const QString)(QString::fromUtf8("vCompactDisc"));
822 const QString _alias_cart = (const QString)(QString::fromUtf8("vCart"));
823 const QString _alias_fdd = (const QString)(QString::fromUtf8("vFloppy"));
824 const QString _alias_hdd = (const QString)(QString::fromUtf8("vHardDisk"));
825 const QString _alias_ld = (const QString)(QString::fromUtf8("vLaserDisc"));
826 const QString _alias_qd = (const QString)(QString::fromUtf8("vQuickDisk"));
827 const QString _alias_tape = (const QString)(QString::fromUtf8("vTape"));
828 const QString _alias_stape = (const QString)(QString::fromUtf8("vSaveCMT"));
830 const QStringList _bin_list = {"bin", "vBinary", "vBIN"};
831 const QStringList _save_bin_list = {"sbin", "vSaveBinary", "vSBIN"};
832 const QStringList _bubble_list = {"bub", "vBubble", "vBUB"};
833 const QStringList _cart_list = {"cart", "vCartridge", "vCart", "vCART"};
834 const QStringList _cd_list = {"cd", "vCompactDisc", "vCd", "vCD"};
835 const QStringList _fdd_list = {"fd", "vFd", "vFloppy", "vFloppyDisk", "vFloppyDrive", "vFD", "vFDD"};
836 const QStringList _hdd_list = {"hd", "vHardDisk", "vHardDrive", "vHD", "vHDD"};
837 const QStringList _ld_list = {"ld", "vLaserDisc", "vLd", "vLD"};
838 const QStringList _qd_list = {"qd", "vQuickDisk", "vQd", "vQD"};
839 const QStringList _tape_list = {"tape", "vTape", "vCasette", "vCMT"};
840 const QStringList _save_tape_list = {"scmt", "vSaveTape", "vSaveCMT", "vSCMT"};
842 #if defined(USE_BINARY_FILE)
843 for(unsigned int i = 0; i < USE_BINARY_FILE; i++) {
844 QString _alias = _alias_bin;
845 _alias.append(QString::fromUtf8("%1").arg(i));
846 aliases.append(_alias);
848 QCommandLineOption _l =
849 SetOptionsList(i, _bin_list,
850 QCoreApplication::translate("main", "Set virtual BINARY file for LOADING slot %1.").arg(i),
851 QCoreApplication::translate("main", "PATH"), QString::fromUtf8(""));
855 for(unsigned int i = 0; i < USE_BINARY_FILE; i++) {
856 QString _alias_s = _alias_sbin;
857 _alias_s.append(QString::fromUtf8("%1").arg(i));
858 aliases.append(_alias_s);
860 QCommandLineOption _ls =
861 SetOptionsList(i, _sbin_list,
862 QCoreApplication::translate("main", "Set virtual BINARY file for SAVING slot %1.").arg(i),
863 QCoreApplication::translate("main", "PATH"), QString::fromUtf8(""));
868 #if defined(USE_BUBBLE)
869 for(unsigned int i = 0; i < USE_BUBBLE; i++) {
870 QString _alias = _alias_bubble;
871 _alias.append(QString::fromUtf8("%1").arg(i));
872 aliases.append(_alias);
874 QCommandLineOption _l =
875 SetOptionsList(i, _bubble_list,
876 QCoreApplication::translate("main", "Set virtual BUBBLE CASETTE %1.").arg(i),
877 QCoreApplication::translate("main", "[W@|WP@][SLOT@]PATH"), QString::fromUtf8(""));
881 #if defined(USE_CART)
882 for(unsigned int i = 0; i < USE_CART; i++) {
883 QString _alias = _alias_cart;
884 _alias.append(QString::fromUtf8("%1").arg(i));
885 aliases.append(_alias);
887 QCommandLineOption _l =
888 SetOptionsList(i, _cart_list,
889 QCoreApplication::translate("main", "Set virtual ROM CARTRIDGE %1.").arg(i),
890 QCoreApplication::translate("main", "PATH"), QString::fromUtf8(""));
894 #if defined(USE_COMPACT_DISC)
895 for(unsigned int i = 0; i < USE_COMPACT_DISC; i++) {
896 QString _alias = _alias_cd;
897 _alias.append(QString::fromUtf8("%1").arg(i));
898 aliases.append(_alias);
900 QCommandLineOption _l =
901 SetOptionsList(i, _cd_list,
902 QCoreApplication::translate("main", "Set virtual COMPACT DISC %1 to FILE.").arg(i),
903 QCoreApplication::translate("main", "PATH"), QString::fromUtf8(""));
907 #if defined(USE_FLOPPY_DISK)
908 for(unsigned int i = 0; i < USE_FLOPPY_DISK; i++) {
909 QString _alias = _alias_fdd;
910 _alias.append(QString::fromUtf8("%1").arg(i));
911 aliases.append(_alias);
913 QCommandLineOption _l =
914 SetOptionsList(i, _fdd_list,
915 QCoreApplication::translate("main", "Set virtual FLOPPY DISK %1.").arg(i),
916 QCoreApplication::translate("main", "[W@|WP@][SLOT@]PATH"), QString::fromUtf8(""));
920 #if defined(USE_HARD_DISK)
921 for(unsigned int i = 0; i < USE_HARD_DISK; i++) {
922 QString _alias = _alias_hdd;
923 _alias.append(QString::fromUtf8("%1").arg(i));
924 aliases.append(_alias);
926 QCommandLineOption _l =
927 SetOptionsList(i, _hdd_list,
928 QCoreApplication::translate("main", "Set virtual HARD DISK DRIVE %1 .").arg(i),
929 QCoreApplication::translate("main", "PATH"), QString::fromUtf8(""));
933 #if defined(USE_LASER_DISC)
934 // ToDo: Fix working around LASER DISC correctly. 20230224 K.O.
935 for(unsigned int i = 0; i < USE_LASER_DISC; i++) {
936 QString _alias = _alias_ld;
937 _alias.append(QString::fromUtf8("%1").arg(i));
938 aliases.append(_alias);
940 QCommandLineOption _l =
941 SetOptionsList(i, _ld_list,
942 QCoreApplication::translate("main", "Set virtual LASER DISC %1.").arg(i),
943 QCoreApplication::translate("main", "PATH"), QString::fromUtf8(""));
947 #if defined(USE_QUICK_DISK)
948 for(unsigned int i = 0; i < USE_QUICK_DISK; i++) {
949 QString _alias = _alias_qd;
950 _alias.append(QString::fromUtf8("%1").arg(i));
951 aliases.append(_alias);
953 QCommandLineOption _l =
954 SetOptionsList(i, _qd_list,
955 QCoreApplication::translate("main", "Set virtual QUICK DISK %1"),
956 QCoreApplication::translate("main", "[W@|WP@][SLOT@]PATH"), QString::fromUtf8(""));
961 #if defined(USE_TAPE)
962 for(unsigned int i = 0; i < USE_TAPE; i++) {
963 QString _alias = _alias_tape;
964 _alias.append(QString::fromUtf8("%1").arg(i));
965 aliases.append(_alias);
967 QCommandLineOption _l =
968 SetOptionsList(i, _tape_list,
969 QCoreApplication::translate("main", "Set virtual CASETTE TAPE %1 for loading.").arg(i),
970 QCoreApplication::translate("main", "PATH"), QString::fromUtf8(""));
973 for(unsigned int i = 0; i < USE_TAPE; i++) {
974 QString _alias = _alias_stape;
975 _alias.append(QString::fromUtf8("%1").arg(i));
976 aliases.append(_alias);
978 QCommandLineOption _l =
979 SetOptionsList(i, _save_tape_list,
980 QCoreApplication::translate("main", "Set virtual CASETTE TAPE %1 for SAVING.").arg(i),
981 QCoreApplication::translate("main", "[W@|WP@][SLOT@]PATH"), QString::fromUtf8(""));
986 if(cmdparser != nullptr) {
987 cmdparser->addOptions(_ret);
993 extern void ProcessCmdLine_Sub(QCommandLineParser *cmdparser);
995 void ProcessCmdLine(QCommandLineParser *cmdparser, const QStringList vmedialist, QMap<QString, QString>& dstlist)
997 char homedir[_MAX_PATH] = {0};
999 #if defined(Q_OS_WIN)
1004 ProcessCmdLine_Sub(cmdparser);
1006 char tmps[128] = {0};
1007 std::string localstr;
1008 if(cmdparser->isSet("cfgfile")) {
1009 strncpy(tmps, cmdparser->value("cfgfile").toLocal8Bit().constData(), 127);
1011 if(strlen(tmps) <= 0){
1012 my_stprintf_s(tmps, sizeof(tmps) - 1, _T("%s.ini"), _T(CONFIG_NAME));
1015 localstr = cpp_confdir + localstr;
1016 load_config(localstr.c_str());
1017 config_fullpath = localstr;
1019 QString rendervalue = QString::fromUtf8("");
1020 const QStringList fixedGLList = {"gl2", "gl3", "gl4", "gl43", "gl46", "gles2", "gles3" };
1021 for(auto _gl = fixedGLList.begin(); _gl != fixedGLList.end(); ++_gl) {
1022 if(cmdparser->isSet((*_gl))) {
1023 rendervalue = (*_gl);
1027 const QStringList fixedGLList_v2 = { "gl2", "glv2", "v2", "2", "openglv2" };
1028 const QStringList fixedGLList_v3 = { "gl3", "glv3", "v3", "3", "openglv3", "opengl", "gl" };
1029 const QStringList fixedGLList_v4 = { "gl4", "glv4", "4", "openglv4"};
1030 const QStringList fixedGLList_v43 = { "gl43", "glv43", "openglv43" "gl4_3", "4.3", "4_3"};
1031 const QStringList fixedGLList_v46 = { "gl46", "glv46", "openglv46" "gl4_6", "4.6", "4_6"};
1032 const QStringList fixedGLList_es2 = { "gles2", "glesv2", "gles", "es2", "esv2", "es" };
1033 const QStringList fixedGLList_es3 = { "gles3", "glesv3", "esv3", "es3" };
1034 if(rendervalue.isEmpty()) {
1035 QString tmps = cmdparser->value("render");
1036 if(fixedGLList_v2.contains(tmps, Qt::CaseInsensitive)) {
1037 rendervalue = QString::fromUtf8("gl2");
1038 } else if(fixedGLList_v3.contains(tmps, Qt::CaseInsensitive)) {
1039 rendervalue = QString::fromUtf8("gl3");
1040 } else if(fixedGLList_v4.contains(tmps, Qt::CaseInsensitive)) {
1041 rendervalue = QString::fromUtf8("gl4");
1042 } else if(fixedGLList_v43.contains(tmps, Qt::CaseInsensitive)) {
1043 rendervalue = QString::fromUtf8("gl43");
1044 } else if(fixedGLList_v46.contains(tmps, Qt::CaseInsensitive)) {
1045 rendervalue = QString::fromUtf8("gl46");
1046 } else if(fixedGLList_es2.contains(tmps, Qt::CaseInsensitive)) {
1047 rendervalue = QString::fromUtf8("gles2");
1048 } else if(fixedGLList_es3.contains(tmps, Qt::CaseInsensitive)) {
1049 rendervalue = QString::fromUtf8("gles3");
1051 rendervalue = tmps.toLower();
1054 typedef struct x_s {
1059 QMap <QString, x_t> _glmap;
1060 _glmap.insert(QString::fromUtf8("gl2"), {CONFIG_RENDER_PLATFORM_OPENGL_MAIN, 2, 0});
1061 _glmap.insert(QString::fromUtf8("gl3"), {CONFIG_RENDER_PLATFORM_OPENGL_MAIN, 3, 0});
1062 _glmap.insert(QString::fromUtf8("gl4"), {CONFIG_RENDER_PLATFORM_OPENGL_CORE, 4, 3});
1063 _glmap.insert(QString::fromUtf8("gl43"), {CONFIG_RENDER_PLATFORM_OPENGL_CORE, 4, 3});
1064 _glmap.insert(QString::fromUtf8("gl46"), {CONFIG_RENDER_PLATFORM_OPENGL_CORE, 4, 6});
1065 _glmap.insert(QString::fromUtf8("gles2"), {CONFIG_RENDER_PLATFORM_OPENGL_ES, 2, 1});
1066 _glmap.insert(QString::fromUtf8("gles3"), {CONFIG_RENDER_PLATFORM_OPENGL_ES, 3, 0});
1068 x_t _t = {CONFIG_RENDER_PLATFORM_OPENGL_ES, 2, 1};
1069 if(_glmap.contains(rendervalue)) {
1070 _t = _glmap.value(rendervalue);
1072 config.render_platform = _t.type;
1073 config.render_major_version = _t.major;
1074 config.render_minor_version = _t.minor;
1076 switch(config.render_platform) {
1077 case CONFIG_RENDER_PLATFORM_OPENGL_MAIN:
1078 case CONFIG_RENDER_PLATFORM_OPENGL_CORE:
1079 QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL, true);
1080 QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, true); // Enable shared contexts.
1081 QCoreApplication::setAttribute(Qt::AA_UseOpenGLES, false);
1083 case CONFIG_RENDER_PLATFORM_OPENGL_ES:
1084 QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL, false);
1085 QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, true); // Enable shared contexts.
1086 QCoreApplication::setAttribute(Qt::AA_UseOpenGLES, true);
1088 default: // to GLES 2.1 as Default
1089 QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL, false);
1090 QCoreApplication::setAttribute(Qt::AA_UseOpenGLES, true);
1091 config.render_platform = CONFIG_RENDER_PLATFORM_OPENGL_ES;
1092 config.render_major_version = 2;
1093 config.render_minor_version = 1;
1098 uint32_t dipsw_onbits = 0x0000000;
1099 uint32_t dipsw_offmask = 0xffffffff;
1100 if(cmdparser->isSet("offbit")) {
1101 QStringList bitList = cmdparser->values("offbit");
1104 for(int i = 0; i < bitList.size(); i++) {
1106 int _bit = tv.toInt(&num_ok);
1108 if((_bit >= 0) && (_bit < 32)) {
1109 dipsw_offmask &= (uint32_t)(~(1 << _bit));
1114 if(cmdparser->isSet("onbit")) {
1115 QStringList bitList = cmdparser->values("onbit");
1118 for(int i = 0; i < bitList.size(); i++) {
1120 int _bit = tv.toInt(&num_ok);
1122 if((_bit >= 0) && (_bit < 32)) {
1123 dipsw_onbits |= (uint32_t)(1 << _bit);
1128 config.dipswitch &= dipsw_offmask;
1129 config.dipswitch |= dipsw_onbits;
1132 for(auto __l = vmedialist.begin(); __l != vmedialist.end(); ++__l) {
1133 if(cmdparser->isSet(*__l)) {
1134 QString tmps = *__l;
1135 if(!(tmps.isEmpty())) {
1136 dstlist.insert(tmps, cmdparser->value(tmps));
1142 void OpeningMessage(std::shared_ptr<CSP_Logger>p_logger, std::string archstr, const QMap<QString, QString> virtualMediaList)
1144 p_logger->set_emu_vm_name(DEVICE_NAME); // Write to syslog, console
1145 p_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Start Common Source Project '%s'", my_procname.c_str());
1146 p_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "(C) Toshiya Takeda / Qt Version K.Ohta");
1147 p_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Architecture: %s", archstr.c_str());
1148 p_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Use -h or --help for help.");
1150 //p_logger->debug_log(AGAR_LOG_INFO, " -? is print help(s).");
1151 p_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Home = %s, Resource directory = %s",
1152 cpp_homedir.c_str(),
1153 sRssDir.c_str()); // Debug
1155 p_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Config dir = %s, config_file = %s",
1156 cpp_confdir.c_str(),
1157 config_fullpath.c_str()); // Debug
1159 p_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "DIPSW VALUE IS 0x%08x", config.dipswitch);
1160 QList<QString> __keys = virtualMediaList.keys();
1161 for(auto __s = __keys.begin(); __s != __keys.end(); ++__s) {
1162 QString __val = virtualMediaList.value(*__s);
1163 p_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Virtual media :%s, name %s",
1164 (*__s).toLocal8Bit().constData(),
1165 __val.toLocal8Bit().constData());
1169 void SetupSDL(std::shared_ptr<CSP_Logger>p_logger)
1171 QStringList _el = _envvars.toStringList();
1173 if(_el.size() > 0) {
1174 for(int i = 0; i < _el.size(); i++) {
1175 QString _s = _el.at(i);
1176 if(_s.startsWith("SDL_")) {
1179 _nl = _s.indexOf('=');
1181 skey = _s.left(_nl);
1182 svar = _s.right(_s.length() - (_nl + 1));
1185 svar = QString::fromUtf8("");
1187 SDL_setenv(skey.toLocal8Bit().constData(), svar.toLocal8Bit().constData(), 1);
1188 p_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Note: SDL ENVIROMENT : %s to %s.",
1189 skey.toLocal8Bit().constData(),
1190 svar.toLocal8Bit().constData());
1194 #if defined(USE_SDL2)
1195 //SDL_Init(SDL_INIT_AUDIO | SDL_INIT_GAMECONTROLLER | SDL_INIT_JOYSTICK);
1196 SDL_Init(SDL_INIT_GAMECONTROLLER | SDL_INIT_JOYSTICK);
1197 //SDL_Init(SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER | SDL_INIT_JOYSTICK | SDL_INIT_EVENTS);
1199 SDL_Init(SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_VIDEO);
1201 p_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Audio subsystem was initialised.");
1204 extern void DLL_PREFIX_I set_debug_logger(std::shared_ptr<CSP_Logger> p);
1206 void SetupLogger(std::shared_ptr<CSP_Logger> csp_logger, QObject *parent, std::string emustr, int _size)
1209 csp_logger->set_emu_vm_name((const char *)(emustr.c_str()));
1210 csp_logger->set_log_stdout(CSP_LOG_DEBUG, true);
1211 csp_logger->set_log_stdout(CSP_LOG_INFO, true);
1212 csp_logger->set_log_stdout(CSP_LOG_WARN, true);
1214 csp_logger->set_state_log(0, config.state_log_to_recording);
1215 csp_logger->set_state_log(1, config.state_log_to_syslog);
1216 csp_logger->set_state_log(2, config.state_log_to_console);
1218 for(int ii = 0; ii < _size; ii++) {
1219 for(int jj = 0; jj < 8; jj++) {
1220 csp_logger->set_device_node_log(ii, 1, jj, config.dev_log_to_syslog[ii][jj]);
1221 csp_logger->set_device_node_log(ii, 2, jj, config.dev_log_to_console[ii][jj]);
1222 csp_logger->set_device_node_log(ii, 0, jj, config.dev_log_recording[ii][jj]);
1227 int MainLoop(int argc, char *argv[])
1230 std::string archstr;
1231 std::string emustr("emu");
1232 std::string cfgstr(CONFIG_NAME);
1237 #if defined(Q_OS_WIN)
1243 QApplication *GuiMain = NULL;
1244 GuiMain = new QApplication(argc, argv);
1245 GuiMain->setObjectName(QString::fromUtf8("Gui_Main"));
1246 QCommandLineParser cmdparser;
1247 QStringList vmedia_aliases;
1249 vmedia_aliases.clear();
1250 SetOptions(&cmdparser, vmedia_aliases);
1252 QStringList arglist;
1254 for(int i = 0; i < argc; i++) {
1255 if(argv[i] != NULL) {
1256 arglist.append(QString::fromLocal8Bit(argv[i]));
1260 archstr = "Generic";
1261 #if defined(__x86_64__)
1264 #if defined(__i386__)
1267 emustr = emustr + cfgstr;
1268 std::shared_ptr<USING_FLAGS> using_flags = std::shared_ptr<USING_FLAGS>(new USING_FLAGS_EXT(&config));
1269 cmdparser.process(arglist);
1271 QMap<QString, QString> virtualMediaList;
1272 virtualMediaList.clear();
1274 ProcessCmdLine(&cmdparser, (const QStringList)vmedia_aliases, virtualMediaList);
1276 _envvars = QProcessEnvironment::systemEnvironment();
1278 std::shared_ptr<CSP_Logger>p_logger = std::shared_ptr<CSP_Logger>(new CSP_Logger(GuiMain, config.log_to_syslog, config.log_to_console, emustr.c_str()));
1279 set_debug_logger(p_logger);
1280 SetupLogger(p_logger, GuiMain, emustr, CSP_LOG_TYPE_VM_DEVICE_END - CSP_LOG_TYPE_VM_DEVICE_0 + 1);
1281 OpeningMessage(p_logger, archstr, (const QMap<QString, QString>)virtualMediaList);
1288 //SetupTranslators();
1289 QTranslator local_translator;
1290 QLocale s_locale = QLocale::system();
1292 if(local_translator.load(s_locale, "machine", ".", ":/", ".qm")) {
1293 GuiMain->installTranslator(&local_translator);
1295 QTranslator s_translator;
1296 if(s_translator.load(s_locale, "gui", ".", ":/", ".qm")) {
1297 GuiMain->installTranslator(&s_translator);
1300 QTranslator common_translator;
1301 if(common_translator.load(s_locale, "common", ".", ":/", ".qm")) {
1302 GuiMain->installTranslator(&common_translator);
1304 QTranslator debugger_translator;
1305 if(debugger_translator.load(s_locale, "debugger", ".", ":/", ".qm")) {
1306 GuiMain->installTranslator(&debugger_translator);
1308 //QProcessEnvironment::systemEnvironment() = _envvars;
1309 if(_b_dump_envvar) {
1310 //QProcessEnvironment ev = QProcessEnvironment::systemEnvironment();
1311 QProcessEnvironment ev = _envvars;
1312 QStringList el = _envvars.toStringList();
1314 p_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "Environment Variables:");
1315 for(int i = 0; i < el.size(); i++) {
1316 p_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "#%d : %s", i, el.at(i).toLocal8Bit().constData());
1321 // USING_FLAGS_EXT *using_flags = new USING_FLAGS_EXT(&config);
1322 // initialize emulation core
1323 rMainWindow = new META_MainWindow(using_flags, p_logger);
1324 rMainWindow->connect(rMainWindow, SIGNAL(sig_quit_all(void)), rMainWindow, SLOT(deleteLater(void)));
1325 rMainWindow->setCoreApplication(GuiMain);
1326 rMainWindow->getWindow()->show();
1327 rMainWindow->retranselateUi_Depended_OSD();
1328 // QMetaObject::connectSlotsByName(rMainWindow);
1329 EmuThreadClass *hRunEmu_Real = new EmuThreadClass(rMainWindow, using_flags);
1330 hRunEmu_Real->setVirtualMediaList((const QMap<QString, QString>)virtualMediaList);
1332 OSD_BASE* p_osd = hRunEmu_Real->get_emu()->get_osd();
1334 QObject::connect((OSD*)p_osd, SIGNAL(sig_update_device_node_name(int, const _TCHAR *)),
1335 rMainWindow, SLOT(do_update_device_node_name(int, const _TCHAR *)));
1336 for(int i = 0; i < (CSP_LOG_TYPE_VM_DEVICE_END - CSP_LOG_TYPE_VM_DEVICE_0 + 1); i++) {
1337 rMainWindow->do_update_device_node_name(i, using_flags->get_vm_node_name(i));
1339 p_logger->set_osd((OSD*)p_osd);
1340 p_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "InitInstance() OK.");
1342 // ToDo: Update raltime.
1343 rMainWindow->connect(rMainWindow, SIGNAL(sig_osd_sound_output_device(QString)), (OSD*)p_osd, SLOT(do_set_host_sound_output_device(QString)));
1344 rMainWindow->do_update_sound_output_list();
1346 QObject::connect((OSD*)p_osd, SIGNAL(sig_update_sound_output_list()), rMainWindow, SLOT(do_update_sound_output_list()));
1347 QObject::connect((OSD*)p_osd, SIGNAL(sig_clear_sound_output_list()), rMainWindow, SLOT(do_clear_sound_output_list()));
1348 QObject::connect((OSD*)p_osd, SIGNAL(sig_append_sound_output_list(QString)), rMainWindow, SLOT(do_append_sound_output_list(QString)));
1350 QObject::connect(rMainWindow, SIGNAL(sig_update_master_volume(int)), (OSD*)p_osd, SLOT(do_update_master_volume(int)));
1352 QObject::connect(GuiMain, SIGNAL(lastWindowClosed()),
1353 rMainWindow, SLOT(on_actionExit_triggered()));
1355 QObject::connect((OSD*)p_osd, SIGNAL(sig_clear_keyname_table()), rMainWindow, SLOT(do_clear_keyname_table()));
1356 QObject::connect((OSD*)p_osd, SIGNAL(sig_add_keyname_table(uint32_t, QString)), rMainWindow, SLOT(do_add_keyname_table(uint32_t, QString)));
1357 p_osd->update_keyname_table();
1359 QObject::connect(rMainWindow, SIGNAL(sig_notify_power_off()), hRunEmu_Real, SLOT(do_notify_power_off()), Qt::QueuedConnection);
1361 GLDrawClass *pgl = rMainWindow->getGraphicsView();
1362 pgl->do_set_texture_size(NULL, -1, -1); // It's very ugly workaround (;_;) 20191028 K.Ohta
1363 // pgl->setFixedSize(pgl->width(), pgl->height());
1365 rMainWindow->LaunchEmuThread(hRunEmu_Real);
1367 #if defined(USE_JOYSTICK)
1368 rMainWindow->LaunchJoyThread();
1370 rMainWindow->do_start_emu_thread();
1371 rMainWindow->do_unblock_task();
1372 rMainWindow->do_start_draw_thread();
1379 #include <../debugger/qt_debugger.h>
1381 void Ui_MainWindow::OnOpenDebugger()
1383 QAction *cp = qobject_cast<QAction*>(QObject::sender());
1384 if(cp == nullptr) return;
1385 int no = cp->data().value<int>();
1387 if((no < 0) || (no >= MAX_CPU)) return;
1388 //emu->open_debugger(no);
1389 if(hRunEmu == nullptr) return;
1390 EMU_TEMPLATE *p_emu = hRunEmu->get_emu();
1392 VM *vm = static_cast<VM*>(p_emu->get_vm());
1394 // ToDo: Multiple debugger 20221105 K.O
1395 if((p_emu->now_debugging ) || (p_emu->hDebugger.get() != nullptr)) /* OnCloseDebugger(); */ return;
1397 if(!(p_emu->now_debugging && p_emu->debugger_thread_param.cpu_index == no)) {
1398 //p_emu->close_debugger();
1399 if(vm->get_cpu(no) != NULL && vm->get_cpu(no)->get_debugger() != NULL) {
1400 QString windowName = QString::fromUtf8(vm->get_cpu(no)->get_device_name());
1401 windowName = QString::fromUtf8("Debugger ") + windowName;
1402 p_emu->hDebugger.reset(new CSP_Debugger(p_emu, this));
1403 if(p_emu->hDebugger.get() == nullptr) {
1406 QString objNameStr = QString("EmuDebugThread");
1407 p_emu->hDebugger->setObjectName(objNameStr);
1409 p_emu->hDebugger->debugger_thread_param.osd = (OSD_BASE *)(p_emu->get_osd());
1410 p_emu->hDebugger->debugger_thread_param.emu = p_emu;
1411 p_emu->hDebugger->debugger_thread_param.vm = vm;
1412 p_emu->hDebugger->debugger_thread_param.cpu_index = no;
1413 p_emu->hDebugger->debugger_thread_param.running = false;
1414 p_emu->hDebugger->debugger_thread_param.request_terminate = false;
1416 p_emu->stop_record_sound();
1417 p_emu->stop_record_video();
1418 //p_emu->now_debugging = true;
1419 connect(this, SIGNAL(quit_debugger_thread()), p_emu->hDebugger.get(), SLOT(doExit()));
1420 connect(this, SIGNAL(destroyed()), p_emu->hDebugger.get(), SLOT(do_destroy_thread()));
1421 //connect(this, SIGNAL(quit_debugger_thread()), p_emu->hDebugger, SLOT(close()));
1422 connect(p_emu->hDebugger.get(), SIGNAL(sig_finished()), this, SLOT(OnCloseDebugger()));
1423 connect(p_emu->hDebugger.get(), SIGNAL(sig_put_string(QString)), p_emu->hDebugger.get(), SLOT(put_string(QString)));
1424 p_emu->hDebugger->show();
1425 p_emu->hDebugger->run();
1426 p_emu->hDebugger->setWindowTitle(windowName);
1431 void Ui_MainWindow::OnCloseDebugger(void )
1433 if(hRunEmu == nullptr) return;
1434 EMU_TEMPLATE *p_emu = hRunEmu->get_emu();
1435 if(p_emu == nullptr) {
1438 // p_emu->close_debugger();
1439 // ToDo: Multiple debugger 20221105 K.O
1440 if((p_emu->now_debugging) && (p_emu->hDebugger.get() != nullptr)) {
1441 if(p_emu->hDebugger->debugger_thread_param.running) {
1442 emit quit_debugger_thread();
1443 //if(!(p_emu->hDebugger->wait(2000))) {
1444 // p_emu->hDebugger->terminate();
1445 // QThread::msleep(100);
1449 p_emu->hDebugger.reset();
1450 p_emu->now_debugging = false;
1454 QString Ui_MainWindow::get_system_version()
1456 if(hRunEmu == nullptr) return QString::fromUtf8("");
1457 EMU_TEMPLATE *p_emu = hRunEmu->get_emu();
1459 QString guiver = get_gui_version();
1462 QString common_vmver;
1464 QString libcommon_ver;
1465 QString libfmgen_ver;
1471 common_vmver.clear();
1474 libcommon_ver.clear();
1476 if(hSaveMovieThread != NULL) {
1477 aviover = hSaveMovieThread->get_avio_version();
1480 if(p_emu != nullptr) {
1481 if(p_emu->get_osd() != NULL) {
1482 _TCHAR *cvp = (_TCHAR *)p_emu->get_osd()->get_lib_common_vm_version();
1483 _TCHAR *gvp = (_TCHAR *)p_emu->get_osd()->get_lib_common_vm_git_version();
1484 _TCHAR *ovp = (_TCHAR *)p_emu->get_osd()->get_lib_osd_version();
1486 common_vmver = QString::fromUtf8(cvp);
1489 vm_gitver = QString::fromUtf8(gvp);
1492 osdver = QString::fromUtf8(ovp);
1497 const _TCHAR *pp = get_lib_common_version();
1499 libcommon_ver = QString::fromUtf8(pp);
1501 libfmgen_ver = QString::fromUtf8(FM::get_libfmgen_version());
1504 outstr.append(QString::fromUtf8("<FONT SIZE=+1>"));
1505 if(!(common_vmver.isEmpty())) {
1506 outstr.append(common_vmver);
1507 outstr.append("<BR>\n");
1509 if(!(libcommon_ver.isEmpty())) {
1510 outstr.append(libcommon_ver);
1511 outstr.append("<BR>\n");
1513 if(!(osdver.isEmpty())) {
1514 outstr.append(osdver);
1515 outstr.append("<BR>\n");
1517 if(!(libfmgen_ver.isEmpty())) {
1518 outstr.append(libfmgen_ver);
1519 outstr.append("<BR>\n");
1521 if(!(osdver.isEmpty())) {
1522 outstr.append(osdver);
1523 outstr.append("<BR>\n");
1525 if(!(guiver.isEmpty())) {
1526 outstr.append(guiver);
1527 outstr.append("<BR>\n");
1529 if(!(aviover.isEmpty())) {
1530 outstr.append(aviover);
1531 outstr.append("<BR>\n");
1533 outstr.append(QString::fromUtf8("</FONT>"));
1534 if(!(vm_gitver.isEmpty())) {
1535 outstr.append("Build Version: ");
1536 outstr.append(vm_gitver);
1537 outstr.append("<BR>\n");
1542 QString Ui_MainWindow::get_build_date()
1544 #if defined(__BUILD_DATE)
1545 return QString::fromUtf8(__BUILD_DATE);
1547 return QString::fromUtf8("");