OSDN Git Service

[MOVIE_LOADER] Fix scaling factor.Displaying video as correct width and height.
[csp-qt/common_source_project-fm7.git] / source / src / qt / osd_wrapper.cpp
index e76570d..fdf04c2 100644 (file)
 
 #include "osd.h"
 #include "../vm/vm.h"
+#include "../vm/device.h"
+
 #include "emu.h"
 
 #include "emu_thread.h"
 #include "draw_thread.h"
 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
-#include "movie_loader.h"
+#include "avio/movie_loader.h"
+#endif
+#if defined(USE_SOUND_FILES)
+#include "avio/sound_loader.h"
 #endif
-
 #include "qt_gldraw.h"
-#include "agar_logger.h"
+#include "csp_logger.h"
 
 void OSD::vm_draw_screen(void)
 {
@@ -46,7 +50,82 @@ Sint16* OSD::create_sound(int *extra_frames)
        return (Sint16 *)vm->create_sound(extra_frames);
 }
 
+#ifdef USE_SOUND_FILES
+void OSD::load_sound_file(int id, const _TCHAR *name, int16_t **data, int *dst_size)
+{
+       int i = 0;
+       if(data != NULL) *data = NULL;
+       if(dst_size != NULL) *dst_size = 0;
+       if(id <= 0) return;
+
+       for(i = 0; i < USE_SOUND_FILES; i++) {
+               SOUND_LOADER *p = sound_file_obj[i];
+               if(p != NULL) {
+                       if(p->get_id() == id) break;
+               }
+       }
+       
+       if(i >= USE_SOUND_FILES) {
+               for(i = 0; i < USE_SOUND_FILES; i++) {
+                       SOUND_LOADER *p = sound_file_obj[i];
+                       if(p != NULL) {
+                               if(p->get_id() < 0) {
+                                       p->set_id(id);
+                                       break;
+                               }
+                       }
+               }
+       }
+       if(i >= USE_SOUND_FILES) return;
+       SOUND_LOADER *p = sound_file_obj[i];
+       if(p != NULL) {
+               p->free_sound_buffer(NULL);
+               p->set_sound_rate(this->get_sound_rate());
+               if(p->open(id, QString::fromUtf8(name))) {
+                       p->do_decode_frames();
+                       p->close();
+                       if(data != NULL) *data = (int16_t *)(p->get_sound_buffer());
+                       if(dst_size != NULL) *dst_size = p->get_dst_size();
+               }
+       }
+}
+
+void OSD::free_sound_file(int id, int16_t **data)
+{
+       if(data == NULL) return;
+       for(int i = 0; i < USE_SOUND_FILES; i++) {
+               SOUND_LOADER *p = sound_file_obj[i];
+               if(p != NULL) {
+                       if(p->get_id() == id) {
+                               p->free_sound_buffer(*data);
+                               *data = NULL;
+                               break;
+                       }
+               }
+       }
+}
+
+void OSD::init_sound_files()
+{
+       for(int i = 0; i < USE_SOUND_FILES; i++) {
+               sound_file_obj[i] = NULL;
+               SOUND_LOADER *p = new SOUND_LOADER((void *)tail_sound_file);
+               if(p != NULL) {
+                       sound_file_obj[i] = p;
+               }
+               tail_sound_file = p;
+       }
+}
 
