OSDN Git Service

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