OSDN Git Service

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