OSDN Git Service

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