OSDN Git Service

[VM][General][Qt] Merge upstream 2015-12-31.
[csp-qt/common_source_project-fm7.git] / source / src / qt / osd.h
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 #ifndef _QT_OSD_H_
11 #define _QT_OSD_H_
12
13
14 #include <QWidget>
15 #include <QThread>
16 #include <QMutex>
17 #include <QSemaphore>
18 #include <QPainter>
19
20 #include <SDL.h>
21 #include <ctime>
22
23 #include "../vm/vm.h"
24 //#include "../emu.h"
25 #include "../config.h"
26 #include "../fileio.h"
27 #include "../fifo.h"
28 #if !defined(Q_OS_WIN32)
29 #include "qt_input.h"
30 #endif
31
32 typedef struct {
33    Sint16 **pSoundBuf;
34    int *uBufSize;
35    int *nSndWritePos;
36    int *nSndDataLen;
37    SDL_sem **pSndApplySem;
38    Uint8 *iTotalVolume;
39    bool *bSndExit;
40    bool *bSoundDebug;
41 } sdl_snddata_t;
42
43
44 #if 0 // TODO
45 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
46 ISampleGrabberCB : public IUnknown {
47 public:
48         virtual HRESULT STDMETHODCALLTYPE SampleCB( double SampleTime,IMediaSample *pSample) = 0;
49         virtual HRESULT STDMETHODCALLTYPE BufferCB( double SampleTime,BYTE *pBuffer,long BufferLen) = 0;
50 };
51 EXTERN_C const IID IID_ISampleGrabber;
52 MIDL_INTERFACE("6B652FFF-11FE-4fce-92AD-0266B5D7C78F")
53 ISampleGrabber : public IUnknown {
54 public:
55         virtual HRESULT STDMETHODCALLTYPE SetOneShot( BOOL OneShot) = 0;
56         virtual HRESULT STDMETHODCALLTYPE SetMediaType( const AM_MEDIA_TYPE *pType) = 0;
57         virtual HRESULT STDMETHODCALLTYPE GetConnectedMediaType( AM_MEDIA_TYPE *pType) = 0;
58         virtual HRESULT STDMETHODCALLTYPE SetBufferSamples( BOOL BufferThem) = 0;
59         virtual HRESULT STDMETHODCALLTYPE GetCurrentBuffer( /* [out][in] */ long *pBufferSize,/* [out] */ long *pBuffer) = 0;
60         virtual HRESULT STDMETHODCALLTYPE GetCurrentSample( /* [retval][out] */ IMediaSample **ppSample) = 0;
61         virtual HRESULT STDMETHODCALLTYPE SetCallback( ISampleGrabberCB *pCallback,long WhichMethodToCallback) = 0;
62 };
63 #endif
64 #ifdef USE_MOVIE_PLAYER
65 class CMySampleGrabberCB : public ISampleGrabberCB {
66 private:
67         VM *vm;
68 public:
69         CMySampleGrabberCB(VM *vm_ptr)
70         {
71                 vm = vm_ptr;
72         }
73         STDMETHODIMP_(ULONG) AddRef()
74         {
75                 return 2;
76         }
77         STDMETHODIMP_(ULONG) Release()
78         {
79                 return 1;
80         }
81         STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
82         {
83                 if(riid == IID_ISampleGrabberCB || riid == IID_IUnknown) {
84                         *ppv = (void *) static_cast<ISampleGrabberCB*>(this);
85                         return NOERROR;
86                 }
87                 return E_NOINTERFACE;
88         }
89         STDMETHODIMP SampleCB(double SampleTime, IMediaSample *pSample)
90         {
91                 return S_OK;
92         }
93         STDMETHODIMP BufferCB(double dblSampleTime, BYTE *pBuffer, long lBufferSize)
94         {
95                 vm->movie_sound_callback(pBuffer, lBufferSize);
96                 return S_OK;
97         }
98 };
99 #endif
100 #endif
101
102 #define WM_RESIZE  (WM_USER + 1)
103 #define WM_SOCKET0 (WM_USER + 2)
104 #define WM_SOCKET1 (WM_USER + 3)
105 #define WM_SOCKET2 (WM_USER + 4)
106 #define WM_SOCKET3 (WM_USER + 5)
107
108 #ifdef USE_SOCKET
109 #define SOCKET_MAX 4
110 #define SOCKET_BUFFER_MAX 0x100000
111 #endif
112
113 #ifdef USE_VIDEO_CAPTURE
114 #define MAX_CAPTURE_DEVS 8
115 #endif
116
117 // check memory leaks
118 #ifdef _DEBUG
119 //#define _CRTDBG_MAP_ALLOC
120 //#include <crtdbg.h>
121 //#define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)
122 //#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
123 #endif
124
125
126 typedef struct bitmap_s {
127         int width, height;
128         QImage pImage;
129         scrntype *get_buffer(int y) {
130                 return (scrntype *)pImage.scanLine(y);
131         };
132         scrntype* lpBuf;
133         QPainter hPainter;
134 } bitmap_t;
135
136 typedef struct font_s {
137         // common
138         _TCHAR family[64];
139         int width, height;
140         int rotate;
141         bool bold, italic;
142         bool init_flag;
143         bool initialized(void) {
144                 return init_flag;
145         };
146         // win32 dependent
147         QFont hFont;
148 } font_t;
149
150 typedef struct pen_s {
151         // common
152         int width;
153         uint8 r, g, b;
154         // win32 dependent
155         QPen hPen;
156 } pen_t;
157
158
159 typedef struct {
160         //PAVISTREAM pAVICompressed;
161         scrntype* lpBmp;
162         //LPBITMAPINFOHEADER pbmInfoHeader;
163         DWORD dwAVIFileSize;
164         UINT64 lAVIFrames;
165         int frames;
166         int result;
167 } rec_video_thread_param_t;
168
169 #include "qt_main.h"
170 #include "mainwidget.h"
171 #include "agar_logger.h"
172
173 class GLDrawClass;
174 class EmuThreadClass;
175 class DrawThreadClass;
176 class Ui_MainWindow;
177 class EMU;
178 class VM;
179 class FIFO;
180
181 QT_BEGIN_NAMESPACE
182 class OSD : public QThread
183 {
184         Q_OBJECT
185 protected:
186 //      VM* vm;
187 //      EMU* emu;
188         EmuThreadClass *parent_thread;
189         QSemaphore *VMSemaphore;
190         _TCHAR auto_key_str[2048];
191         sdl_snddata_t snddata;
192         private:
193         _TCHAR app_path[_MAX_PATH];
194         
195         // console
196         FILE *hStdIn, *hStdOut;
197         char console_string[128];
198         bool osd_console_opened;
199         // input
200         void initialize_input();
201         void release_input();
202         void key_down_sub(int code, bool repeat);
203         void key_up_sub(int code);
204         scrntype *get_buffer(bitmap_t *p, int y);
205         bool dinput_key_ok;
206 //      bool dinput_joy_ok;
207         
208         uint8 keycode_conv[256];
209         uint8 key_status[256];  // windows key code mapping
210         uint8 key_dik_prev[256];
211 #ifdef USE_SHIFT_NUMPAD_KEY
212         uint8 key_converted[256];
213         bool key_shift_pressed, key_shift_released;
214 #endif
215         uint32_t modkey_status;
216         bool lost_focus;
217         
218         uint32 joy_status[2];   // joystick #1, #2 (b0 = up, b1 = down, b2 = left, b3 = right, b4- = buttons
219         int joy_num;
220         uint32 joy_mask[2];
221         
222         int mouse_status[3];    // x, y, button (b0 = left, b1 = right)
223         bool mouse_enabled;
224         int mouse_ptrx;
225         int mouse_ptry;
226         int mouse_button;
227         int mouse_oldx;
228         int mouse_oldy;
229         Qt::CursorShape mouse_shape;
230         
231 #ifdef USE_AUTO_KEY
232         FIFO* autokey_buffer;
233         int autokey_phase, autokey_shift;
234         int autokey_table[256];
235 #endif
236         
237         // printer
238         
239         // screen
240         void initialize_screen();
241         void release_screen();
242         void initialize_screen_buffer(bitmap_t *buffer, int width, int height, int mode);
243         void release_screen_buffer(bitmap_t *buffer);
244 #ifdef USE_SCREEN_ROTATE
245         void rotate_screen_buffer(bitmap_t *source, bitmap_t *dest);
246 #endif
247         void stretch_screen_buffer(bitmap_t *source, bitmap_t *dest);
248         int add_video_frames();
249         
250         bitmap_t vm_screen_buffer;
251         bitmap_t video_screen_buffer;
252         bitmap_t* draw_screen_buffer;
253         
254         int host_window_width, host_window_height;
255         bool host_window_mode;
256         int base_window_width, base_window_height;
257         int vm_screen_width, vm_screen_height, vm_screen_width_aspect, vm_screen_height_aspect;
258         int draw_screen_width, draw_screen_height;
259         
260         
261         _TCHAR video_file_name[_MAX_PATH];
262         int rec_video_fps;
263         double rec_video_run_frames;
264         double rec_video_frames;
265         
266         //LPBITMAPINFO lpDibRec;
267         //PAVIFILE pAVIFile;
268         //PAVISTREAM pAVIStream;
269         //PAVISTREAM pAVICompressed;
270         //AVICOMPRESSOPTIONS AVIOpts;
271         DWORD dwAVIFileSize;
272         UINT64 lAVIFrames;
273         //HANDLE hVideoThread;
274         rec_video_thread_param_t rec_video_thread_param;
275         
276         bool first_draw_screen;
277         bool first_invalidate;
278         bool self_invalidate;
279         
280         // sound
281         void initialize_sound(int rate, int samples);
282         void release_sound();
283         
284         int sound_rate, sound_samples;
285         bool sound_ok, sound_started, now_mute;
286         bool sound_first_half;
287         
288         _TCHAR sound_file_name[_MAX_PATH];
289         FILEIO* rec_sound_fio;
290         int rec_sound_bytes;
291         int rec_sound_buffer_ptr;
292         
293         
294 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
295         // video device
296         void initialize_video();
297         void release_video();
298         
299         //IGraphBuilder *pGraphBuilder;
300         //IBaseFilter *pVideoBaseFilter;
301         //IBaseFilter *pCaptureBaseFilter;
302         //ICaptureGraphBuilder2 *pCaptureGraphBuilder2;
303         //ISampleGrabber *pVideoSampleGrabber;
304         //IBaseFilter *pSoundBaseFilter;
305         //ISampleGrabber *pSoundSampleGrabber;
306         //CMySampleGrabberCB *pSoundCallBack;
307         //IMediaControl *pMediaControl;
308         //IMediaSeeking *pMediaSeeking;
309         //IMediaPosition *pMediaPosition;
310         //IVideoWindow *pVideoWindow;
311         //IBasicVideo *pBasicVideo;
312         //IBasicAudio *pBasicAudio;
313         //bool bTimeFormatFrame;
314         //bool bVerticalReversed;
315         
316         bitmap_t dshow_screen_buffer;
317         int direct_show_width, direct_show_height;
318         bool direct_show_mute[2];
319 #endif
320 #ifdef USE_MOVIE_PLAYER
321         double movie_frame_rate;
322         int movie_sound_rate;
323 #endif
324 #ifdef USE_VIDEO_CAPTURE
325         void enum_capture_devs();
326         bool connect_capture_dev(int index, bool pin);
327         int cur_capture_dev_index;
328         int num_capture_devs;
329         _TCHAR capture_dev_name[MAX_CAPTURE_DEVS][256];
330 #endif
331         _TCHAR prn_file_name[_MAX_PATH];
332         FILEIO *prn_fio;
333         int prn_data, prn_wait_frames;
334         bool prn_strobe;
335
336         // socket
337 #ifdef USE_SOCKET
338         void initialize_socket();
339         void release_socket();
340         
341         int soc[SOCKET_MAX];
342         bool is_tcp[SOCKET_MAX];
343         //struct sockaddr_in udpaddr[SOCKET_MAX];
344         int socket_delay[SOCKET_MAX];
345         char recv_buffer[SOCKET_MAX][SOCKET_BUFFER_MAX];
346         int recv_r_ptr[SOCKET_MAX], recv_w_ptr[SOCKET_MAX];
347 #endif
348         
349 public:
350         OSD();
351         ~OSD();
352         
353         // common
354         VM* vm;
355         //EMU* emu;
356         class Ui_MainWindow *main_window_handle;
357         GLDrawClass *glv;
358         int host_cpus;
359         
360         void initialize(int rate, int samples);
361         void release();
362         void power_off();
363         void suspend();
364         void restore();
365         _TCHAR* application_path()
366         {
367                 return app_path;
368         }
369         _TCHAR* bios_path(const _TCHAR* file_name);
370         void get_host_time(cur_time_t* time);
371         void sleep(uint32 ms);
372         void create_date_file_name(_TCHAR *name, int length, const _TCHAR *extension);
373         
374         // common console
375         void open_console(_TCHAR* title);
376         void close_console();
377         unsigned int get_console_code_page();
378         bool is_console_active();
379         void set_console_text_attribute(unsigned short attr);
380         void write_console(_TCHAR* buffer, unsigned int length);
381         int read_console_input(_TCHAR* buffer);
382         
383         // common input
384         void update_input();
385         void key_down(int code, bool repeat);
386         void key_up(int code);
387         void key_lost_focus()
388         {
389                 lost_focus = true;
390         }
391 #ifdef ONE_BOARD_MICRO_COMPUTER
392         void press_button(int num);
393 #endif
394 # if !defined(Q_OS_WIN) && !defined(Q_OS_CYGWIN)
395         uint16_t GetAsyncKeyState(uint32_t vk);  // Win32 GetAsyncKeyState() wrappeer.
396 # endif
397         void key_modifiers(uint32 mod) {
398                 modkey_status = mod;
399         }
400         void enable_mouse();
401         void disenable_mouse();
402         void toggle_mouse();
403         bool get_mouse_enabled()
404         {
405                 return mouse_enabled;
406         }
407         //QImage *getPseudoVramClass(void) { return pPseudoVram;}
408         void set_mouse_pointer(int x, int y) {
409                 mouse_ptrx = x;
410                 mouse_ptry = y;
411         }
412         void set_mouse_button(int button) {
413                 mouse_button = button;
414         }
415         int get_mouse_button() {
416                 return mouse_button;
417         }
418 #ifdef USE_AUTO_KEY
419         void start_auto_key();
420         void stop_auto_key();
421         bool now_auto_key()
422         {
423                 return (autokey_phase != 0);
424         }
425 #endif
426         uint8* key_buffer()
427         {
428                 return key_status;
429         }
430         uint32* joy_buffer()
431         {
432                 return joy_status;
433         }
434         int* mouse_buffer()
435         {
436                 return mouse_status;
437         }
438         
439         // common printer
440         void reset_printer() {
441                 close_printer_file();
442                 prn_data = -1;
443                 prn_strobe = false;
444         }
445         void update_printer() {
446                 if(prn_fio->IsOpened() && --prn_wait_frames == 0) {
447                         close_printer_file();
448                 }
449         }
450         void printer_out(uint8 value) {
451                 prn_data = value;
452         }
453         void printer_strobe(bool value) {
454                 bool falling = (prn_strobe && !value);
455                 prn_strobe = value;
456         
457                 if(falling) {
458                         if(!prn_fio->IsOpened()) {
459                                 if(prn_data == -1) {
460                                         return;
461                                 }
462                                 open_printer_file();
463                         }
464                         prn_fio->Fputc(prn_data);
465                         // wait 10sec
466 #ifdef SUPPORT_VARIABLE_TIMING
467                         prn_wait_frames = (int)(vm->frame_rate() * 10.0 + 0.5);
468 #else
469                         prn_wait_frames = (int)(FRAMES_PER_SEC * 10.0 + 0.5);
470 #endif
471                 }
472         }
473         // printer
474         void initialize_printer();
475         void release_printer();
476         void open_printer_file() {
477                 create_date_file_name(prn_file_name, _MAX_PATH, _T("txt"));
478                 prn_fio->Fopen(bios_path(prn_file_name), FILEIO_WRITE_BINARY);
479         }
480
481         void close_printer_file() {
482                 if(prn_fio->IsOpened()) {
483                         // remove if the file size is less than 2 bytes
484                         bool remove = (prn_fio->Ftell() < 2);
485                         prn_fio->Fclose();
486                         if(remove) {
487                                 FILEIO::RemoveFile(bios_path(prn_file_name));
488                         }
489                 }
490         }
491         
492         // common screen
493         int get_window_width(int mode);
494         int get_window_height(int mode);
495         void set_window_size(int window_width, int window_height, bool window_mode);
496         void set_vm_screen_size(int width, int height, int width_aspect, int height_aspect, int window_width, int window_height);
497         scrntype* get_vm_screen_buffer(int y);
498         int draw_screen();
499 #ifdef ONE_BOARD_MICRO_COMPUTER
500         void reload_bitmap()
501         {
502                 first_invalidate = true;
503         }
504 #endif
505         void capture_screen();
506         bool start_rec_video(int fps);
507         void stop_rec_video();
508         void restart_rec_video();
509         void add_extra_frames(int extra_frames);
510         bool now_rec_video;
511 #ifdef USE_CRT_FILTER
512         bool screen_skip_line;
513 #endif
514
515         // common sound
516         void update_sound(int* extra_frames);
517         void mute_sound();
518         void stop_sound();
519         void start_rec_sound();
520         void stop_rec_sound();
521         void restart_rec_sound();
522         bool now_rec_sound;
523         
524 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
525         // common video device
526         void get_video_buffer();
527         void mute_video_dev(bool l, bool r);
528 #endif
529 #ifdef USE_MOVIE_PLAYER
530         bool open_movie_file(const _TCHAR* file_path);
531         void close_movie_file();
532         void play_movie();
533         void stop_movie();
534         void pause_movie();
535         double get_movie_frame_rate()
536         {
537                 return movie_frame_rate;
538         }
539         int get_movie_sound_rate()
540         {
541                 return movie_sound_rate;
542         }
543         void set_cur_movie_frame(int frame, bool relative);
544         uint32 get_cur_movie_frame();
545         bool now_movie_play, now_movie_pause;
546 #endif
547 #ifdef USE_VIDEO_CAPTURE
548         int get_cur_capture_dev_index()
549         {
550                 return cur_capture_dev_index;
551         }
552         int get_num_capture_devs()
553         {
554                 return num_capture_devs;
555         }
556         _TCHAR* get_capture_dev_name(int index)
557         {
558                 return capture_dev_name[index];
559         }
560         void open_capture_dev(int index, bool pin);
561         void close_capture_dev();
562         void show_capture_dev_filter();
563         void show_capture_dev_pin();
564         void show_capture_dev_source();
565         void set_capture_dev_channel(int ch);
566 #endif
567         
568         // common printer
569 #ifdef USE_PRINTER
570         void create_bitmap(bitmap_t *bitmap, int width, int height);
571         void release_bitmap(bitmap_t *bitmap);
572         void create_font(font_t *font, const _TCHAR *family, int width, int height, int rotate, bool bold, bool italic);
573         void release_font(font_t *font);
574         void create_pen(pen_t *pen, int width, uint8 r, uint8 g, uint8 b);
575         void release_pen(pen_t *pen);
576
577         void clear_bitmap(bitmap_t *bitmap, uint8 r, uint8 g, uint8 b);
578         int get_text_width(bitmap_t *bitmap, font_t *font, const char *text);
579         
580         void draw_text_to_bitmap(bitmap_t *bitmap, font_t *font, int x, int y, const _TCHAR *text, uint8 r, uint8 g, uint8 b);
581         void draw_line_to_bitmap(bitmap_t *bitmap, pen_t *pen, int sx, int sy, int ex, int ey);
582         void draw_rectangle_to_bitmap(bitmap_t *bitmap, int x, int y, int width, int height, uint8 r, uint8 g, uint8 b);
583         void draw_point_to_bitmap(bitmap_t *bitmap, int x, int y, uint8 r, uint8 g, uint8 b);
584
585         void stretch_bitmap(bitmap_t *dest, int dest_x, int dest_y, int dest_width, int dest_height, bitmap_t *source, int source_x, int source_y, int source_width, int source_height);
586 #endif
587         void write_bitmap_to_file(bitmap_t *bitmap, const _TCHAR *file_path);
588
589         // common socket
590 #ifdef USE_SOCKET
591         int get_socket(int ch)
592         {
593                 return soc[ch];
594         }
595         void socket_connected(int ch);
596         void socket_disconnected(int ch);
597         void update_socket();
598         bool init_socket_tcp(int ch);
599         bool init_socket_udp(int ch);
600         bool connect_socket(int ch, uint32 ipaddr, int port);
601         void disconnect_socket(int ch);
602         bool listen_socket(int ch);
603         void send_data_tcp(int ch);
604         void send_data_udp(int ch, uint32 ipaddr, int port);
605         void send_data(int ch);
606         void recv_data(int ch);
607 #endif
608
609         // win32 dependent
610         void update_screen();
611         void set_parent_thread(EmuThreadClass *parent);
612         EmuThreadClass *get_parent_handler();
613         void set_draw_thread(DrawThreadClass *handler);
614         _TCHAR *console_input_string(void);
615         void clear_console_input_string(void);
616         void lock_vm(void);
617         void unlock_vm(void);
618         void force_unlock_vm(void);
619
620 public slots:
621 #ifdef USE_AUTO_KEY
622         void set_auto_key_string(QByteArray);
623 #endif
624         void do_write_inputdata(QString s);
625         void do_set_input_string(QString s);
626         void do_close_debugger_console();
627         void do_close_debugger_thread();
628         
629 signals:
630         int sig_update_screen(bitmap_t *);
631         int sig_save_screen(const char *);
632         int sig_close_window(void);
633         int sig_resize_vm_screen(QImage *, int, int);
634         int sig_put_string_debugger(QString);
635         int sig_console_input_string(QString);
636         int sig_debugger_finished();
637 };
638 QT_END_NAMESPACE
639
640 #endif