+void OSD::release_sound_files()
+{
+       for(int i = 0; i < USE_SOUND_FILES; i++) {
+               SOUND_LOADER *p = sound_file_obj[i];
+               if(p != NULL) delete p;
+               sound_file_obj[i] = NULL;
+       }
+}
+#endif
 bool OSD::get_use_socket(void)
 {
 #ifdef USE_SOCKET
@@ -239,20 +318,24 @@ int OSD::get_screen_height(void)
 void OSD::lock_vm(void)
 {
        locked_vm = true;
-       if(parent_thread != NULL) { 
-               if(!parent_thread->now_debugging()) VMSemaphore->acquire(1);
-       } else {
-               VMSemaphore->acquire(1);
-       }
+       vm_mutex->lock();
+       //if(parent_thread != NULL) { 
+               //if(!parent_thread->now_debugging()) VMSemaphore->acquire(1);
+               //VMSemaphore->acquire(1);
+       //} else {
+       //      VMSemaphore->acquire(1);
+       //}
 }
 
 void OSD::unlock_vm(void)
 {
-       if(parent_thread != NULL) { 
-               if(!parent_thread->now_debugging()) VMSemaphore->release(1);
-       } else {
-               VMSemaphore->release(1);
-       }
+       vm_mutex->unlock();
+       //if(parent_thread != NULL) { 
+       //      //if(!parent_thread->now_debugging()) VMSemaphore->release(1);
+       //      VMSemaphore->release(1);
+       //} else {
+       //      VMSemaphore->release(1);
+       //}
        locked_vm = false;
 }
 
@@ -264,29 +347,20 @@ bool OSD::is_vm_locked(void)
 
 void OSD::force_unlock_vm(void)
 {
-       if(parent_thread == NULL) {
-               while(VMSemaphore->available() < 1) VMSemaphore->release(1);
-               locked_vm = false;
-               return;
-       }
-       if(parent_thread->now_debugging()) {
-               locked_vm = false;
-               return;
-       }
-       while(VMSemaphore->available() < 1) VMSemaphore->release(1);
+       vm_mutex->unlock();
        locked_vm = false;
 }
 
 void OSD::set_draw_thread(DrawThreadClass *handler)
 {
-       this->moveToThread(handler);
+       //this->moveToThread(handler);
        connect(this, SIGNAL(sig_update_screen(bitmap_t *)), handler, SLOT(do_update_screen(bitmap_t *)));
        connect(this, SIGNAL(sig_save_screen(const char *)), glv, SLOT(do_save_frame_screen(const char *)));
        connect(this, SIGNAL(sig_resize_vm_screen(QImage *, int, int)), glv, SLOT(do_set_texture_size(QImage *, int, int)));
+       connect(this, SIGNAL(sig_resize_vm_lines(int)), glv, SLOT(do_set_horiz_lines(int)));
        connect(parent_thread, SIGNAL(sig_debugger_input(QString)), this, SLOT(do_set_input_string(QString)));
        connect(parent_thread, SIGNAL(sig_quit_debugger()), this, SLOT(do_close_debugger_thread()));
        connect(this, SIGNAL(sig_close_window()), parent_thread, SLOT(doExit()));
-       connect(this, SIGNAL(sig_console_input_string(QString)), parent_thread, SLOT(do_call_debugger_command(QString)));
 }
 
 void OSD::initialize_screen()
@@ -346,9 +420,14 @@ void OSD::initialize_video()
        movie_loader = NULL;
 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
        movie_loader = new MOVIE_LOADER(this, &config);
-       connect(movie_saver, SIGNAL(sig_call_sound_callback(uint8_t *, long)), this, SLOT(do_call_sound_callback(uint8 *, long)));
-       connect(movie_saver, SIGNAL(sig_movie_end(bool)), this, SLOT(do_video_movie_end(bool)));
-       connect(movie_saver, SIGNAL(sig_decoding_error(int)), this, SLOT(do_video_decoding_error(int)));
+       //connect(movie_loader, SIGNAL(sig_send_audio_frame(uint8_t *, long)), this, SLOT(do_run_movie_audio_callback2(uint8_t *, long)));
+       connect(movie_loader, SIGNAL(sig_movie_end(bool)), this, SLOT(do_video_movie_end(bool)));
+       connect(this, SIGNAL(sig_movie_play(void)), movie_loader, SLOT(do_play()));
+       connect(this, SIGNAL(sig_movie_stop(void)), movie_loader, SLOT(do_stop()));
+       connect(this, SIGNAL(sig_movie_pause(bool)), movie_loader, SLOT(do_pause(bool)));
+       connect(this, SIGNAL(sig_movie_seek_frame(bool, int)), movie_loader, SLOT(do_seek_frame(bool, int)));
+       //connect(this, SIGNAL(sig_movie_mute(bool, bool)), movie_loader, SLOT(do_mute(bool, bool)));
+       connect(movie_loader, SIGNAL(sig_decoding_error(int)), this, SLOT(do_video_decoding_error(int)));
 #endif 
 }
 
