OSDN Git Service

[UI][Qt][EMU]Menu: Make around quick-disk new signal framework.
[csp-qt/common_source_project-fm7.git] / source / src / qt / gui / emu_thread_tmpl.cpp
1 /*
2         Skelton for retropc emulator
3         Author : Takeda.Toshiya
4     Port to Qt : K.Ohta <whatisthis.sowhat _at_ gmail.com>
5         Date   : 2015.11.10
6         History: 2015.11.10 Split from qt_main.cpp
7         Note: This class must be compiled per VM, must not integrate shared units.
8         [ win32 main ] -> [ Qt main ] -> [Emu Thread] -> [Independed from VMs]
9 */
10
11 #include <QString>
12 #include <QStringList>
13 #include <QFileInfo>
14 #include <QTextCodec>
15 #include <QWaitCondition>
16 #include <QWidget>
17 #include <QOpenGLContext>
18
19 #include <SDL.h>
20
21 #include "emu_thread_tmpl.h"
22 #include "mainwidget_base.h"
23 #include "qt_gldraw.h"
24 #include "common.h"
25 #include "dock_disks.h"
26
27 #include "./virtualfileslist.h"
28 #include "menu_metaclass.h"
29
30 //#include "../../romakana.h"
31
32 //#include "csp_logger.h"
33 #include "menu_flags.h"
34
35 EmuThreadClassBase::EmuThreadClassBase(Ui_MainWindowBase *rootWindow, std::shared_ptr<USING_FLAGS> p, QObject *parent) : QThread(parent) {
36         MainWindow = rootWindow;
37         bBlockTask = true;
38         using_flags = p;
39         p_config = p->get_config_ptr();
40         p_emu = nullptr;
41         p_osd = nullptr;
42         poweroff_notified = false; // OK?
43
44         is_shared_glcontext = false;
45         glContext = nullptr;
46         glContext = new QOpenGLContext(this);
47
48         if(glContext != nullptr) {
49                 glContext->setShareContext(rootWindow->getGraphicsView()->context());
50                 glContext->create();
51         }
52         if(glContext->isValid()) {
53                 is_shared_glcontext = true;
54 //              printf("Context sharing succeeded.ADDR=%08x GLES=%s\n", glContext, (glContext->isOpenGLES()) ? "YES" : "NO");
55         }
56
57         bRunThread = true;
58         thread_id = (Qt::HANDLE)0;
59         queue_fixed_cpu = -1;
60         prev_skip = false;
61         //tick_timer.start();
62         //update_fps_time = tick_timer.elapsed();
63         //next_time = update_fps_time;
64         total_frames = 0;
65         draw_frames = 0;
66         skip_frames = 0;
67         calc_message = true;
68         mouse_flag = false;
69         vMovieQueue.clear();
70
71         drawCond = new QWaitCondition();
72 //      keyMutex = new QMutex(QMutex::Recursive);
73
74         mouse_x = 0;
75         mouse_y = 0;
76         if(using_flags.get() != nullptr) {
77                 if(using_flags->is_use_tape() && !using_flags->is_tape_binary_only()) {
78                         tape_play_flag = false;
79                         tape_rec_flag = false;
80                         tape_pos = 0;
81                 }
82
83                 if(using_flags->get_use_sound_volume() > 0) {
84                         for(int i = 0; i < using_flags->get_use_sound_volume(); i++) {
85                                 bUpdateVolumeReq[i] = true;
86                                 volume_avg[i] = (p_config->sound_volume_l[i] +
87                                                                  p_config->sound_volume_r[i]) / 2;
88                                 volume_balance[i] = (p_config->sound_volume_r[i] -
89                                                                          p_config->sound_volume_l[i]) / 2;
90                         }
91                 }
92         }
93         QMutexLocker _n(&keyMutex);
94
95
96         key_fifo = new FIFO(512 * 6);
97         key_fifo->clear();
98
99
100 };
101
102 EmuThreadClassBase::~EmuThreadClassBase() {
103
104         delete drawCond;
105
106         key_fifo->release();
107         delete key_fifo;
108 };
109
110 void EmuThreadClassBase::calc_volume_from_balance(int num, int balance)
111 {
112         int level = volume_avg[num];
113         int right;
114         int left;
115         volume_balance[num] = balance;
116         right = level + balance;
117         left  = level - balance;
118         p_config->sound_volume_l[num] = left;
119         p_config->sound_volume_r[num] = right;
120 }
121
122 void EmuThreadClassBase::calc_volume_from_level(int num, int level)
123 {
124         int balance = volume_balance[num];
125         int right,left;
126         volume_avg[num] = level;
127         right = level + balance;
128         left  = level - balance;
129         p_config->sound_volume_l[num] = left;
130         p_config->sound_volume_r[num] = right;
131 }
132
133 void EmuThreadClassBase::doExit(void)
134 {
135         bRunThread = false;
136 }
137
138 void EmuThreadClassBase::button_pressed_mouse(Qt::MouseButton button)
139 {
140         if(using_flags.get() == nullptr) return;
141         if(using_flags->is_use_mouse()) {
142                 button_pressed_mouse_sub(button);
143         } else {
144                 if(using_flags->get_max_button() > 0) {
145                         button_desc_t *vm_buttons_d = using_flags->get_vm_buttons();
146                         if(vm_buttons_d == NULL) return;
147                         int _x = (int)rint(mouse_x);
148                         int _y = (int)rint(mouse_y);
149                         switch(button) {
150                         case Qt::LeftButton:
151 //                      case Qt::RightButton:
152                                 for(int i = 0; i < using_flags->get_max_button(); i++) {
153                                         if((_x >= vm_buttons_d[i].x) &&
154                                            (_x < (vm_buttons_d[i].x + vm_buttons_d[i].width))) {
155                                                 if((_y >= vm_buttons_d[i].y) &&
156                                                    (_y < (vm_buttons_d[i].y + vm_buttons_d[i].height))) {
157                                                         if(vm_buttons_d[i].code != 0x00) {
158                                                                 key_queue_t sp;
159                                                                 sp.code = vm_buttons_d[i].code;
160                                                                 sp.mod = key_mod;
161                                                                 sp.repeat = false;
162                                                                 enqueue_key_down(sp);
163                                                         } else {
164                                                                 bResetReq = true;
165                                                         }
166                                                 }
167                                         }
168                                 }
169                                 break;
170                         default:
171                                 break;
172                         }
173                 }
174         }
175 }
176
177 void EmuThreadClassBase::button_released_mouse(Qt::MouseButton button)
178 {
179         if(using_flags.get() == nullptr) return;
180         if(using_flags->is_use_mouse()) {
181                 button_released_mouse_sub(button);
182         } else {
183                 if(using_flags->get_max_button() > 0) {
184                         button_desc_t *vm_buttons_d = using_flags->get_vm_buttons();
185                         if(vm_buttons_d == NULL) return;
186                         int _x = (int)rint(mouse_x);
187                         int _y = (int)rint(mouse_y);
188                         switch(button) {
189                         case Qt::LeftButton:
190 //                      case Qt::RightButton:
191                                 for(int i = 0; i < using_flags->get_max_button(); i++) {
192                                         if((_x >= vm_buttons_d[i].x) &&
193                                            (_x < (vm_buttons_d[i].x + vm_buttons_d[i].width))) {
194                                                 if((_y >= vm_buttons_d[i].y) &&
195                                                    (_y < (vm_buttons_d[i].y + vm_buttons_d[i].height))) {
196                                                         if(vm_buttons_d[i].code != 0x00) {
197                                                                 key_queue_t sp;
198                                                                 sp.code = vm_buttons_d[i].code;
199                                                                 sp.mod = key_mod;
200                                                                 sp.repeat = false;
201                                                                 enqueue_key_up(sp);
202                                                         }
203                                                 }
204                                         }
205                                 }
206                                 break;
207                         default:
208                                 break;
209                         }
210                 }
211         }
212 }
213
214 // New UI
215 void EmuThreadClassBase::do_key_down(uint32_t vk, uint32_t mod, bool repeat)
216 {
217         key_queue_t sp;
218         sp.code = vk;
219         sp.mod = mod;
220         sp.repeat = repeat;
221         //key_changed = true;
222         enqueue_key_down(sp);
223         key_mod = mod;
224 }
225
226 void EmuThreadClassBase::do_key_up(uint32_t vk, uint32_t mod)
227 {
228         key_queue_t sp;
229         sp.code = vk;
230         sp.mod = mod;
231         sp.repeat = false;
232         enqueue_key_up(sp);
233         key_mod = mod;
234 }
235
236 void EmuThreadClassBase::set_tape_play(bool flag)
237 {
238         tape_play_flag = flag;
239 }
240
241 void EmuThreadClassBase::resize_screen(int screen_width, int screen_height, int stretched_width, int stretched_height)
242 {
243         emit sig_resize_screen(screen_width, screen_height);
244         emit sig_resize_osd(screen_width);
245 }
246
247 void EmuThreadClassBase::sample_access_drv(void)
248 {
249         if(using_flags.get() == nullptr) return;
250         if(using_flags->is_use_qd()) get_qd_string();
251         if(using_flags->is_use_fd()) get_fd_string();
252         if(using_flags->is_use_hdd()) get_hdd_string();
253         if(using_flags->is_use_tape() && !using_flags->is_tape_binary_only()) get_tape_string();
254         if(using_flags->is_use_compact_disc()) get_cd_string();
255         if(using_flags->is_use_bubble()) get_bubble_string();
256 }
257
258
259
260
261 void EmuThreadClassBase::do_update_config()
262 {
263         bUpdateConfigReq = true;
264 }
265
266 void EmuThreadClassBase::do_start_record_sound()
267 {
268         bStartRecordSoundReq = true;
269 }
270
271 void EmuThreadClassBase::do_stop_record_sound()
272 {
273         bStopRecordSoundReq = true;
274 }
275
276 void EmuThreadClassBase::do_reset()
277 {
278         bResetReq = true;
279 }
280
281 void EmuThreadClassBase::do_unblock()
282 {
283         bBlockTask = false;
284 }
285
286 void EmuThreadClassBase::do_block()
287 {
288         bBlockTask = true;
289 }
290 void EmuThreadClassBase::do_start_emu_thread()
291 {
292         start(QThread::TimeCriticalPriority);
293 }
294
295 void EmuThreadClassBase::do_special_reset(void)
296 {
297         QAction *cp = qobject_cast<QAction*>(QObject::sender());
298         if(cp == nullptr) return;
299         int num = cp->data().value<int>();
300
301         if(num < 0) return;
302         if(using_flags.get() != nullptr) {
303                 if(num >= using_flags->get_use_special_reset_num()) return;
304         }
305         bSpecialResetReq = true;
306         specialResetNum = num;
307 }
308
309 void EmuThreadClassBase::do_load_state(void)
310 {
311         QAction *cp = qobject_cast<QAction*>(QObject::sender());
312         if(cp == nullptr) return;
313         QString s = cp->data().toString();
314
315         lStateFile = s;
316         bLoadStateReq = true;
317 }
318
319 void EmuThreadClassBase::do_save_state(void)
320 {
321         QAction *cp = qobject_cast<QAction*>(QObject::sender());
322         if(cp == nullptr) return;
323         QString s = cp->data().toString();
324
325         sStateFile = s;
326         bSaveStateReq = true;
327 }
328
329 void EmuThreadClassBase::do_start_record_video()
330 {
331         if(p_config == nullptr) return;
332         int fps = p_config->video_frame_rate;
333         record_fps = fps;
334         bStartRecordMovieReq = true;
335 }
336
337 void EmuThreadClassBase::do_stop_record_video()
338 {
339         bStartRecordMovieReq = false;
340 }
341
342 void EmuThreadClassBase::do_update_volume_level(int num, int level)
343 {
344         if(using_flags.get() == nullptr) return;
345         if(using_flags->get_use_sound_volume() > 0) {
346                 if((num < using_flags->get_use_sound_volume()) && (num >= 0)) {
347                         calc_volume_from_level(num, level);
348                         bUpdateVolumeReq[num] = true;
349                 }
350         }
351 }
352
353 void EmuThreadClassBase::do_update_volume_balance(int num, int level)
354 {
355         if(using_flags.get() == nullptr) return;
356         if(using_flags->get_use_sound_volume() > 0) {
357                 if((num < using_flags->get_use_sound_volume()) && (num >= 0)) {
358                         calc_volume_from_balance(num, level);
359                         bUpdateVolumeReq[num] = true;
360                 }
361         }
362 }
363
364 int EmuThreadClassBase::parse_command_queue(QStringList _l, int _begin)
365 {
366         int _ret = _l.size() / 2;
367         for(int i = _begin * 2; i < _l.size(); i+= 2) {
368                 QString _dom = _l.at(i);
369                 QString _file = _l.at(i + 1);
370                 QString _dom_type = _dom.left(_dom.size() - 1);
371                 int _dom_num;
372                 bool _num_ok;
373                 _dom_num = _dom.right(1).toInt(&_num_ok);
374                 if(_num_ok) {
375                         if((_dom_type == QString::fromUtf8("vFloppyDisk")) ||
376                            (_dom_type == QString::fromUtf8("vBubble"))) {
377                                 int _n = _file.indexOf(QString::fromUtf8("@"));
378                                 int _slot = 0;
379                                 QFileInfo fileInfo;
380                                 if((_n > 0) && (_n < 4)) {
381                                         _slot = _file.left(_n).toInt(&_num_ok);
382                                         if(_num_ok) {
383                                                 fileInfo = QFileInfo(_file.right(_file.size() - (_n + 1)));
384                                         } else {
385                                                 fileInfo = QFileInfo(_file);
386                                                 _slot = 0;
387                                         }
388                                 } else {
389                                         fileInfo = QFileInfo(_file);
390                                         _slot = 0;
391                                 }
392                                 if(fileInfo.isFile()) {
393                                         const _TCHAR *path_shadow = (const _TCHAR *)(fileInfo.absoluteFilePath().toLocal8Bit().constData());
394                                         if(_dom_type == QString::fromUtf8("vFloppyDisk")) {
395                                                 if(check_file_extension(path_shadow, ".d88") || check_file_extension(path_shadow, ".d77")) {
396
397                                                         emit sig_change_virtual_media(CSP_DockDisks_Domain_FD, _dom_num, fileInfo.absoluteFilePath());;
398                                                 } else {
399                                                         emit sig_open_fd(_dom_num, fileInfo.absoluteFilePath());
400                                                         emit sig_change_virtual_media(CSP_DockDisks_Domain_FD, _dom_num, fileInfo.absoluteFilePath());;
401                                                 }
402                                         } else  if(_dom_type == QString::fromUtf8("vHardDisk")) {
403                                                 emit sig_open_hdd(_dom_num, fileInfo.absoluteFilePath());
404                                                 emit sig_change_virtual_media(CSP_DockDisks_Domain_HD, _dom_num, fileInfo.absoluteFilePath());;
405                                         } else if(_dom_type == QString::fromUtf8("vBubble")) {
406                                                 if(check_file_extension(path_shadow, ".b77")) {
407                                                         emit sig_open_b77_bubble(_dom_num, fileInfo.absoluteFilePath(), _slot);
408                                                         emit sig_change_virtual_media(CSP_DockDisks_Domain_Bubble, _dom_num, fileInfo.absoluteFilePath());;
409                                                 } else {
410                                                         emit sig_open_bubble(_dom_num, fileInfo.absoluteFilePath());
411                                                         emit sig_change_virtual_media(CSP_DockDisks_Domain_Bubble, _dom_num, fileInfo.absoluteFilePath());;
412                                                 }
413                                         }
414                                 }
415                         } else {
416                                 QFileInfo fileInfo = QFileInfo(_file);
417                                 if(fileInfo.isFile()) {
418                                         if(_dom_type == QString::fromUtf8("vQuickDisk")) {
419                                                 emit sig_open_quick_disk(_dom_num, fileInfo.absoluteFilePath());
420                                                 emit sig_change_virtual_media(CSP_DockDisks_Domain_QD, _dom_num, fileInfo.absoluteFilePath());;
421                                 } else if(_dom_type == QString::fromUtf8("vCmt")) {
422                                                 emit sig_open_cmt_load(_dom_num, fileInfo.absoluteFilePath());
423                                                 emit sig_change_virtual_media(CSP_DockDisks_Domain_CMT, _dom_num, fileInfo.absoluteFilePath());;
424                                         } else if(_dom_type == QString::fromUtf8("vBinary")) {
425                                                 emit sig_open_binary_load(_dom_num, fileInfo.absoluteFilePath());
426                                                 emit sig_change_virtual_media(CSP_DockDisks_Domain_Binary, _dom_num, fileInfo.absoluteFilePath());;
427                                         } else if(_dom_type == QString::fromUtf8("vCart")) {
428                                                 emit sig_open_cart(_dom_num, fileInfo.absoluteFilePath());
429                                                 emit sig_change_virtual_media(CSP_DockDisks_Domain_Cart, _dom_num, fileInfo.absoluteFilePath());;
430                                         } else if(_dom_type == QString::fromUtf8("vLD")) {
431                                                 vMovieQueue.append(_dom);
432                                                 vMovieQueue.append(fileInfo.absoluteFilePath());
433                                                 emit sig_change_virtual_media(CSP_DockDisks_Domain_LD, _dom_num, fileInfo.absoluteFilePath());;
434                                                 //emit sig_open_laser_disc(_dom_num, fileInfo.absoluteFilePath());
435                                         } else if(_dom_type == QString::fromUtf8("vCD")) {
436                                                 emit sig_open_cdrom(_dom_num, fileInfo.absoluteFilePath());
437                                                 emit sig_change_virtual_media(CSP_DockDisks_Domain_CD, _dom_num, fileInfo.absoluteFilePath());;
438                                         }
439                                 }
440                         }
441                 }
442         }
443         _ret = _ret - _begin;
444         if(_ret < 0) _ret = 0;
445         return _ret;
446 }
447
448
449 const _TCHAR *EmuThreadClassBase::get_device_name(void)
450 {
451         return (const _TCHAR *)_T("TEST");
452 }
453
454 void EmuThreadClassBase::print_framerate(int frames)
455 {
456         if(frames >= 0) draw_frames += frames;
457         if(calc_message) {
458                 qint64 current_time = tick_timer.elapsed();
459                 //qint64        current_time = SDL_GetTicks();
460
461                 if(update_fps_time <= current_time && update_fps_time != 0) {
462                         _TCHAR buf[256];
463                         QString message;
464                         //int ratio = (int)(100.0 * (double)draw_frames / (double)total_frames + 0.5);
465
466                         if((poweroff_notified) || (p_emu == nullptr)) {
467                                 my_stprintf_s(buf, 255, _T("*Power OFF*"));
468                         } else if(now_skip) {
469                                 int ratio = (int)(100.0 * (((double)total_frames / get_emu_frame_rate())  * 2.0) + 0.5);
470                                 my_stprintf_s(buf, 255, _T("%s - Skip Frames (%d %%)"), get_device_name(), ratio);
471                         } else {
472                                         if(get_message_count() > 0) {
473                                                 snprintf(buf, 255, _T("%s - %s"), get_device_name(), get_emu_message());
474                                                 dec_message_count();
475                                         } else {
476                                                 int ratio = (int)(100.0 * ((double)draw_frames / (double)total_frames) * 2.0 + 0.5);
477                                                 snprintf(buf, 255, _T("%s - %d fps (%d %%)"), get_device_name(), draw_frames, ratio);
478                                         }
479                                 }
480                                 if(p_config->romaji_to_kana) {
481                                         message = QString::fromUtf8("[R]");
482                                         message = message + QString::fromUtf8(buf);
483                                 } else {
484                                         message = buf;
485                                 }
486                                 emit message_changed(message);
487                                 emit window_title_changed(message);
488                                 update_fps_time += 1000;
489                                 total_frames = draw_frames = 0;
490
491                         }
492                         if(update_fps_time <= current_time) {
493                                 update_fps_time = current_time + 1000;
494                         }
495                         calc_message = false;
496                 } else {
497                         calc_message = true;
498                 }
499 }
500
501 int EmuThreadClassBase::get_d88_file_cur_bank(int drive)
502 {
503         std::shared_ptr<USING_FLAGS> p = using_flags;
504         if(p.get() == nullptr) return -1;
505         if(!(p->is_use_fd())) return -1;
506
507         if((drive < p->get_max_drive()) && (p_emu != nullptr)) {
508                 QMutexLocker _locker(&uiMutex);
509                 int bank_num = p_emu->d88_file[drive].bank_num;
510                 int cur_bank = p_emu->d88_file[drive].cur_bank;
511                 if((bank_num > 0) && (cur_bank < bank_num)) {
512                         return cur_bank;
513                 }
514         }
515
516         return -1;
517 }
518
519 int EmuThreadClassBase::get_d88_file_bank_num(int drive)
520 {
521         if(using_flags.get() == nullptr) return -1;
522         if(!(using_flags->is_use_fd())) return -1;
523
524         if(drive < using_flags->get_max_drive()) {
525                 QMutexLocker _locker(&uiMutex);
526                 return p_emu->d88_file[drive].bank_num;
527         }
528
529         return -1;
530 }
531
532
533 QString EmuThreadClassBase::get_d88_file_disk_name(int drive, int banknum)
534 {
535         if(using_flags.get() == nullptr) return QString::fromUtf8("");
536         if(!(using_flags->is_use_fd())) return QString::fromUtf8("");
537
538         if(drive < 0) return QString::fromUtf8("");
539         if((drive < using_flags->get_max_drive()) && (banknum < get_d88_file_bank_num(drive))) {
540                 QMutexLocker _locker(&uiMutex);
541                 QString _n = QString::fromLocal8Bit((const char *)(&(p_emu->d88_file[drive].disk_name[banknum][0])));
542                 return _n;
543         }
544
545         return QString::fromUtf8("");
546 }
547
548
549 bool EmuThreadClassBase::is_floppy_disk_protected(int drive)
550 {
551         if(using_flags.get() == nullptr) return false;
552         if(!(using_flags->is_use_fd())) return false;
553
554         QMutexLocker _locker(&uiMutex);
555         bool _b = p_emu->is_floppy_disk_protected(drive);
556         return _b;
557 }
558
559
560 QString EmuThreadClassBase::get_d88_file_path(int drive)
561 {
562         if(using_flags.get() == nullptr) return QString::fromUtf8("");
563
564         if(!(using_flags->is_use_fd())) return QString::fromUtf8("");
565         if(drive < 0) return QString::fromUtf8("");
566
567         if(drive < using_flags->get_max_drive()) {
568                 QMutexLocker _locker(&uiMutex);
569                 QString _n = QString::fromLocal8Bit((const char *)(&(p_emu->d88_file[drive].path)));
570                 return _n;
571         }
572
573         return QString::fromUtf8("");
574 }
575
576 void EmuThreadClassBase::set_floppy_disk_protected(int drive, bool flag)
577 {
578         if(using_flags.get() == nullptr) return;
579         if(!(using_flags->is_use_fd())) return;
580
581         QMutexLocker _locker(&uiMutex);
582         p_emu->is_floppy_disk_protected(drive, flag);
583
584 }
585 #if defined(Q_OS_LINUX)
586 //#define _GNU_SOURCE
587 #include <unistd.h>
588 #include <sched.h>
589 #include <pthread.h>
590 #endif
591
592 void EmuThreadClassBase::do_set_emu_thread_to_fixed_cpu_from_action(void)
593 {
594         QAction *cp = qobject_cast<QAction*>(QObject::sender());
595         if(cp == nullptr) return;
596         int cpunum = cp->data().value<int>();
597         set_emu_thread_to_fixed_cpu(cpunum);
598 }
599
600 void EmuThreadClassBase::set_emu_thread_to_fixed_cpu(int cpunum)
601 {
602 #if defined(Q_OS_LINUX)
603         if(thread_id == (Qt::HANDLE)nullptr) {
604                 queue_fixed_cpu = cpunum;
605                 return;
606         }
607
608         long cpus = sysconf(_SC_NPROCESSORS_ONLN);
609         cpu_set_t *mask;
610         mask = CPU_ALLOC(cpus);
611         CPU_ZERO_S(CPU_ALLOC_SIZE(cpus), mask);
612         if((cpunum < 0) || (cpunum >= cpus)) {
613                 for(int i = 0; i < cpus; i++ ) {
614                         CPU_SET(i, mask);
615                 }
616         } else {
617                 CPU_SET(cpunum, mask);
618         }
619 //      sched_setaffinity((pid_t)thread_id, CPU_ALLOC_SIZE(cpus), (const cpu_set_t*)mask);
620         pthread_setaffinity_np(*((pthread_t*)thread_id), CPU_ALLOC_SIZE(cpus),(const cpu_set_t *)mask);
621         CPU_FREE(mask);
622 #else
623         return;
624 #endif
625         return;
626 }
627
628 void EmuThreadClassBase::get_fd_string(void)
629 {
630         if(using_flags.get() == nullptr) return;
631         if(!(using_flags->is_use_fd())) return;
632         int i;
633         QString tmpstr;
634         QString iname;
635         QString alamp;
636         uint32_t access_drv = 0;
637         bool lamp_stat = false;
638         access_drv = p_emu->is_floppy_disk_accessed();
639         {
640                 for(i = 0; i < (int)using_flags->get_max_drive(); i++) {
641                         tmpstr.clear();
642                         alamp.clear();
643                         lamp_stat = false;
644                         if(p_emu->is_floppy_disk_inserted(i)) {
645                                 if(i == (access_drv - 1)) {
646                                         lamp_stat = true;
647                                         alamp = QString::fromUtf8("<FONT COLOR=FIREBRICK>●</FONT>"); // ðŸ’ŸU+1F4BE Floppy Disk
648                                 } else {
649                                         alamp = QString::fromUtf8("<FONT COLOR=BLUE>○</FONT>"); // ðŸ’ŸU+1F4BE Floppy Disk
650                                 }
651                                 if(p_emu->d88_file[i].bank_num > 0) {
652                                         iname = QString::fromUtf8(p_emu->d88_file[i].disk_name[p_emu->d88_file[i].cur_bank]);
653                                 } else {
654                                         iname = QString::fromUtf8("*Inserted*");
655                                 }
656                                 tmpstr = iname;
657                         } else {
658                                 tmpstr.clear();
659                                 alamp = QString::fromUtf8("×");
660                         }
661                         if(alamp != fd_lamp[i]) {
662                                 emit sig_set_access_lamp(i + 2, lamp_stat);
663                                 emit sig_change_access_lamp(CSP_DockDisks_Domain_FD, i, alamp);
664                                 fd_lamp[i] = alamp;
665                         }
666                         if(tmpstr != fd_text[i]) {
667                                 emit sig_set_access_lamp(i + 2, lamp_stat);
668                                 emit sig_change_osd(CSP_DockDisks_Domain_FD, i, tmpstr);
669                                 fd_text[i] = tmpstr;
670                         }
671                         lamp_stat = false;
672                 }
673         }
674 }
675
676 void EmuThreadClassBase::get_qd_string(void)
677 {
678         if(using_flags.get() == nullptr) return;
679         if(!(using_flags->is_use_qd())) return;
680         int i;
681         QString iname;
682         QString alamp;
683         QString tmpstr;
684         uint32_t access_drv = 0;
685         bool lamp_stat = false;
686         access_drv = p_emu->is_quick_disk_accessed();
687         for(i = 0; i < using_flags->get_max_qd(); i++) {
688                 tmpstr.clear();
689                 lamp_stat = false;
690                 if(p_emu->is_quick_disk_inserted(i)) {
691                         if(i == (access_drv - 1)) {
692                                 alamp = QString::fromUtf8("<FONT COLOR=MAGENTA>●</FONT>"); // ðŸ’œã€€U+1F4BD MiniDisc
693                                 lamp_stat = true;
694                         } else {
695                                 alamp = QString::fromUtf8("<FONT COLOR=BLUE>○</FONT>"); // ðŸ’œU+1F4BD MiniDisc
696                         }
697                         tmpstr = alamp;
698                         //tmpstr = tmpstr + QString::fromUtf8(" ");
699                         //iname = QString::fromUtf8("*Inserted*");
700                         //tmpstr = tmpstr + iname;
701                 } else {
702                         tmpstr = QString::fromUtf8("×");
703                 }
704                 if(tmpstr != qd_text[i]) {
705                         emit sig_set_access_lamp(i + 10, lamp_stat);
706                         emit sig_change_access_lamp(CSP_DockDisks_Domain_QD, i, tmpstr);
707                         qd_text[i] = tmpstr;
708                 }
709                 lamp_stat = false;
710         }
711 }
712
713 void EmuThreadClassBase::get_tape_string()
714 {
715         QString tmpstr;
716         bool readwrite;
717         bool inserted;
718
719         if(using_flags.get() == nullptr) return;
720         if(!(using_flags->is_use_tape()) || (using_flags->is_tape_binary_only())) return;
721         for(int i = 0; i < using_flags->get_max_tape(); i++) {
722                 inserted = p_emu->is_tape_inserted(i);
723                 readwrite = false;
724                 if(inserted) {
725                         tmpstr.clear();
726                         const _TCHAR *ts = p_emu->get_tape_message(i);
727                         if(ts != NULL) {
728                                 tmpstr = QString::fromUtf8(ts);
729                                 readwrite = p_emu->is_tape_recording(i);
730                                 if(readwrite) {
731                                         tmpstr = QString::fromUtf8("<FONT COLOR=RED><B>") + tmpstr + QString::fromUtf8("</B></FONT>");
732                                 } else {
733                                         tmpstr = QString::fromUtf8("<FONT COLOR=GREEN><B>") + tmpstr + QString::fromUtf8("</B></FONT>");
734                                 }
735                         }
736                 } else {
737                         tmpstr = QString::fromUtf8("<FONT COLOR=BLUE>   EMPTY   </FONT>");
738                 }
739                 emit sig_set_access_lamp(i + 12 + ((readwrite) ? 2 : 0), inserted);
740                 if(tmpstr != cmt_text[i]) {
741                         emit sig_change_osd(CSP_DockDisks_Domain_CMT, i, tmpstr);
742                         cmt_text[i] = tmpstr;
743                 }
744         }
745
746 }
747
748 void EmuThreadClassBase::get_hdd_string(void)
749 {
750         if(using_flags.get() == nullptr) return;
751         if(!(using_flags->is_use_hdd())) return;
752
753         QString tmpstr, alamp;
754         uint32_t access_drv = p_emu->is_hard_disk_accessed();
755         bool lamp_stat = false;
756         alamp.clear();
757         tmpstr.clear();
758         for(int i = 0; i < (int)using_flags->get_max_hdd(); i++) {
759                 if(p_emu->is_hard_disk_inserted(i)) {
760                         if((access_drv & (1 << i)) != 0) {
761                                 alamp = QString::fromUtf8("<FONT COLOR=LIME>■</FONT>");  //
762                                 lamp_stat = true;
763                         } else {
764                                 alamp = QString::fromUtf8("<FONT COLOR=BLUE>□</FONT>");  //
765                         }
766                 } else {
767                         alamp = QString::fromUtf8("×");
768                 }
769                 if(tmpstr != hdd_text[i]) {
770                         emit sig_set_access_lamp(i + 16, lamp_stat);
771                         emit sig_change_osd(CSP_DockDisks_Domain_HD, i, tmpstr);
772                         hdd_text[i] = tmpstr;
773                 }
774                 if(alamp != hdd_lamp[i]) {
775                         emit sig_set_access_lamp(i + 16, lamp_stat);
776                         emit sig_change_access_lamp(CSP_DockDisks_Domain_HD, i, alamp);
777                         hdd_lamp[i] = alamp;
778                 }
779                 lamp_stat = false;
780         }
781
782 }
783 void EmuThreadClassBase::get_cd_string(void)
784 {
785         if(using_flags.get() == nullptr) return;
786         if(!(using_flags->is_use_compact_disc())) return;
787
788         QString tmpstr;
789         uint32_t access_drv = p_emu->is_compact_disc_accessed();
790         for(int i = 0; i < (int)using_flags->get_max_cd(); i++) {
791                 if(p_emu->is_compact_disc_inserted(i)) {
792                         if((access_drv & (1 << i)) != 0) {
793                                 tmpstr = QString::fromUtf8("<FONT COLOR=DEEPSKYBLUE>●</FONT>");  // U+1F4BF OPTICAL DISC
794                         } else {
795                                 tmpstr = QString::fromUtf8("<FONT COLOR=BLUE>○</FONT>");  // U+1F4BF OPTICAL DISC
796                         }
797                 } else {
798                         tmpstr = QString::fromUtf8("×");
799                 }
800                 if(tmpstr != cdrom_text[i]) {
801                         emit sig_set_access_lamp(i + 24, ((access_drv & (1 << i)) != 0));
802                         emit sig_change_access_lamp(CSP_DockDisks_Domain_CD, i, tmpstr);
803                         cdrom_text[i] = tmpstr;
804                 }
805         }
806
807 }
808
809 void EmuThreadClassBase::get_bubble_string(void)
810 {
811         if(using_flags.get() == nullptr) return;
812         if(!(using_flags->is_use_bubble())) return;
813
814         uint32_t access_drv;
815         int i;
816         QString alamp;
817         QString tmpstr;
818         for(i = 0; i < using_flags->get_max_bubble() ; i++) {
819                 if(p_emu->is_bubble_casette_inserted(i)) {
820                         alamp = QString::fromUtf8("● ");
821                         //tmpstr = alamp + QString::fromUtf8(" ");
822                 } else {
823                         tmpstr = QString::fromUtf8("×");
824                         //tmpstr = tmpstr + QString::fromUtf8(" ");
825                 }
826                 if(alamp != bubble_text[i]) {
827                         emit sig_change_access_lamp(CSP_DockDisks_Domain_Bubble, i, tmpstr);
828                         bubble_text[i] = alamp;
829                 }
830         }
831
832 }
833
834 double EmuThreadClassBase::get_emu_frame_rate(void)
835 {
836         if(using_flags.get() == nullptr) return 30.0;
837         return p_emu->get_frame_rate();
838 }
839
840 int EmuThreadClassBase::get_message_count(void)
841 {
842         if(using_flags.get() == nullptr) return 0;
843         return p_emu->message_count;
844 }
845
846 const _TCHAR *EmuThreadClassBase::get_emu_message(void)
847 {
848         if(using_flags.get() == nullptr) return ((const _TCHAR *)_T(""));
849         return (const _TCHAR *)(p_emu->message);
850 }
851
852 bool EmuThreadClassBase::now_debugging()
853 {
854         if(using_flags.get() == nullptr) return false;
855         if(using_flags->is_use_debugger()) {
856                 return p_emu->now_debugging;
857         } else {
858                 return false;
859         }
860 }
861
862
863 #if defined(Q_OS_LINUX)
864 //#undef _GNU_SOURCE
865 #endif