OSDN Git Service

[OSD][SOUND][WIP] QT_MULTIMEDIA: Now enabling sound, but not enabled.
[csp-qt/common_source_project-fm7.git] / source / src / qt / osd_base.cpp
1 /*
2         Skelton for retropc emulator
3
4         Author : K.Ohta <whatisthis.sowhat _at_ gmail.com>
5         Date   : 2015.11.30-
6
7         [ Qt dependent ]
8 */
9
10 //#include "emu.h"
11 #include <string>
12
13 #include <QObject>
14 #include <QWidget>
15
16 #include <mutex>
17 #include <chrono>
18
19 #include <QSemaphore>
20 #include <QPainter>
21 #include <QElapsedTimer>
22 #include <QQueue>
23
24 #include <QDateTime>
25 #include <QDate>
26 #include <QTime>
27 #include <QString>
28 #include <QObject>
29 #include <QThread>
30
31 #include <QOpenGLContext>
32 #include <QtMultimedia>
33
34 #include "simd_types.h"
35
36 #include <ctime>
37 #include <limits>
38
39 #include "../config.h"
40 #include "../fileio.h"
41 #include "../fifo.h"
42 #include "../vm/device.h"
43
44 #include "qt_input.h"
45 //#include "qt_main.h"
46 //#include "csp_logger.h"
47 #include "osd_base.h"
48 #include "gui/dock_disks.h"
49 #include "../vm/vm_template.h"
50
51 #include "./osd_sound_mod_qtmultimedia.h"
52
53 OSD_BASE::OSD_BASE(std::shared_ptr<USING_FLAGS> p, std::shared_ptr<CSP_Logger> logger) : QObject(0)
54 {
55         using_flags = p;
56         locked_vm = false;
57         #if 0  /* Note: Below are new sound driver. */
58                 #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
59         m_audioOutputDevice = QMediaDevices::defaultAudioOutput();
60         m_audioInputDevice  = QMediaDevices::defaultAudioInput();
61         //m_audioOutputSink = std::shared_ptr<QAudioSink>(new QAudioSink(m_audioOutputDevice, m_audioOutputDevice.preferredFormat()));
62         m_audioOutputSink.reset(new QAudioSink(m_audioOutputDevice, m_audioOutputDevice.preferredFormat()));
63                 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
64         m_audioOutputDevice = QAudioDeviceInfo::defaultOutputDevice();
65         m_audioInputDevice  = QAudioDeviceInfo::defaultInputDevice();
66
67         m_audioOutputSink.reset(new QAudioOutput(m_audioOutputDevice, m_audioOutputDevice.preferredFormat()));
68                 #endif
69         m_audioInputSource.reset();
70         //m_audioOutputSink->moveToThread(this->thread());
71         m_audioOutput = nullptr;
72         m_audioInput = nullptr;
73         sound_initialized = false;
74         sound_us_before_rendered = 0;
75         #endif /* END Note: */
76         device_node_list.clear();
77         max_vm_nodes = 0;
78         p_logger = logger;
79         vm = NULL;
80         
81         SupportedFeatures.clear();
82         midi_receivers.clear();
83         midi_senders.clear();
84         sio_receivers.clear();
85         sio_senders.clear();
86         
87         is_glcontext_shared = false;
88         glContext = NULL;
89
90         #if 1  /* Note: Below are new sound driver. */
91         m_sound_driver.reset(
92                 new SOUND_OUTPUT_MODULE::M_QT_MULTIMEDIA(this,
93                                                                                                  nullptr,
94                                                                                                  48000,
95                                                                                                  100,
96                                                                                                  2,
97                                                                                                  nullptr,
98                                                                                                  0));
99
100         #endif  /* END Note: */
101         get_sound_device_list();
102 }
103
104 OSD_BASE::~OSD_BASE()
105 {
106         if(log_mutex.try_lock_for(std::chrono::milliseconds(100))) {
107                 p_logger->set_osd(NULL);
108                 log_mutex.unlock();
109         }
110 }
111
112 extern std::string cpp_homedir;
113 extern std::string my_procname;
114
115 const _TCHAR *OSD_BASE::get_lib_osd_version()
116 {
117         const _TCHAR *p = (const _TCHAR *)"\0";
118 #if defined(__LIBOSD_VERSION)
119         return (const _TCHAR *)__LIBOSD_VERSION;
120 #endif
121         return p;         
122 }
123
124 QOpenGLContext *OSD_BASE::get_gl_context()
125 {
126         if(glContext == NULL) return NULL;
127         if(!(glContext->isValid())) return NULL;
128         return glContext;
129 }
130
131 EmuThreadClass *OSD_BASE::get_parent_handler()
132 {
133         return parent_thread;
134 }
135
136 void OSD_BASE::set_parent_thread(EmuThreadClass *parent)
137 {
138         parent_thread = parent;
139 }
140
141 void OSD_BASE::initialize(int rate, int samples, int* presented_rate, int* presented_samples)
142 {
143 }
144
145 void OSD_BASE::release()
146 {
147 }
148
149 void OSD_BASE::suspend()
150 {
151         if(get_use_movie_player()) {
152                 if(now_movie_play && !now_movie_pause) {
153                         pause_movie();
154                         now_movie_pause = false;
155                 }
156         }
157         mute_sound();
158 }
159
160 void OSD_BASE::restore()
161 {
162         if(get_use_movie_player()) {
163                 if(now_movie_play && !now_movie_pause) {
164                         play_movie();
165                 }
166         }
167 }
168
169
170 void OSD_BASE::debug_log(int level, const char *fmt, ...)
171 {
172         char strbuf[4096];
173         va_list ap;
174         
175         va_start(ap, fmt);      
176         vsnprintf(strbuf, 4095, fmt, ap);
177         debug_log(level, 0, strbuf);
178         va_end(ap);
179 }
180
181 void OSD_BASE::debug_log(int level, int domain_num, const char *fmt, ...)
182 {
183         char strbuf[4096];
184         va_list ap;
185         
186         va_start(ap, fmt);      
187         vsnprintf(strbuf, 4095, fmt, ap);
188         debug_log(level, domain_num, strbuf);
189         va_end(ap);
190 }
191
192 _TCHAR *OSD_BASE::get_app_path(void)
193 {
194         return app_path;
195 }
196
197 _TCHAR* OSD_BASE::bios_path(const _TCHAR* file_name)
198 {
199         static _TCHAR file_path[_MAX_PATH];
200         snprintf((char *)file_path, _MAX_PATH, "%s%s", app_path, (const char *)file_name);
201         debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_OSD, "BIOS PATH:%s", file_path);
202         return file_path;
203 }
204
205 void OSD_BASE::get_host_time(cur_time_t* time)
206 {
207         //SYSTEMTIME sTime;
208         //GetLocalTime(&sTime);
209         QDateTime nowTime = QDateTime::currentDateTime();
210         QDate d = nowTime.date();
211         QTime t = nowTime.time();
212
213         time->year = d.year();
214         time->month = d.month();
215         time->day = d.day();
216         time->day_of_week = d.dayOfWeek();
217         time->hour = t.hour();
218         time->minute = t.minute();
219         time->second = t.second();
220 }
221
222 void OSD_BASE::sleep(uint32_t ms)
223 {
224         QThread::msleep(ms);
225 }
226
227 void OSD_BASE::create_date_file_name(_TCHAR *name, int length, const _TCHAR *extension)
228 {
229         QDateTime nowTime = QDateTime::currentDateTime();
230         QString tmps = QString::fromUtf8("emu");
231         tmps = tmps + get_vm_config_name();
232         tmps = tmps + QString::fromUtf8("_");
233         tmps = tmps + nowTime.toString(QString::fromUtf8("yyyy-MM-dd_hh-mm-ss.zzz."));
234         tmps = tmps + QString::fromUtf8((const char *)extension);
235         snprintf((char *)name, length, "%s", tmps.toLocal8Bit().constData());
236 }
237
238 _TCHAR* OSD_BASE::application_path()
239 {
240         return app_path;
241 }
242
243
244 bool OSD_BASE::get_use_socket(void)
245 {
246         return false;
247 }
248
249 bool OSD_BASE::get_use_auto_key(void)
250 {
251         return false;
252 }
253
254 bool OSD_BASE::get_dont_keeep_key_pressed(void)
255 {
256         return false;
257 }
258
259 bool OSD_BASE::get_one_board_micro_computer(void)
260 {
261         return false;
262 }
263
264 bool OSD_BASE::get_use_screen_rotate(void)
265 {
266         return false;
267 }
268
269 bool OSD_BASE::get_use_movie_player(void)
270 {
271         return false;
272 }
273
274 bool OSD_BASE::get_use_video_capture(void)
275 {
276         return false;
277 }
278
279
280 void OSD_BASE::vm_key_down(int code, bool flag)
281 {
282         std::lock_guard<std::recursive_timed_mutex> lv(vm_mutex);
283
284         if(vm != NULL) {
285                 vm->key_down(code, flag);
286         }
287 }
288
289 void OSD_BASE::vm_key_up(int code)
290 {
291         std::lock_guard<std::recursive_timed_mutex> lv(vm_mutex);
292
293         if(vm != NULL) {
294                 vm->key_up(code);
295         }
296 }
297
298 void OSD_BASE::vm_reset(void)
299 {
300         std::lock_guard<std::recursive_timed_mutex> lv(vm_mutex);
301
302         if(vm != NULL) {
303                 vm->reset();
304         }
305 }
306
307 int OSD_BASE::get_vm_buttons_code(int num)
308 {
309         return 0;
310 }       
311
312 QString OSD_BASE::get_vm_config_name(void)
313 {
314         return QString::fromUtf8(" ");
315 }
316
317 int OSD_BASE::get_screen_width(void)
318 {
319         return 320;
320 }
321
322 int OSD_BASE::get_screen_height(void)
323 {
324         return 200;
325 }
326
327 void OSD_BASE::lock_vm(void)
328 {
329         locked_vm = true;
330         vm_mutex.lock();
331 }
332
333 void OSD_BASE::unlock_vm(void)
334 {
335         vm_mutex.unlock();
336         locked_vm = false;
337 }
338
339
340 bool OSD_BASE::is_vm_locked(void)
341 {
342         return locked_vm;
343 }
344
345 void OSD_BASE::force_unlock_vm(void)
346 {
347         vm_mutex.unlock();
348         locked_vm = false;
349 }
350
351 void OSD_BASE::set_draw_thread(DrawThreadClass *handler)
352 {
353 }
354
355 void OSD_BASE::initialize_screen()
356 {
357         first_draw_screen = false;
358         first_invalidate = true;
359         self_invalidate = false;
360 }
361
362 void OSD_BASE::release_screen()
363 {
364 }
365
366 int OSD_BASE::get_window_mode_width(int mode)
367 {
368         return 640;
369 }
370
371 int OSD_BASE::get_window_mode_height(int mode)
372 {
373         return 200;
374 }
375
376 double OSD_BASE::get_window_mode_power(int mode)
377 {
378         if(mode + 1 == 2) {
379                 return 1.5;
380         } else if(mode + 1 > 2) {
381                 return mode + 1 - 1;
382         }
383         return mode + 1;
384 }
385
386 void OSD_BASE::reset_vm_node(void)
387 {
388         device_node_t sp;
389         device_node_list.clear();
390         p_logger->reset();
391         max_vm_nodes = 0;
392 }
393
394 void OSD_BASE::debug_log(int level, int domain_num, char *strbuf)
395 {
396         p_logger->debug_log(level, domain_num, strbuf);
397 }
398
399
400 void OSD_BASE::set_device_name(int id, char *name)
401 {
402         p_logger->set_device_name(id, (char *)name);
403 }
404
405 void OSD_BASE::set_vm_node(int id, const _TCHAR *name)
406 {
407         device_node_t sp;
408         int i;
409         for(i = 0; i < device_node_list.size(); i++) {
410                 sp = device_node_list.at(i);
411                 if(id == sp.id) {
412                         sp.id = id;
413                         sp.name = name;
414                         set_device_name(id, (char *)name);
415                         device_node_list.replace(i, sp);
416                         if(id >= max_vm_nodes) max_vm_nodes = id + 1;
417                         return;
418                 }
419         }
420         // Not Found
421         sp.id = id;
422         sp.name = name;
423         set_device_name(id, (char *)name);
424         device_node_list.append(sp);
425         if(id >= max_vm_nodes) max_vm_nodes = id + 1;
426 }
427
428 const _TCHAR *OSD_BASE::get_vm_node_name(int id)
429 {
430         int i;
431         device_node_t sp;
432         for(i = 0; i < device_node_list.size(); i++) {
433                 sp = device_node_list.at(i);
434                 if(id == sp.id) {
435                         return sp.name;
436                 }
437         }
438         return NULL;
439 }
440
441 int OSD_BASE::get_vm_node_size(void)
442 {
443         return max_vm_nodes;
444 }
445
446
447 void OSD_BASE::add_feature(const _TCHAR *key, double value)
448 {
449         QString tmps;
450         supportedlist_t l;
451         tmps = QString::fromUtf8(key);
452         if(!check_feature(key)) {
453                 l.string = tmps;
454                 l.v.fvalue = value;
455                 SupportedFeatures.append(l);
456         }
457 }
458
459 void OSD_BASE::add_feature(const _TCHAR *key, int64_t value)
460 {
461         QString tmps;
462         supportedlist_t l;
463         tmps = QString::fromUtf8(key);
464         if(!check_feature(key)) {
465                 l.string = tmps;
466                 l.v.ivalue = value;
467                 SupportedFeatures.append(l);
468         }
469 }
470
471 void OSD_BASE::add_feature(const _TCHAR *key, uint64_t value)
472 {
473         QString tmps;
474         supportedlist_t l;
475         tmps = QString::fromUtf8(key);
476         if(!check_feature(key)) {
477                 l.string = tmps;
478                 l.v.uvalue = value;
479                 SupportedFeatures.append(l);
480         }
481 }
482
483 void OSD_BASE::add_feature(const _TCHAR *key, float value)
484 {
485         add_feature(key, (double)value);
486 }
487
488 void OSD_BASE::add_feature(const _TCHAR *key, int value)
489 {
490         add_feature(key, (int64_t)value);
491 }
492
493
494 void OSD_BASE::add_feature(const _TCHAR *key, int16_t value)
495 {
496         add_feature(key, (int64_t)value);
497 }
498
499 void OSD_BASE::add_feature(const _TCHAR *key, int8_t value)
500 {
501         add_feature(key, (int64_t)value);
502 }
503
504 void OSD_BASE::add_feature(const _TCHAR *key, uint32_t value)
505 {
506         add_feature(key, (uint64_t)(value & 0xffffffff));
507 }
508
509 void OSD_BASE::add_feature(const _TCHAR *key, uint16_t value)
510 {
511         add_feature(key, (uint64_t)(value & 0xffff));
512 }
513
514 void OSD_BASE::add_feature(const _TCHAR *key, uint8_t value)
515 {
516         add_feature(key, (uint64_t)(value & 0xff));
517 }
518
519
520 bool OSD_BASE::check_feature(const _TCHAR *key)
521 {
522         QString tmps;
523         supportedlist_t l;
524         tmps = QString::fromUtf8(key);
525         for(int i = 0; i < SupportedFeatures.size(); i++) {
526                 l = SupportedFeatures.at(i);
527                 if(l.string == tmps) {
528                         return true;
529                 }
530         }
531         return false;
532 }
533
534 double OSD_BASE::get_feature_double_value(const _TCHAR *key)
535 {
536         QString tmps;
537         supportedlist_t l;
538         tmps = QString::fromUtf8(key);
539         for(int i = 0; i < SupportedFeatures.size(); i++) {
540                 l = SupportedFeatures.at(i);
541                 if(l.string == tmps) {
542                         return l.v.fvalue;
543                 }
544         }
545         return std::numeric_limits<double>::quiet_NaN(); // You don't use (0.0 / 0.0). 
546 }
547
548 int64_t OSD_BASE::get_feature_int64_value(const _TCHAR *key)
549 {
550         QString tmps;
551         supportedlist_t l;
552         tmps = QString::fromUtf8(key);
553         for(int i = 0; i < SupportedFeatures.size(); i++) {
554                 l = SupportedFeatures.at(i);
555                 if(l.string == tmps) {
556                         return l.v.ivalue;
557                 }
558         }
559         return 0;
560 }
561
562 int OSD_BASE::get_feature_int_value(const _TCHAR *key)
563 {
564         return (int)get_feature_int64_value(key);
565 }
566
567 int32_t OSD_BASE::get_feature_int32_value(const _TCHAR *key)
568 {
569         return (int32_t)get_feature_int64_value(key);
570 }
571
572 int16_t OSD_BASE::get_feature_int16_value(const _TCHAR *key)
573 {
574         return (int16_t)get_feature_int64_value(key);
575 }
576
577 int8_t OSD_BASE::get_feature_int8_value(const _TCHAR *key)
578 {
579         return (int8_t)get_feature_int64_value(key);
580 }
581
582
583 uint64_t OSD_BASE::get_feature_uint64_value(const _TCHAR *key)
584 {
585         QString tmps;
586         supportedlist_t l;
587         tmps = QString::fromUtf8(key);
588         for(int i = 0; i < SupportedFeatures.size(); i++) {
589                 l = SupportedFeatures.at(i);
590                 if(l.string == tmps) {
591                         return l.v.uvalue;
592                 }
593         }
594         return 0;
595 }
596
597 uint32_t OSD_BASE::get_feature_uint32_value(const _TCHAR *key)
598 {
599         return (uint32_t)(get_feature_uint64_value(key) & 0xffffffff);
600 }
601
602 uint16_t OSD_BASE::get_feature_uint16_value(const _TCHAR *key)
603 {
604         return (uint16_t)(get_feature_uint64_value(key) & 0xffff);
605 }
606
607 uint8_t OSD_BASE::get_feature_uint8_value(const _TCHAR *key)
608 {
609         return (uint8_t)(get_feature_uint64_value(key) & 0xff);
610 }
611
612 void OSD_BASE::start_waiting_in_debugger()
613 {
614         // ToDo: Wait for rising up debugger window.
615         debug_mutex.lock(); 
616 }
617
618 void OSD_BASE::finish_waiting_in_debugger()
619 {
620         // ToDo: Wait for closing up debugger window.
621         debug_mutex.unlock(); 
622 }
623
624 void OSD_BASE::process_waiting_in_debugger()
625 {
626         // ToDo: Check sequence
627         QThread::msleep(10);
628 }
629
630 void OSD_BASE::set_dbg_completion_list(std::list<std::string> *p)
631 {
632         if(p != NULL) {
633                 emit sig_clear_dbg_completion_list();
634                 for(auto n = p->begin(); n != p->end(); ++n) {
635                         emit sig_add_dbg_completion_list((_TCHAR *)((*n).c_str()));
636                 }
637                 emit sig_apply_dbg_completion_list();
638         }
639 }
640
641 void OSD_BASE::clear_dbg_completion_list(void)
642 {
643         emit sig_clear_dbg_completion_list();
644         emit sig_apply_dbg_completion_list();
645 }
646
647 // Belows are API for GUI STATUS BAR.
648 void OSD_BASE::set_hdd_image_name(int drv, _TCHAR *filename)
649 {
650         QString _n = QString::fromLocal8Bit(filename);
651         emit sig_change_virtual_media(CSP_DockDisks_Domain_HD, drv, _n);
652 }
653
654 // Moved from OSD_WRAPPER.
655 const _TCHAR *OSD_BASE::get_lib_common_vm_version()
656 {
657         return (const _TCHAR *)"\0";
658 }
659
660 const _TCHAR *OSD_BASE::get_lib_common_vm_git_version()
661 {
662         std::lock_guard<std::recursive_timed_mutex> lv(vm_mutex);
663
664         return vm->get_vm_git_version();
665 }
666
667
668 // Screen
669 void OSD_BASE::vm_draw_screen(void)
670 {
671         vm->draw_screen();
672 }
673
674 double OSD_BASE::vm_frame_rate(void)
675 {
676         std::lock_guard<std::recursive_timed_mutex> lv(vm_mutex);
677
678         return vm->get_frame_rate();
679 }
680
681 Sint16* OSD_BASE::create_sound(int *extra_frames)
682 {
683         std::lock_guard<std::recursive_timed_mutex> lv(vm_mutex);
684
685         return (Sint16 *)vm->create_sound(extra_frames);
686 }
687