OSDN Git Service

[General] Merge Updtream 2017-03-15 . Still not build all of VMs.
[csp-qt/common_source_project-fm7.git] / source / src / win32 / osd.h
1 /*
2         Skelton for retropc emulator
3
4         Author : Takeda.Toshiya
5         Date   : 2015.11.20-
6
7         [ win32 dependent ]
8 */
9
10 #ifndef _WIN32_OSD_H_
11 #define _WIN32_OSD_H_
12
13 #define DIRECTSOUND_VERSION     0x900
14 #define DIRECT3D_VERSION        0x900
15 // XXX: if your DirectX 9.0 SDK is newer and does not contain dinput.lib,
16 // please change the definition of DIRECTINPUT_VERSION from 0x500 to 0x800
17 #define DIRECTINPUT_VERSION     0x500
18 //#define DIRECTINPUT_VERSION   0x800
19
20 #include <windows.h>
21 #include <windowsx.h>
22 #include <mmsystem.h>
23 #include <process.h>
24 #include <commctrl.h>
25 #include <wingdi.h>
26 #include <gdiplus.h>
27 #include <d3d9.h>
28 #include <d3dx9.h>
29 #include <d3d9types.h>
30 #include <vfw.h>
31 #include <dsound.h>
32 #include <dinput.h>
33 #include "../vm/vm.h"
34 //#include "../emu.h"
35 #include "../config.h"
36
37 #ifdef USE_SOCKET
38 #include <winsock.h>
39 #pragma comment(lib, "wsock32.lib")
40 #endif
41 #pragma comment(lib, "comctl32.lib")
42 #pragma comment(lib, "msimg32.lib")
43 #pragma comment(lib, "gdiplus.lib")
44 using namespace Gdiplus;
45 #pragma comment(lib, "d3d9.lib")
46 #pragma comment(lib, "d3dx9.lib")
47 #pragma comment(lib, "vfw32.lib")
48 #pragma comment(lib, "dsound.lib")
49 #if DIRECTINPUT_VERSION >= 0x0800
50 #pragma comment(lib, "dinput8.lib")
51 #else
52 #pragma comment(lib, "dinput.lib")
53 #endif
54 #pragma comment(lib, "dxguid.lib")
55
56 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
57 #pragma comment(lib, "strmiids.lib")
58 #include <dshow.h>
59 //#include <qedit.h>
60 EXTERN_C const CLSID CLSID_SampleGrabber;
61 EXTERN_C const CLSID CLSID_NullRenderer;
62 EXTERN_C const IID IID_ISampleGrabberCB;
63 MIDL_INTERFACE("0579154A-2B53-4994-B0D0-E773148EFF85")
64 ISampleGrabberCB : public IUnknown {
65 public:
66         virtual HRESULT STDMETHODCALLTYPE SampleCB( double SampleTime,IMediaSample *pSample) = 0;
67         virtual HRESULT STDMETHODCALLTYPE BufferCB( double SampleTime,BYTE *pBuffer,long BufferLen) = 0;
68 };
69 EXTERN_C const IID IID_ISampleGrabber;
70 MIDL_INTERFACE("6B652FFF-11FE-4fce-92AD-0266B5D7C78F")
71 ISampleGrabber : public IUnknown {
72 public:
73         virtual HRESULT STDMETHODCALLTYPE SetOneShot( BOOL OneShot) = 0;
74         virtual HRESULT STDMETHODCALLTYPE SetMediaType( const AM_MEDIA_TYPE *pType) = 0;
75         virtual HRESULT STDMETHODCALLTYPE GetConnectedMediaType( AM_MEDIA_TYPE *pType) = 0;
76         virtual HRESULT STDMETHODCALLTYPE SetBufferSamples( BOOL BufferThem) = 0;
77         virtual HRESULT STDMETHODCALLTYPE GetCurrentBuffer( /* [out][in] */ long *pBufferSize,/* [out] */ long *pBuffer) = 0;
78         virtual HRESULT STDMETHODCALLTYPE GetCurrentSample( /* [retval][out] */ IMediaSample **ppSample) = 0;
79         virtual HRESULT STDMETHODCALLTYPE SetCallback( ISampleGrabberCB *pCallback,long WhichMethodToCallback) = 0;
80 };
81 #endif
82 #ifdef USE_MOVIE_PLAYER
83 class CMySampleGrabberCB : public ISampleGrabberCB {
84 private:
85         VM *vm;
86 public:
87         CMySampleGrabberCB(VM *vm_ptr)
88         {
89                 vm = vm_ptr;
90         }
91         STDMETHODIMP_(ULONG) AddRef()
92         {
93                 return 2;
94         }
95         STDMETHODIMP_(ULONG) Release()
96         {
97                 return 1;
98         }
99         STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
100         {
101                 if(riid == IID_ISampleGrabberCB || riid == IID_IUnknown) {
102                         *ppv = (void *) static_cast<ISampleGrabberCB*>(this);
103                         return NOERROR;
104                 }
105                 return E_NOINTERFACE;
106         }
107         STDMETHODIMP SampleCB(double SampleTime, IMediaSample *pSample)
108         {
109                 return S_OK;
110         }
111         STDMETHODIMP BufferCB(double dblSampleTime, BYTE *pBuffer, long lBufferSize)
112         {
113                 vm->movie_sound_callback(pBuffer, lBufferSize);
114                 return S_OK;
115         }
116 };
117 #endif
118
119 #define WM_RESIZE  (WM_USER + 1)
120 #define WM_SOCKET0 (WM_USER + 2)
121 #define WM_SOCKET1 (WM_USER + 3)
122 #define WM_SOCKET2 (WM_USER + 4)
123 #define WM_SOCKET3 (WM_USER + 5)
124
125 #ifdef USE_SOCKET
126 #define SOCKET_MAX 4
127 #define SOCKET_BUFFER_MAX 0x100000
128 #endif
129
130 #ifdef USE_VIDEO_CAPTURE
131 #define MAX_CAPTURE_DEVS 8
132 #endif
133
134 #define SUPPORT_WIN32_DLL
135
136 // check memory leaks
137 #ifdef _DEBUG
138 #define _CRTDBG_MAP_ALLOC
139 #include <crtdbg.h>
140 #define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)
141 #define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
142 #endif
143
144 typedef struct bitmap_s {
145         // common
146         inline bool initialized()
147         {
148                 return (hdcDib != NULL);
149         }
150         inline scrntype_t* get_buffer(int y)
151         {
152                 return lpBmp + width * (height - y - 1);
153         }
154         int width, height;
155         // win32 dependent
156         HDC hdcDib;
157         HBITMAP hBmp, hOldBmp;
158         LPBYTE lpBuf;
159         scrntype_t* lpBmp;
160         LPBITMAPINFO lpDib;
161 } bitmap_t;
162
163 typedef struct font_s {
164         // common
165         inline bool initialized()
166         {
167                 return (hFont != NULL);
168         }
169         _TCHAR family[64];
170         int width, height, rotate;
171         bool bold, italic;
172         // win32 dependent
173         HFONT hFont;
174 } font_t;
175
176 typedef struct pen_s {
177         // common
178         inline bool initialized()
179         {
180                 return (hPen != NULL);
181         }
182         int width;
183         uint8_t r, g, b;
184         // win32 dependent
185         HPEN hPen;
186 } pen_t;
187
188 typedef struct {
189         PAVISTREAM pAVICompressed;
190         scrntype_t* lpBmp;
191         LPBITMAPINFOHEADER pbmInfoHeader;
192         DWORD dwAVIFileSize;
193         LONG lAVIFrames;
194         int frames;
195         int result;
196 } rec_video_thread_param_t;
197
198 class FIFO;
199 class FILEIO;
200
201 class OSD
202 {
203 private:
204         int lock_count;
205         
206         // console
207         HANDLE hStdIn, hStdOut;
208         
209         // input
210         void initialize_input();
211         void release_input();
212         
213 #if DIRECTINPUT_VERSION >= 0x0800
214         LPDIRECTINPUT8 lpdi;
215         LPDIRECTINPUTDEVICE8 lpdikey;
216 //      LPDIRECTINPUTDEVICE8 lpdijoy;
217 #else
218         LPDIRECTINPUT lpdi;
219         LPDIRECTINPUTDEVICE lpdikey;
220 //      LPDIRECTINPUTDEVICE lpdijoy;
221 #endif
222         bool dinput_key_available;
223 //      bool dinput_joy_available;
224         
225         uint8_t keycode_conv[256];
226         uint8_t key_status[256];        // windows key code mapping
227         uint8_t key_dik_prev[256];
228 #ifdef USE_SHIFT_NUMPAD_KEY
229         uint8_t key_converted[256];
230         bool key_shift_pressed, key_shift_released;
231 #endif
232         bool key_caps_locked;
233         bool lost_focus;
234         
235 #ifdef USE_JOYSTICK
236         uint32_t joy_status[4];         // joystick #1-#4 (b0 = up, b1 = down, b2 = left, b3 = right, b4- = buttons
237         int joy_num;
238         uint32_t joy_mask[4];
239 #endif
240         
241 #ifdef USE_MOUSE
242         int32_t mouse_status[3];        // x, y, button (b0 = left, b1 = right)
243         bool mouse_enabled;
244 #endif
245         
246         // screen
247         void initialize_screen();
248         void release_screen();
249         void initialize_screen_buffer(bitmap_t *buffer, int width, int height, int mode);
250         void release_screen_buffer(bitmap_t *buffer);
251 #ifdef USE_CRT_FILTER
252         void apply_crt_fileter_to_screen_buffer(bitmap_t *source, bitmap_t *dest);
253         void apply_crt_filter_x3_y3(bitmap_t *source, bitmap_t *dest);
254         void apply_crt_filter_x3_y2(bitmap_t *source, bitmap_t *dest);
255         void apply_crt_filter_x2_y3(bitmap_t *source, bitmap_t *dest);
256         void apply_crt_filter_x2_y2(bitmap_t *source, bitmap_t *dest);
257         void apply_crt_filter_x1_y1(bitmap_t *source, bitmap_t *dest);
258 #endif
259 #ifdef USE_SCREEN_ROTATE
260         void rotate_screen_buffer(bitmap_t *source, bitmap_t *dest);
261 #endif
262         void stretch_screen_buffer(bitmap_t *source, bitmap_t *dest);
263         bool initialize_d3d9();
264         bool initialize_d3d9_surface(bitmap_t *buffer);
265         void release_d3d9();
266         void release_d3d9_surface();
267         void copy_to_d3d9_surface(bitmap_t *buffer);
268         int add_video_frames();
269         
270         bitmap_t vm_screen_buffer;
271 #ifdef USE_CRT_FILTER
272         bitmap_t filtered_screen_buffer;
273         bitmap_t tmp_filtered_screen_buffer;
274 #endif
275 #ifdef USE_SCREEN_ROTATE
276         bitmap_t rotated_screen_buffer;
277 #endif
278         bitmap_t stretched_screen_buffer;
279         bitmap_t shrinked_screen_buffer;
280         bitmap_t video_screen_buffer;
281         
282         bitmap_t* draw_screen_buffer;
283         
284         int host_window_width, host_window_height;
285         bool host_window_mode;
286         int vm_screen_width, vm_screen_height;
287         int vm_window_width, vm_window_height;
288         int vm_window_width_aspect, vm_window_height_aspect;
289         int draw_screen_width, draw_screen_height;
290         
291         Gdiplus::GdiplusStartupInput gdiSI;
292         ULONG_PTR gdiToken;
293         
294         LPDIRECT3D9 lpd3d9;
295         LPDIRECT3DDEVICE9 lpd3d9Device;
296         LPDIRECT3DSURFACE9 lpd3d9Surface;
297         LPDIRECT3DSURFACE9 lpd3d9OffscreenSurface;
298         
299         _TCHAR video_file_path[_MAX_PATH];
300         int rec_video_fps;
301         double rec_video_run_frames;
302         double rec_video_frames;
303         
304         LPBITMAPINFO lpDibRec;
305         PAVIFILE pAVIFile;
306         PAVISTREAM pAVIStream;
307         PAVISTREAM pAVICompressed;
308         AVICOMPRESSOPTIONS AVIOpts;
309         DWORD dwAVIFileSize;
310         LONG lAVIFrames;
311         HANDLE hVideoThread;
312         rec_video_thread_param_t rec_video_thread_param;
313         
314         bool first_draw_screen;
315         bool first_invalidate;
316         bool self_invalidate;
317         
318         // sound
319         void initialize_sound(int rate, int samples);
320         void release_sound();
321         
322         int sound_rate, sound_samples;
323         bool sound_available, sound_started, sound_muted;
324         
325         LPDIRECTSOUND lpds;
326         LPDIRECTSOUNDBUFFER lpdsPrimaryBuffer, lpdsSecondaryBuffer;
327         bool sound_first_half;
328         
329         _TCHAR sound_file_path[_MAX_PATH];
330         FILEIO* rec_sound_fio;
331         int rec_sound_bytes;
332         int rec_sound_buffer_ptr;
333         
334         // video device
335 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
336         void initialize_video();
337         void release_video();
338         
339         IGraphBuilder *pGraphBuilder;
340         IBaseFilter *pVideoBaseFilter;
341         IBaseFilter *pCaptureBaseFilter;
342         ICaptureGraphBuilder2 *pCaptureGraphBuilder2;
343         ISampleGrabber *pVideoSampleGrabber;
344         IBaseFilter *pSoundBaseFilter;
345         ISampleGrabber *pSoundSampleGrabber;
346         CMySampleGrabberCB *pSoundCallBack;
347         IMediaControl *pMediaControl;
348         IMediaSeeking *pMediaSeeking;
349         IMediaPosition *pMediaPosition;
350         IVideoWindow *pVideoWindow;
351         IBasicVideo *pBasicVideo;
352         IBasicAudio *pBasicAudio;
353         bool bTimeFormatFrame;
354         bool bVerticalReversed;
355         
356         bitmap_t direct_show_screen_buffer;
357         bitmap_t direct_show_stretch_buffer;
358         int direct_show_width, direct_show_height;
359         bool direct_show_mute[2];
360 #endif
361 #ifdef USE_MOVIE_PLAYER
362         double movie_frame_rate;
363         int movie_sound_rate;
364 #endif
365 #ifdef USE_VIDEO_CAPTURE
366         void enum_capture_devs();
367         bool connect_capture_dev(int index, bool pin);
368         int cur_capture_dev_index;
369         int num_capture_devs;
370         _TCHAR capture_dev_name[MAX_CAPTURE_DEVS][256];
371 #endif
372         
373         // socket
374 #ifdef USE_SOCKET
375         void initialize_socket();
376         void release_socket();
377         
378         int soc[SOCKET_MAX];
379         bool is_tcp[SOCKET_MAX];
380         struct sockaddr_in udpaddr[SOCKET_MAX];
381         int socket_delay[SOCKET_MAX];
382         char recv_buffer[SOCKET_MAX][SOCKET_BUFFER_MAX];
383         int recv_r_ptr[SOCKET_MAX], recv_w_ptr[SOCKET_MAX];
384 #endif
385         
386 public:
387         OSD()
388         {
389                 lock_count = 0;
390         }
391         ~OSD() {}
392         
393         // common
394         VM* vm;
395         
396         void initialize(int rate, int samples);
397         void release();
398         void power_off();
399         void suspend();
400         void restore();
401         void lock_vm();
402         void unlock_vm();
403         bool is_vm_locked()
404         {
405                 return (lock_count != 0);
406         }
407         void force_unlock_vm();
408         void sleep(uint32_t ms);
409         
410         // common console
411         void open_console(const _TCHAR* title);
412         void close_console();
413         unsigned int get_console_code_page();
414         bool is_console_active();
415         void set_console_text_attribute(unsigned short attr);
416         void write_console(_TCHAR* buffer, unsigned int length);
417         int read_console_input(_TCHAR* buffer);
418         bool is_console_key_pressed(int vk);
419         void close_debugger_console();
420         
421         // common input
422         void update_input();
423         void key_down(int code, bool repeat);
424         void key_up(int code);
425         void key_down_native(int code, bool repeat);
426         void key_up_native(int code);
427         void key_lost_focus()
428         {
429                 lost_focus = true;
430         }
431 #ifdef USE_MOUSE
432         void enable_mouse();
433         void disable_mouse();
434         void toggle_mouse();
435         bool is_mouse_enabled()
436         {
437                 return mouse_enabled;
438         }
439 #endif
440         uint8_t* get_key_buffer()
441         {
442                 return key_status;
443         }
444 #ifdef USE_JOYSTICK
445         uint32_t* get_joy_buffer()
446         {
447                 return joy_status;
448         }
449 #endif
450 #ifdef USE_MOUSE
451         int32_t* get_mouse_buffer()
452         {
453                 return mouse_status;
454         }
455 #endif
456 #ifdef USE_AUTO_KEY
457         bool now_auto_key;
458 #endif
459         
460         // common screen
461         int get_window_mode_width(int mode);
462         int get_window_mode_height(int mode);
463         void set_host_window_size(int window_width, int window_height, bool window_mode);
464         void set_vm_screen_size(int screen_width, int screen_height, int window_width, int window_height, int window_width_aspect, int window_height_aspect);
465         int get_vm_window_width()
466         {
467                 return vm_window_width;
468         }
469         int get_vm_window_height()
470         {
471                 return vm_window_height;
472         }
473         int get_vm_window_width_aspect()
474         {
475                 return vm_window_width_aspect;
476         }
477         int get_vm_window_height_aspect()
478         {
479                 return vm_window_height_aspect;
480         }
481         scrntype_t* get_vm_screen_buffer(int y);
482         int draw_screen();
483 #ifdef ONE_BOARD_MICRO_COMPUTER
484         void reload_bitmap()
485         {
486                 first_invalidate = true;
487         }
488 #endif
489         void capture_screen();
490         bool start_record_video(int fps);
491         void stop_record_video();
492         void restart_record_video();
493         void add_extra_frames(int extra_frames);
494         bool now_record_video;
495 #ifdef USE_CRT_FILTER
496         bool screen_skip_line;
497 #endif
498         
499         // common sound
500         void update_sound(int* extra_frames);
501         void mute_sound();
502         void stop_sound();
503         void start_record_sound();
504         void stop_record_sound();
505         void restart_record_sound();
506         bool now_record_sound;
507         
508         // common video device
509 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
510         void get_video_buffer();
511         void mute_video_dev(bool l, bool r);
512 #endif
513 #ifdef USE_MOVIE_PLAYER
514         bool open_movie_file(const _TCHAR* file_path);
515         void close_movie_file();
516         void play_movie();
517         void stop_movie();
518         void pause_movie();
519         double get_movie_frame_rate()
520         {
521                 return movie_frame_rate;
522         }
523         int get_movie_sound_rate()
524         {
525                 return movie_sound_rate;
526         }
527         void set_cur_movie_frame(int frame, bool relative);
528         uint32_t get_cur_movie_frame();
529         bool now_movie_play, now_movie_pause;
530 #endif
531 #ifdef USE_VIDEO_CAPTURE
532         int get_cur_capture_dev_index()
533         {
534                 return cur_capture_dev_index;
535         }
536         int get_num_capture_devs()
537         {
538                 return num_capture_devs;
539         }
540         _TCHAR* get_capture_dev_name(int index)
541         {
542                 return capture_dev_name[index];
543         }
544         void open_capture_dev(int index, bool pin);
545         void close_capture_dev();
546         void show_capture_dev_filter();
547         void show_capture_dev_pin();
548         void show_capture_dev_source();
549         void set_capture_dev_channel(int ch);
550 #endif
551         
552         // common printer
553 #ifdef USE_PRINTER
554         void create_bitmap(bitmap_t *bitmap, int width, int height);
555         void release_bitmap(bitmap_t *bitmap);
556         void create_font(font_t *font, const _TCHAR *family, int width, int height, int rotate, bool bold, bool italic);
557         void release_font(font_t *font);
558         void create_pen(pen_t *pen, int width, uint8_t r, uint8_t g, uint8_t b);
559         void release_pen(pen_t *pen);
560         void clear_bitmap(bitmap_t *bitmap, uint8_t r, uint8_t g, uint8_t b);
561         int get_text_width(bitmap_t *bitmap, font_t *font, const char *text);
562         void draw_text_to_bitmap(bitmap_t *bitmap, font_t *font, int x, int y, const char *text, uint8_t r, uint8_t g, uint8_t b);
563         void draw_line_to_bitmap(bitmap_t *bitmap, pen_t *pen, int sx, int sy, int ex, int ey);
564         void draw_rectangle_to_bitmap(bitmap_t *bitmap, int x, int y, int width, int height, uint8_t r, uint8_t g, uint8_t b);
565         void draw_point_to_bitmap(bitmap_t *bitmap, int x, int y, uint8_t r, uint8_t g, uint8_t b);
566         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);
567 #endif
568         void write_bitmap_to_file(bitmap_t *bitmap, const _TCHAR *file_path);
569         
570         // common socket
571 #ifdef USE_SOCKET
572         int get_socket(int ch)
573         {
574                 return soc[ch];
575         }
576         void notify_socket_connected(int ch);
577         void notify_socket_disconnected(int ch);
578         void update_socket();
579         bool initialize_socket_tcp(int ch);
580         bool initialize_socket_udp(int ch);
581         bool connect_socket(int ch, uint32_t ipaddr, int port);
582         void disconnect_socket(int ch);
583         bool listen_socket(int ch);
584         void send_socket_data_tcp(int ch);
585         void send_socket_data_udp(int ch, uint32_t ipaddr, int port);
586         void send_socket_data(int ch);
587         void recv_socket_data(int ch);
588 #endif
589         
590         // win32 dependent
591         void update_screen(HDC hdc);
592         HWND main_window_handle;
593         HINSTANCE instance_handle;
594         bool vista_or_later;
595 };
596
597 #endif