@@ -377,7 +456,7 @@ void OSD::close_movie_file()
 {
 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
        if(movie_loader != NULL) {
-               movie_loadrer->close();
+               movie_loader->close();
        }
 #endif
        now_movie_play = false;
@@ -387,9 +466,9 @@ void OSD::close_movie_file()
 #include <limits.h>
 uint32_t OSD::get_cur_movie_frame()
 {
-       uint64_t pos;
 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
        if(movie_loader != NULL) {
+               uint64_t pos;
                pos = movie_loader->get_current_frame();
                if(pos > UINT_MAX) {
                        return UINT_MAX;
@@ -405,9 +484,9 @@ void OSD::do_run_movie_audio_callback(uint8_t *data, long len)
        if(data == NULL) return;
 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
 #if defined(_PX7)
-       if(this->vm->ld700 != NULL) {
+       {
                lock_vm();
-               this->vm->ld700->movie_sound_callback(data, len);
+               this->vm->movie_sound_callback(data, len);
                unlock_vm();
        }
 #endif
@@ -418,14 +497,414 @@ void OSD::do_run_movie_audio_callback(uint8_t *data, long len)
 void OSD::do_decode_movie(int frames)
 {
 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
-       movie_loader->do_decode_frames(frames);
+       //movie_loader->do_decode_frames(frames, SCREEN_WIDTH, SCREEN_HEIGHT);
+       movie_loader->do_decode_frames(frames, vm_window_width_aspect, vm_window_height_aspect);
 #endif 
 }
 
 void OSD::get_video_buffer()
 {
-#if defined(_PX7)
+#if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
+       //movie_loader->do_decode_frames(1, this->get_vm_window_width(), this->get_vm_window_height());
        movie_loader->get_video_frame();
+       //printf("**\n");
 #endif
 }
 
+int OSD::get_movie_sound_rate()
+{
+#if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
+       return movie_loader->get_movie_sound_rate();
+#endif
+       return 44100;
+}
+
+void OSD::reset_vm_node()
+{
+       device_node_t sp;
+       device_node_list.clear();
+       csp_logger->reset();
+       max_vm_nodes = 0;
+       for(DEVICE *p = vm->first_device; p != NULL; p = p->next_device) {
+               sp.id = p->this_device_id;
+               sp.name = p->this_device_name;
+               csp_logger->set_device_name(sp.id, sp.name);
+               csp_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_GENERAL,  "Device %d :%s", sp.id, sp.name);
+               device_node_list.append(sp);
+               if(max_vm_nodes <= p->this_device_id) max_vm_nodes = p->this_device_id + 1;
+       }
+       for(DEVICE *p = vm->first_device; p != NULL; p = p->next_device) {
+               emit sig_update_device_node_name(p->this_device_id, p->this_device_name);
+       }
+}
+
+#if defined(USE_SOCKET)
+#include <QHostAddress>
+#include "osd_socket.h"
+#endif
+// Socket
+void OSD::initialize_socket()
+{
+       for(int i = 0; i < SOCKET_MAX; i++) {
+               tcp_socket[i] = NULL;
+               udp_socket[i] = NULL;
+               is_tcp[i] = false;
+               socket_delay[i] = 0;
+               host_mode[i] = false;
+       }
+}
+
+void OSD::release_socket()
+{
+       // release sockets
+#ifdef USE_SOCKET
+       for(int i = 0; i < SOCKET_MAX; i++) {
+               if(tcp_socket[i] != NULL) {
+                       if(tcp_socket[i]->isOpen()) tcp_socket[i]->close();
+                       delete tcp_socket[i];
+                       tcp_socket[i] = NULL;
+               }
+               if(udp_socket[i] != NULL) {
+                       if(udp_socket[i]->isOpen()) udp_socket[i]->close();
+                       delete udp_socket[i];
+                       udp_socket[i] = NULL;
+               }
+       }
+#endif 
+}
+
+
+void OSD::notify_socket_connected(int ch)
+{
+       do_notify_socket_connected(ch);
+}
+
+void OSD::do_notify_socket_connected(int ch)
+{
+#ifdef USE_SOCKET
+       vm->notify_socket_connected(ch);
+#endif 
+}
+
+
+void OSD::notify_socket_disconnected(int ch)
+{
+       do_notify_socket_disconnected(ch);
+}
+
+
+void OSD::do_notify_socket_disconnected(int ch)
+{
+       if(!socket_delay[ch]) {
+               socket_delay[ch] = 1;//56;
+       }
+}
+
+// Called per 1 frame.
+void OSD::update_socket()
+{
+#ifdef USE_SOCKET
+       qint64 bytes;
+       for(int i = 0; i < SOCKET_MAX; i++) {
+               QIODevice *p = NULL;
+               if(is_tcp[i]) {
+                       if(tcp_socket[i] != NULL) {
+                               if(tcp_socket[i]->isOpen()) {
+                                       p = tcp_socket[i];
+                               }
+                       }
+               } else {
+                       if(udp_socket[i] != NULL) {
+                               if(udp_socket[i]->isOpen()) {
+                                       p = udp_socket[i];
+                               }
+                       }
+               }
+               if(p != NULL) { 
+                       // recv
+                       bytes = p->bytesAvailable();
+                       if(bytes > 0) {
+                               int size0, size1;
+                               uint8_t* buf0 = vm->get_socket_recv_buffer0(i, &size0, &size1);
+                               uint8_t* buf1 = vm->get_socket_recv_buffer1(i);
+                               qint64 size;
+                               
+                               if(bytes > (qint64)(size0 + size1)) {
+                                       bytes = (qint64)(size0 + size1);
+                               }
+                               QByteArray src = p->read(bytes);
+
+                               size = src.size();
+                               uint8_t *pp = (uint8_t *)(src.constData());
+                               if(size <= (qint64)size0) {
+                                       memcpy(buf0, pp, size);
+                               } else {
+                                       memcpy(buf0, pp, size0);
+                                       memcpy(buf1, pp + size0, (int)size - size0);
+                               }
+                               vm->inc_socket_recv_buffer_ptr(i, (int)size);
+                       } else if(socket_delay[i] != 0) {
+                               if(--socket_delay[i] == 0) {
+                                       vm->notify_socket_disconnected(i);
+                               }
+                       }
+               }
+       }
+#endif 
+}
+
+bool OSD::initialize_socket_tcp(int ch)
+{
+#ifdef USE_SOCKET
+       if(udp_socket[ch] != NULL) {
+               if(udp_socket[ch]->isOpen()) {
+                       udp_socket[ch]->close();
+               }
+               delete udp_socket[ch];
+               udp_socket[ch] = NULL;
+       }
+       if(tcp_socket[ch] != NULL) {
+               if(tcp_socket[ch]->isOpen()) tcp_socket[ch]->close();
+               delete tcp_socket[ch];
+       }
+       is_tcp[ch] = true;
+       tcp_socket[ch] = new QTcpSocket2(ch);
+       if(tcp_socket[ch] == NULL) return false;
+       tcp_socket[ch]->setChannel(ch);
+       connect(tcp_socket[ch], SIGNAL(connected()), tcp_socket[ch], SLOT(do_connected()));
+       connect(tcp_socket[ch], SIGNAL(sig_connected(int)), this, SLOT(do_notify_socket_connected(int)));
+       connect(tcp_socket[ch], SIGNAL(disconnected()), tcp_socket[ch], SLOT(do_disconnected()));
+       connect(tcp_socket[ch], SIGNAL(sig_disconnected(int)), this, SLOT(do_notify_socket_disconnected(int)));
+#endif 
+       return true;
+}
+
+bool OSD::initialize_socket_udp(int ch)
+{
+#ifdef USE_SOCKET
+       if(tcp_socket[ch] != NULL) {
+               if(tcp_socket[ch]->isOpen()) {
+                       tcp_socket[ch]->close();
+               }
+               delete tcp_socket[ch];
+               tcp_socket[ch] = NULL;
+       }
+       if(udp_socket[ch] != NULL) {
+               if(udp_socket[ch]->isOpen()) udp_socket[ch]->close();
+               delete udp_socket[ch];
+       }
+       is_tcp[ch] = false;
+       udp_socket[ch] = new QUdpSocket2(ch);
+       if(udp_socket[ch] == NULL) return false;
+       connect(udp_socket[ch], SIGNAL(connected()), udp_socket[ch], SLOT(do_connected()));
+       connect(udp_socket[ch], SIGNAL(sig_connected(int)), this, SLOT(do_notify_socket_connected(int)));
+       connect(udp_socket[ch], SIGNAL(disconnected()), udp_socket[ch], SLOT(do_disconnected()));
+       connect(udp_socket[ch], SIGNAL(sig_disconnected(int)), this, SLOT(do_notify_socket_disconnected(int)));
+#endif 
+       return true;
+}
+
+bool OSD::connect_socket(int ch, uint32_t ipaddr, int port)
+{
+#ifdef USE_SOCKET
+       QHostAddress addr = QHostAddress((quint32)ipaddr);
+       if(is_tcp[ch]) {
+               if(tcp_socket[ch] != NULL) {
+                       tcp_socket[ch]->connectToHost(addr, (quint16)port);
+               } else {
+                       return false;
+               }
+       } else {
+               if(udp_socket[ch] != NULL) {
+                       udp_socket[ch]->connectToHost(addr, (quint16)port);
+               } else {
+                       return false;
+               }
+       }
+       host_mode[ch] = false;
+#endif
+       return true;
+}
+
+void OSD::disconnect_socket(int ch)
+{
+//     soc[ch] = -1;
+#ifdef USE_SOCKET
+       if(host_mode[ch]) {
+               if(is_tcp[ch]) {
+                       if(tcp_socket[ch] != NULL) {
+                               if(tcp_socket[ch]->isOpen()) tcp_socket[ch]->close();
+                       }
+               } else {
+                       if(udp_socket[ch] != NULL) {
+                               if(udp_socket[ch]->isOpen()) udp_socket[ch]->close();
+                       }
+               }
+       } else {
+               if(is_tcp[ch]) {
+                       if(tcp_socket[ch] != NULL) {
+                               udp_socket[ch]->disconnectFromHost();
+                       }
+               } else {
+                       if(udp_socket[ch] != NULL) {
+                               udp_socket[ch]->disconnectFromHost();
+                       }
+               }
+       }               
+       vm->notify_socket_disconnected(ch);
+#endif 
+}
+
+bool OSD::listen_socket(int ch)
+{
+#ifdef USE_SOCKET
+       //QHostAddress addr = QHostAddress(QHostAddress::AnyIPv4); // OK?
+       // This unit is dummy?
+       //connect(udp_socket[ch], SIGNAL(connected()), udp_socket[ch], SLOT(do_connected()));
+       //connect(udp_socket[ch], SIGNAL(sig_connected(int)), this, SLOT(do_notify_socket_connected(int)));
+       //connect(udp_socket[ch], SIGNAL(disconnected()), udp_socket[ch], SLOT(do_disconnected()));
+       //connect(udp_socket[ch], SIGNAL(sig_disconnected(int)), this, SLOT(do_notify_socket_disconnected(int)));
+#endif 
+       return false;
+}
+
+void OSD::send_socket_data_tcp(int ch)
+{
+#ifdef USE_SOCKET
+       if(is_tcp[ch]) {
+               while(1) {
+                       int size;
+                       uint8_t *buf = vm->get_socket_send_buffer(ch, &size);
+                       if(size <= 0) {
+                               return;
+                       }
+                       qint64 size2 = 0;
+                       if(tcp_socket[ch] != NULL) {
+                               if(tcp_socket[ch]->isWritable()) {
+                                       size2 = tcp_socket[ch]->write((const char *)buf, (qint64)size);
+                                       if(size2 < 0) {
+                                               disconnect_socket(ch);
+                                               notify_socket_disconnected(ch);
+                                               return;
+                                       }
+                               }
+                       } else {
+                               return;
+                       }
+                       vm->inc_socket_send_buffer_ptr(ch, (int)size2);
+               }
+       }
+#endif 
+}
+
+void OSD::send_socket_data_udp(int ch, uint32_t ipaddr, int port)
+{
+#ifdef USE_SOCKET
+       QHostAddress addr = QHostAddress((quint32)ipaddr);
+       if(!is_tcp[ch]) {
+               while(1) {
+                       int size;
+                       uint8_t *buf = vm->get_socket_send_buffer(ch, &size);
+                       if(size <= 0) {
+                               return;
+                       }
+                       qint64 size2 = 0;
+                       
+                       if(udp_socket[ch] != NULL) {
+                               size2 = udp_socket[ch]->writeDatagram((const char *)buf, (qint64)size, addr, (quint16)port);
+                               if(size2 < 0) {
+                                       disconnect_socket(ch);
+                                       notify_socket_disconnected(ch);
+                                       return;
+                               }
+                       } else {
+                               return;
+                       }
+                       vm->inc_socket_send_buffer_ptr(ch, (int)size2);
+               }
+       }
+#endif 
+}
+
+void OSD::send_socket_data(int ch)
+{
+       // This is dummy.
+}
+
+void OSD::recv_socket_data(int ch)
+{
+       // This is dummy.
+}
+
+int OSD::get_socket(int ch)
+{
+#ifdef USE_SOCKET
+       if(is_tcp[ch]) {
+               if(tcp_socket[ch] == NULL) return -1;
+       } else {
+               if(udp_socket[ch] == NULL) return -1;
+       }
+#endif 
+       return ch;
+}
+
+//
+#if defined(USE_SOCKET)
+QTcpSocket2::QTcpSocket2(int channel, QObject *parent) : QTcpSocket(parent)
+{
+       ch = channel;
+}
+
+QTcpSocket2::~QTcpSocket2()
+{
+}
+
+void QTcpSocket2::do_connected(void)
+{
+       emit sig_connected(ch);
+}
+
+void QTcpSocket2::do_disconnected(void)
+{
+       emit sig_disconnected(ch);
+}
+
+void QTcpSocket2::setChannel(int channel)
+{
+       ch = channel;
+}
+
+int QTcpSocket2::getChannel(void)
+{
+       return ch;
+}
+
+QUdpSocket2::QUdpSocket2(int channel, QObject *parent) : QUdpSocket(parent)
+{
+       ch = channel;
+}
+
+QUdpSocket2::~QUdpSocket2()
+{
+}
+
+void QUdpSocket2::do_connected(void)
+{
+       emit sig_connected(ch);
+}
+
+void QUdpSocket2::do_disconnected(void)
+{
+       emit sig_disconnected(ch);
+}
+
+void QUdpSocket2::setChannel(int channel)
+{
+       ch = channel;
+}
+
+int QUdpSocket2::getChannel(void)
+{
+       return ch;
+}
+#endif