2 Skelton for retropc emulator
4 Author : K.Ohta <whatisthis.sowhat _at_ gmail.com>
18 #include <QElapsedTimer>
28 #include <QOpenGLContext>
39 #include "../vm/device.h"
40 #include "../common.h"
44 #include "emu_thread.h"
45 #include "draw_thread.h"
46 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
47 #include "avio/movie_loader.h"
49 #include "qt_gldraw.h"
50 #include "csp_logger.h"
52 bool OSD::get_use_socket(void)
62 bool OSD::get_use_auto_key(void)
71 bool OSD::get_dont_keeep_key_pressed(void)
73 #ifdef DONT_KEEEP_KEY_PRESSED
80 bool OSD::get_one_board_micro_computer(void)
82 #ifdef ONE_BOARD_MICRO_COMPUTER
89 bool OSD::get_use_screen_rotate(void)
91 #ifdef USE_SCREEN_ROTATE
98 bool OSD::get_use_movie_player(void)
100 #ifdef USE_MOVIE_PLAYER
107 bool OSD::get_use_video_capture(void)
109 #ifdef USE_VIDEO_CAPTURE
117 int OSD::get_vm_buttons_code(int num)
119 #ifdef ONE_BOARD_MICRO_COMPUTER
120 if(num < 0) return 0;
121 return vm_buttons[num].code;
128 QString OSD::get_vm_config_name(void)
130 #if defined(CONFIG_NAME)
131 return QString::fromUtf8(CONFIG_NAME);
133 return QString::fromUtf8(" ");
137 int OSD::get_screen_width(void)
142 int OSD::get_screen_height(void)
144 return SCREEN_HEIGHT;
148 void OSD::set_draw_thread(DrawThreadClass *handler)
150 //this->moveToThread(handler);
151 connect(this, SIGNAL(sig_update_screen(void *, bool)), handler, SLOT(do_update_screen(void *, bool)));
152 connect(this, SIGNAL(sig_save_screen(const char *)), p_glv, SLOT(do_save_frame_screen(const char *)));
153 connect(this, SIGNAL(sig_resize_vm_screen(QImage *, int, int)), p_glv, SLOT(do_set_texture_size(QImage *, int, int)));
154 connect(this, SIGNAL(sig_resize_vm_lines(int)), p_glv, SLOT(do_set_horiz_lines(int)));
155 connect(parent_thread, SIGNAL(sig_debugger_input(QString)), this, SLOT(do_set_input_string(QString)));
156 connect(parent_thread, SIGNAL(sig_quit_debugger()), this, SLOT(do_close_debugger_thread()));
157 connect(this, SIGNAL(sig_move_mouse_to_center()), p_glv, SLOT(do_move_mouse_to_center()));
158 connect(this, SIGNAL(sig_close_window()), parent_thread, SLOT(doExit()));
161 void OSD::initialize_screen()
163 host_window_width = base_window_width = WINDOW_WIDTH;
164 host_window_height = base_window_height = WINDOW_HEIGHT;
165 host_window_mode = true;
167 vm_screen_width = SCREEN_WIDTH;
168 vm_screen_height = SCREEN_HEIGHT;
169 vm_window_width = WINDOW_WIDTH;
170 vm_window_height = WINDOW_HEIGHT;
171 vm_window_width_aspect = WINDOW_WIDTH_ASPECT;
172 vm_window_height_aspect = WINDOW_HEIGHT_ASPECT;
174 QColor col(0, 0, 0, 255);
176 vm_screen_buffer.width = SCREEN_WIDTH;
177 vm_screen_buffer.height = SCREEN_HEIGHT;
178 vm_screen_buffer.pImage = QImage(SCREEN_WIDTH, SCREEN_HEIGHT, QImage::Format_ARGB32);
179 vm_screen_buffer.pImage.fill(col);
180 now_record_video = false;
182 first_draw_screen = false;
183 first_invalidate = true;
184 self_invalidate = false;
187 void OSD::release_screen()
190 release_screen_buffer(&vm_screen_buffer);
193 int OSD::get_window_mode_width(int mode)
195 if(get_use_screen_rotate()) {
196 if(p_config->rotate_type == 1 || p_config->rotate_type == 3) {
197 return (p_config->window_stretch_type == 0 ? vm_window_height : vm_window_height_aspect) * (mode + WINDOW_MODE_BASE);
200 return (p_config->window_stretch_type == 0 ? vm_window_width : vm_window_width_aspect) * (mode + WINDOW_MODE_BASE);
203 int OSD::get_window_mode_height(int mode)
205 if(get_use_screen_rotate()) {
206 if(p_config->rotate_type == 1 || p_config->rotate_type == 3) {
207 return (p_config->window_stretch_type == 0 ? vm_window_width : vm_window_width_aspect) * (mode + WINDOW_MODE_BASE);
210 return (p_config->window_stretch_type == 0 ? vm_window_height : vm_window_height_aspect) * (mode + WINDOW_MODE_BASE);
213 double OSD::get_window_mode_power(int mode)
215 if(mode + WINDOW_MODE_BASE == 2) {
217 } else if(mode + WINDOW_MODE_BASE > 2) {
218 return mode + WINDOW_MODE_BASE - 1;
220 return mode + WINDOW_MODE_BASE;
224 void OSD::initialize_video()
227 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
228 movie_loader = new MOVIE_LOADER(this, &config);
229 //connect(movie_loader, SIGNAL(sig_send_audio_frame(uint8_t *, long)), this, SLOT(do_run_movie_audio_callback2(uint8_t *, long)));
230 connect(movie_loader, SIGNAL(sig_movie_end(bool)), this, SLOT(do_video_movie_end(bool)));
231 connect(this, SIGNAL(sig_movie_play(void)), movie_loader, SLOT(do_play()));
232 connect(this, SIGNAL(sig_movie_stop(void)), movie_loader, SLOT(do_stop()));
233 connect(this, SIGNAL(sig_movie_pause(bool)), movie_loader, SLOT(do_pause(bool)));
234 connect(this, SIGNAL(sig_movie_seek_frame(bool, int)), movie_loader, SLOT(do_seek_frame(bool, int)));
235 //connect(this, SIGNAL(sig_movie_mute(bool, bool)), movie_loader, SLOT(do_mute(bool, bool)));
236 connect(movie_loader, SIGNAL(sig_decoding_error(int)), this, SLOT(do_video_decoding_error(int)));
240 void OSD::release_video()
242 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
249 bool OSD::open_movie_file(const _TCHAR* file_path)
252 if(file_path == NULL) return ret;
253 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
254 if(movie_loader != NULL) {
255 ret = movie_loader->open(QString::fromUtf8(file_path));
261 void OSD::close_movie_file()
263 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
264 if(movie_loader != NULL) {
265 movie_loader->close();
268 now_movie_play = false;
269 now_movie_pause = false;
273 uint32_t OSD::get_cur_movie_frame()
275 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
276 if(movie_loader != NULL) {
278 pos = movie_loader->get_current_frame();
282 return (uint32_t)pos;
288 void OSD::do_run_movie_audio_callback(uint8_t *data, long len)
290 if(data == NULL) return;
291 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
295 this->vm->movie_sound_callback(data, len);
303 void OSD::do_decode_movie(int frames)
305 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
306 //movie_loader->do_decode_frames(frames, SCREEN_WIDTH, SCREEN_HEIGHT);
307 movie_loader->do_decode_frames(frames, vm_window_width_aspect, vm_window_height_aspect);
311 void OSD::get_video_buffer()
313 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
314 //movie_loader->do_decode_frames(1, this->get_vm_window_width(), this->get_vm_window_height());
315 movie_loader->get_video_frame();
320 int OSD::get_movie_sound_rate()
322 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
323 return movie_loader->get_movie_sound_rate();
328 #if defined(USE_SOCKET)
329 #include <QHostAddress>
330 #include <QTcpSocket>
331 #include <QUdpSocket>
333 #include "osd_socket.h"
336 void OSD::initialize_socket()
338 for(int i = 0; i < SOCKET_MAX; i++) {
339 tcp_socket[i] = NULL;
340 udp_socket[i] = NULL;
343 host_mode[i] = false;
347 void OSD::release_socket()
351 for(int i = 0; i < SOCKET_MAX; i++) {
352 if(tcp_socket[i] != NULL) {
353 if(tcp_socket[i]->isOpen()) tcp_socket[i]->close();
354 delete tcp_socket[i];
355 tcp_socket[i] = NULL;
357 if(udp_socket[i] != NULL) {
358 if(udp_socket[i]->isOpen()) udp_socket[i]->close();
359 delete udp_socket[i];
360 udp_socket[i] = NULL;
367 void OSD::notify_socket_connected(int ch)
369 do_notify_socket_connected(ch);
372 void OSD::do_notify_socket_connected(int ch)
375 // ToDo: Really need to lock? 20221011 K.O
376 std::lock_guard<std::recursive_timed_mutex> lv(vm_mutex);
377 vm->notify_socket_connected(ch);
382 void OSD::notify_socket_disconnected(int ch)
384 do_notify_socket_disconnected(ch);
388 void OSD::do_notify_socket_disconnected(int ch)
390 if(!socket_delay[ch]) {
391 socket_delay[ch] = 1;//56;
395 // Called per 1 frame.
396 void OSD::update_socket()
399 // ToDo: Really need to lock? 20221011 K.O
400 std::lock_guard<std::recursive_timed_mutex> lv(vm_mutex);
402 for(int i = 0; i < SOCKET_MAX; i++) {
405 if(tcp_socket[i] != NULL) {
406 if(tcp_socket[i]->isOpen()) {
411 if(udp_socket[i] != NULL) {
412 if(udp_socket[i]->isOpen()) {
417 if((p != nullptr) && (vm != nullptr)) {
419 bytes = p->bytesAvailable();
422 uint8_t* buf0 = vm->get_socket_recv_buffer0(i, &size0, &size1);
423 uint8_t* buf1 = vm->get_socket_recv_buffer1(i);
426 if(bytes > (qint64)(size0 + size1)) {
427 bytes = (qint64)(size0 + size1);
429 QByteArray src = p->read(bytes);
432 uint8_t *pp = (uint8_t *)(src.constData());
433 if(size <= (qint64)size0) {
434 memcpy(buf0, pp, size);
436 memcpy(buf0, pp, size0);
437 memcpy(buf1, pp + size0, (int)size - size0);
439 vm->inc_socket_recv_buffer_ptr(i, (int)size);
440 } else if(socket_delay[i] != 0) {
441 if(--socket_delay[i] == 0) {
442 vm->notify_socket_disconnected(i);
450 bool OSD::initialize_socket_tcp(int ch)
453 if(udp_socket[ch] != NULL) {
454 if(udp_socket[ch]->isOpen()) {
455 udp_socket[ch]->close();
457 delete udp_socket[ch];
458 udp_socket[ch] = NULL;
460 if(tcp_socket[ch] != NULL) {
461 if(tcp_socket[ch]->isOpen()) tcp_socket[ch]->close();
462 delete tcp_socket[ch];
465 tcp_socket[ch] = new QTcpSocket2(ch);
466 if(tcp_socket[ch] == NULL) return false;
467 tcp_socket[ch]->setChannel(ch);
468 connect(tcp_socket[ch], SIGNAL(connected()), tcp_socket[ch], SLOT(do_connected()));
469 connect(tcp_socket[ch], SIGNAL(sig_connected(int)), this, SLOT(do_notify_socket_connected(int)));
470 connect(tcp_socket[ch], SIGNAL(disconnected()), tcp_socket[ch], SLOT(do_disconnected()));
471 connect(tcp_socket[ch], SIGNAL(sig_disconnected(int)), this, SLOT(do_notify_socket_disconnected(int)));
476 bool OSD::initialize_socket_udp(int ch)
479 if(tcp_socket[ch] != NULL) {
480 if(tcp_socket[ch]->isOpen()) {
481 tcp_socket[ch]->close();
483 delete tcp_socket[ch];
484 tcp_socket[ch] = NULL;
486 if(udp_socket[ch] != NULL) {
487 if(udp_socket[ch]->isOpen()) udp_socket[ch]->close();
488 delete udp_socket[ch];
491 udp_socket[ch] = new QUdpSocket2(ch);
492 if(udp_socket[ch] == NULL) return false;
493 connect(udp_socket[ch], SIGNAL(connected()), udp_socket[ch], SLOT(do_connected()));
494 connect(udp_socket[ch], SIGNAL(sig_connected(int)), this, SLOT(do_notify_socket_connected(int)));
495 connect(udp_socket[ch], SIGNAL(disconnected()), udp_socket[ch], SLOT(do_disconnected()));
496 connect(udp_socket[ch], SIGNAL(sig_disconnected(int)), this, SLOT(do_notify_socket_disconnected(int)));
501 bool OSD::connect_socket(int ch, uint32_t ipaddr, int port)
504 QHostAddress addr = QHostAddress((quint32)ipaddr);
506 if(tcp_socket[ch] != NULL) {
507 tcp_socket[ch]->connectToHost(addr, (quint16)port);
512 if(udp_socket[ch] != NULL) {
513 udp_socket[ch]->connectToHost(addr, (quint16)port);
518 host_mode[ch] = false;
523 void OSD::disconnect_socket(int ch)
527 // ToDo: Really need to lock? 20221011 K.O
528 std::lock_guard<std::recursive_timed_mutex> lv(vm_mutex);
532 if(tcp_socket[ch] != NULL) {
533 if(tcp_socket[ch]->isOpen()) tcp_socket[ch]->close();
536 if(udp_socket[ch] != NULL) {
537 if(udp_socket[ch]->isOpen()) udp_socket[ch]->close();
542 if(tcp_socket[ch] != NULL) {
543 udp_socket[ch]->disconnectFromHost();
546 if(udp_socket[ch] != NULL) {
547 udp_socket[ch]->disconnectFromHost();
551 if(vm == nullptr) return;
552 vm->notify_socket_disconnected(ch);
556 bool OSD::listen_socket(int ch)
559 // ToDo: Really need to lock? 20221011 K.O
560 std::lock_guard<std::recursive_timed_mutex> lv(vm_mutex);
562 //QHostAddress addr = QHostAddress(QHostAddress::AnyIPv4); // OK?
563 // This unit is dummy?
564 //connect(udp_socket[ch], SIGNAL(connected()), udp_socket[ch], SLOT(do_connected()));
565 //connect(udp_socket[ch], SIGNAL(sig_connected(int)), this, SLOT(do_notify_socket_connected(int)));
566 //connect(udp_socket[ch], SIGNAL(disconnected()), udp_socket[ch], SLOT(do_disconnected()));
567 //connect(udp_socket[ch], SIGNAL(sig_disconnected(int)), this, SLOT(do_notify_socket_disconnected(int)));
572 void OSD::send_socket_data_tcp(int ch)
575 // ToDo: Really need to lock? 20221011 K.O
576 std::lock_guard<std::recursive_timed_mutex> lv(vm_mutex);
578 if(vm == nullptr) return;
582 uint8_t *buf = vm->get_socket_send_buffer(ch, &size);
587 if(tcp_socket[ch] != NULL) {
588 if(tcp_socket[ch]->isWritable()) {
589 size2 = tcp_socket[ch]->write((const char *)buf, (qint64)size);
591 disconnect_socket(ch);
592 notify_socket_disconnected(ch);
599 vm->inc_socket_send_buffer_ptr(ch, (int)size2);
605 void OSD::send_socket_data_udp(int ch, uint32_t ipaddr, int port)
608 // ToDo: Really need to lock? 20221011 K.O
609 std::lock_guard<std::recursive_timed_mutex> lv(vm_mutex);
611 QHostAddress addr = QHostAddress((quint32)ipaddr);
612 if(vm == nullptr) return;
616 uint8_t *buf = vm->get_socket_send_buffer(ch, &size);
622 if(udp_socket[ch] != NULL) {
623 size2 = udp_socket[ch]->writeDatagram((const char *)buf, (qint64)size, addr, (quint16)port);
625 disconnect_socket(ch);
626 notify_socket_disconnected(ch);
632 vm->inc_socket_send_buffer_ptr(ch, (int)size2);
638 void OSD::send_socket_data(int ch)
643 void OSD::recv_socket_data(int ch)
648 SOCKET OSD::get_socket(int ch)
652 if(tcp_socket[ch] == NULL) return (SOCKET)0;
653 return (SOCKET)tcp_socket[ch];
655 if(udp_socket[ch] == NULL) return (SOCKET)0;
656 return (SOCKET)udp_socket[ch];
665 scrntype_t DLL_PREFIX *bitmap_s::get_buffer(int y)
667 if((is_mapped) && (glv != NULL)) {
668 scrntype_t *p = NULL;
669 p = glv->get_screen_buffer(y);
670 if(p != NULL) return p;
672 return (scrntype_t *)pImage.scanLine(y);
675 scrntype_t* OSD::get_buffer(bitmap_t *p, int y)
677 if(p_glv->is_ready_to_map_vram_texture()) {
678 if(p == &vm_screen_buffer) {
679 return (scrntype_t *)p->get_buffer(y);
682 if((y >= p->pImage.height()) || (y < 0) || (y >= p->height)) {
685 return (scrntype_t *)p->pImage.scanLine(y);
689 int OSD::draw_screen()
692 std::lock_guard<std::recursive_timed_mutex> Locker_S(screen_mutex);
695 //QMutexLocker Locker_VM(&vm_mutex);
696 if(vm_screen_buffer.width != vm_screen_width || vm_screen_buffer.height != vm_screen_height) {
697 //emit sig_movie_set_width(vm_screen_width);
698 //emit sig_movie_set_height(vm_screen_height);
699 initialize_screen_buffer(&vm_screen_buffer, vm_screen_width, vm_screen_height, 0);
702 if(p_glv->is_ready_to_map_vram_texture()) {
703 vm_screen_buffer.is_mapped = true;
705 vm_screen_buffer.glv = p_glv;
707 vm_screen_buffer.is_mapped = false;
710 vm_screen_buffer.is_mapped = false;
712 this->vm_draw_screen();
713 // screen size was changed in vm->draw_screen()
714 if(vm_screen_buffer.width != vm_screen_width || vm_screen_buffer.height != vm_screen_height) {
717 draw_screen_buffer = &vm_screen_buffer;
719 // calculate screen size
721 // ToDo: Support MAX_DRAW_RANGES. 20221212 K.O
722 emit sig_update_screen((void *)draw_screen_buffer, mapped);
724 first_draw_screen = self_invalidate = true;
727 if(now_record_video) {
733 void OSD::initialize_screen_buffer(bitmap_t *buffer, int width, int height, int mode)
735 OSD_BASE::initialize_screen_buffer(buffer, width, height, mode);
737 //emit sig_movie_set_width(width);
738 //emit sig_movie_set_height(height);
739 emit sig_resize_vm_screen(&(buffer->pImage), width, height);
742 bool OSD::set_glview(GLDrawClass *glv)
744 if(glv == NULL) return false;
745 if(glContext != NULL) {
746 if(glContext->isValid()) return true;
751 glContext = new QOpenGLContext();
752 if(glContext != NULL) {
753 glContext->setShareContext(glv->context());
756 if(glContext->isValid()) {
757 is_glcontext_shared = true;
763 int OSD::add_video_frames()
765 //static double frames = 0;
766 //static int prev_video_fps = -1;
768 //static double prev_vm_fps = -1;
769 double vm_fps = vm_frame_rate();
770 int delta_ns = (int)(1.0e9 / vm_fps);
771 //if(rec_video_fps_nsec >= delta_ns) {
772 if(delta_ns == rec_video_fps_nsec) {
773 rec_video_nsec += delta_ns;
774 if(rec_video_nsec > (rec_video_fps_nsec * 2)) {
775 rec_video_nsec -= rec_video_fps_nsec;
776 } else if(rec_video_nsec < (rec_video_fps_nsec * -2)) {
777 rec_video_nsec += rec_video_fps_nsec;
779 while(rec_video_nsec > rec_video_fps_nsec) {
780 rec_video_nsec -= rec_video_fps_nsec;
783 } else { // Will branch whether rec_video_fps_nsec >= delta_ns ?
784 rec_video_nsec += delta_ns;
785 if(rec_video_nsec > (rec_video_fps_nsec * 2)) {
786 rec_video_nsec -= rec_video_fps_nsec;
787 } else if(rec_video_nsec < (rec_video_fps_nsec * -2)) {
788 rec_video_nsec += rec_video_fps_nsec;
790 while(rec_video_nsec >= rec_video_fps_nsec) {
791 rec_video_nsec -= rec_video_fps_nsec;
796 if(using_flags->is_use_one_board_computer()) {
797 //int size = vm_screen_buffer.pImage.byteCount();
799 rec_image_buffer = background_image.rgbSwapped();
800 if(p_glv->is_ready_to_map_vram_texture()) {
801 vm_screen_buffer.is_mapped = true;
802 vm_screen_buffer.glv = p_glv;
803 for(int y = 0; y < vm_screen_buffer.pImage.height(); y++) {
804 scrntype_t *p = vm_screen_buffer.get_buffer(y);
806 if(p != (scrntype_t*)(vm_screen_buffer.pImage.scanLine(y))) {
807 memcpy(vm_screen_buffer.pImage.scanLine(y), p, vm_screen_buffer.pImage.width() * sizeof(scrntype_t));
810 if(vm_screen_buffer.pImage.scanLine(y) != NULL) {
811 memset(vm_screen_buffer.pImage.scanLine(y), 0x00, vm_screen_buffer.pImage.width() * sizeof(scrntype_t));
816 QImage video_result = QImage(vm_screen_buffer.pImage);
819 int ww = video_result.width();
820 int hh = video_result.height();
821 //printf("%d x %d\n", ww, hh);
822 for(int yy = 0; yy < hh; yy++) {
823 for(int xx = 0; xx < ww; xx++) {
824 pixel = video_result.pixel(xx, yy);
825 #if defined(__LITTLE_ENDIAN__)
827 if(pixel != 0xff000000) {
828 rec_image_buffer.setPixel(xx, yy, pixel);
832 if(pixel != 0x000000ff) {
833 rec_image_buffer.setPixel(xx, yy, pixel);
840 emit sig_enqueue_video(i, background_image.width(), background_image.height(), &rec_image_buffer);
844 //int size = vm_screen_buffer.pImage.byteCount();
847 video_result = QImage(vm_screen_buffer.pImage);
851 emit sig_enqueue_video(i, vm_screen_width, vm_screen_height, &video_result);
854 // _TCHAR __tmps1[128] = {0};
855 // my_stprintf_s(__tmps1, sizeof(__tmps1) - 1, "Push Video %d frames\n", counter);
856 //emit sig_debug_log(CSP_LOG_DEBUG2, CSP_LOG_TYPE_SCREEN, QString::fromUtf8(__tmps1) );
861 double OSD::get_vm_current_usec()
863 if(log_mutex.try_lock_for(std::chrono::milliseconds(100))) {
868 double _d = vm->get_current_usec();
875 uint64_t OSD::get_vm_current_clock_uint64()
877 if(log_mutex.try_lock_for(std::chrono::milliseconds(100))) {
882 uint64_t _n = vm->get_current_clock_uint64();
889 const _TCHAR *OSD::get_lib_common_vm_version()
891 // ToDo: Really need to lock? 20221011 K.O
892 // std::lock_guard<std::recursive_timed_mutex> lv(vm_mutex);
894 if(vm->first_device != NULL) {
895 return vm->first_device->get_lib_common_vm_version();
897 return (const _TCHAR *)"\0";
901 void OSD::reset_vm_node(void)
903 // ToDo: Really need to lock? 20221011 K.O
904 std::lock_guard<std::recursive_timed_mutex> lv(vm_mutex);
907 device_node_list.clear();
908 emit sig_logger_reset();
911 if(vm == NULL) return;
912 for(DEVICE *p = vm->first_device; p != NULL; p = p->next_device) {
913 sp.id = p->this_device_id;
914 sp.name = p->this_device_name;
915 emit sig_logger_set_device_name(sp.id, QString::fromUtf8(sp.name));
917 _TCHAR tmps2[512] = {0};
918 my_stprintf_s(tmps2, sizeof(tmps2) - 1, "Device %d :%s", sp.id, sp.name);
919 emit sig_debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_GENERAL, QString::fromUtf8(tmps2));
921 device_node_list.append(sp);
922 if(max_vm_nodes <= p->this_device_id) max_vm_nodes = p->this_device_id + 1;
924 for(DEVICE *p = vm->first_device; p != NULL; p = p->next_device) {
925 emit sig_update_device_node_name(p->this_device_id, p->this_device_name);