OSDN Git Service

[General] Merge Upstream 2017-04-02.
[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 #define SCREEN_FILTER_NONE      0
155 #define SCREEN_FILTER_RGB       1
156 #define SCREEN_FILTER_RF        2
157
158 // check memory leaks
159 #ifdef _DEBUG
160 #define _CRTDBG_MAP_ALLOC
161 #include <crtdbg.h>
162 #define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)
163 #define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
164 #endif
165
166 typedef struct bitmap_s {
167         // common
168         inline bool initialized()
169         {
170                 return (hdcDib != NULL);
171         }
172         inline scrntype_t* get_buffer(int y)
173         {
174                 return lpBmp + width * (height - y - 1);
175         }
176         int width, height;
177         // win32 dependent
178         HDC hdcDib;
179         HBITMAP hBmp, hOldBmp;
180         LPBYTE lpBuf;
181         scrntype_t* lpBmp;
182         LPBITMAPINFO lpDib;
183 } bitmap_t;
184
185 typedef struct font_s {
186         // common
187         inline bool initialized()
188         {
189                 return (hFont != NULL);
190         }
191         _TCHAR family[64];
192         int width, height, rotate;
193         bool bold, italic;
194         // win32 dependent
195         HFONT hFont;
196 } font_t;
197
198 typedef struct pen_s {
199         // common
200         inline bool initialized()
201         {
202                 return (hPen != NULL);
203         }
204         int width;
205         uint8_t r, g, b;
206         // win32 dependent
207         HPEN hPen;
208 } pen_t;
209
210 typedef struct {
211         PAVISTREAM pAVICompressed;
212         scrntype_t* lpBmp;
213         LPBITMAPINFOHEADER pbmInfoHeader;
214         DWORD dwAVIFileSize;
215         LONG lAVIFrames;
216         int frames;
217         int result;
218 } rec_video_thread_param_t;
219
220 class FIFO;
221 class FILEIO;
222
223 class OSD
224 {
225 private:
226         int lock_count;
227         
228         // console
229         HANDLE hStdIn, hStdOut;
230         
231         // input
232         void initialize_input();
233         void release_input();
234         
235 #if DIRECTINPUT_VERSION >= 0x0800
236         LPDIRECTINPUT8 lpdi;
237         LPDIRECTINPUTDEVICE8 lpdikey;
238 //      LPDIRECTINPUTDEVICE8 lpdijoy;
239 #else
240         LPDIRECTINPUT lpdi;
241         LPDIRECTINPUTDEVICE lpdikey;
242 //      LPDIRECTINPUTDEVICE lpdijoy;
243 #endif
244         bool dinput_key_available;
245 //      bool dinput_joy_available;
246         
247         uint8_t keycode_conv[256];
248         uint8_t key_status[256];        // windows key code mapping
249         uint8_t key_dik_prev[256];
250 #ifdef USE_SHIFT_NUMPAD_KEY
251         uint8_t key_converted[256];
252         bool key_shift_pressed, key_shift_released;
253 #endif
254         bool key_caps_locked;
255         bool lost_focus;
256         
257 #ifdef USE_JOYSTICK
258         uint32_t joy_status[4];         // joystick #1-#4 (b0 = up, b1 = down, b2 = left, b3 = right, b4- = buttons
259         int joy_num;
260         uint32_t joy_mask[4];
261 #endif
262         
263 #ifdef USE_MOUSE
264         int32_t mouse_status[3];        // x, y, button (b0 = left, b1 = right)
265         bool mouse_enabled;
266 #endif
267         
268         // screen
269         void initialize_screen();
270         void release_screen();
271         void initialize_screen_buffer(bitmap_t *buffer, int width, int height, int mode);
272         void release_screen_buffer(bitmap_t *buffer);
273 #ifdef USE_SCREEN_FILTER
274         void apply_rgb_filter_to_screen_buffer(bitmap_t *source, bitmap_t *dest);
275         void apply_rgb_filter_x3_y3(bitmap_t *source, bitmap_t *dest);
276         void apply_rgb_filter_x3_y2(bitmap_t *source, bitmap_t *dest);
277         void apply_rgb_filter_x2_y3(bitmap_t *source, bitmap_t *dest);
278         void apply_rgb_filter_x2_y2(bitmap_t *source, bitmap_t *dest);
279         void apply_rgb_filter_x1_y1(bitmap_t *source, bitmap_t *dest);
280 #endif
281 //#ifdef USE_SCREEN_ROTATE
282         void rotate_screen_buffer(bitmap_t *source, bitmap_t *dest);
283 //#endif
284         void stretch_screen_buffer(bitmap_t *source, bitmap_t *dest);
285         bool initialize_d3d9();
286         bool initialize_d3d9_surface(bitmap_t *buffer);
287         void release_d3d9();
288         void release_d3d9_surface();
289         void copy_to_d3d9_surface(bitmap_t *buffer);
290         int add_video_frames();
291         
292         bitmap_t vm_screen_buffer;
293 #ifdef USE_SCREEN_FILTER
294         bitmap_t filtered_screen_buffer;
295         bitmap_t tmp_filtered_screen_buffer;
296 #endif
297 //#ifdef USE_SCREEN_ROTATE
298         bitmap_t rotated_screen_buffer;
299 //#endif
300         bitmap_t stretched_screen_buffer;
301         bitmap_t shrinked_screen_buffer;
302         bitmap_t video_screen_buffer;
303         
304         bitmap_t* draw_screen_buffer;
305         
306         int host_window_width, host_window_height;
307         bool host_window_mode;
308         int vm_screen_width, vm_screen_height;
309         int vm_window_width, vm_window_height;
310         int vm_window_width_aspect, vm_window_height_aspect;
311         int draw_screen_width, draw_screen_height;
312         
313         Gdiplus::GdiplusStartupInput gdiSI;
314         ULONG_PTR gdiToken;
315         
316         LPDIRECT3D9 lpd3d9;
317         LPDIRECT3DDEVICE9 lpd3d9Device;
318         LPDIRECT3DSURFACE9 lpd3d9Surface;
319         LPDIRECT3DSURFACE9 lpd3d9OffscreenSurface;
320         
321         _TCHAR video_file_path[_MAX_PATH];
322         int rec_video_fps;
323         double rec_video_run_frames;
324         double rec_video_frames;
325         
326         LPBITMAPINFO lpDibRec;
327         PAVIFILE pAVIFile;
328         PAVISTREAM pAVIStream;
329         PAVISTREAM pAVICompressed;
330         AVICOMPRESSOPTIONS AVIOpts;
331         DWORD dwAVIFileSize;
332         LONG lAVIFrames;
333         HANDLE hVideoThread;
334         rec_video_thread_param_t rec_video_thread_param;
335         
336         bool first_draw_screen;
337         bool first_invalidate;
338         bool self_invalidate;
339         
340         // sound
341         void initialize_sound(int rate, int samples);
342         void release_sound();
343         
344         int sound_rate, sound_samples;
345         bool sound_available, sound_started, sound_muted;
346         
347         LPDIRECTSOUND lpds;
348         LPDIRECTSOUNDBUFFER lpdsPrimaryBuffer, lpdsSecondaryBuffer;
349         bool sound_first_half;
350         
351         _TCHAR sound_file_path[_MAX_PATH];
352         FILEIO* rec_sound_fio;
353         int rec_sound_bytes;
354         int rec_sound_buffer_ptr;
355         
356         // video device
357 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
358         void initialize_video();
359         void release_video();
360         
361         IGraphBuilder *pGraphBuilder;
362         IBaseFilter *pVideoBaseFilter;
363         IBaseFilter *pCaptureBaseFilter;
364         ICaptureGraphBuilder2 *pCaptureGraphBuilder2;
365         ISampleGrabber *pVideoSampleGrabber;
366         IBaseFilter *pSoundBaseFilter;
367         ISampleGrabber *pSoundSampleGrabber;
368         CMySampleGrabberCB *pSoundCallBack;
369         IMediaControl *pMediaControl;
370         IMediaSeeking *pMediaSeeking;
371         IMediaPosition *pMediaPosition;
372         IVideoWindow *pVideoWindow;
373         IBasicVideo *pBasicVideo;
374         IBasicAudio *pBasicAudio;
375         bool bTimeFormatFrame;
376         bool bVerticalReversed;
377         
378         bitmap_t direct_show_screen_buffer;
379         bitmap_t direct_show_stretch_buffer;
380         int direct_show_width, direct_show_height;
381         bool direct_show_mute[2];
382 #endif
383 #ifdef USE_MOVIE_PLAYER
384         double movie_frame_rate;
385         int movie_sound_rate;
386 #endif
387 #ifdef USE_VIDEO_CAPTURE
388         void enum_capture_devs();
389         bool connect_capture_dev(int index, bool pin);
390         int cur_capture_dev_index;
391         int num_capture_devs;
392         _TCHAR capture_dev_name[MAX_CAPTURE_DEVS][256];
393 #endif
394         
395         // socket
396 #ifdef USE_SOCKET
397         void initialize_socket();
398         void release_socket();
399         
400         int soc[SOCKET_MAX];
401         bool is_tcp[SOCKET_MAX];
402         struct sockaddr_in udpaddr[SOCKET_MAX];
403         int socket_delay[SOCKET_MAX];
404         char recv_buffer[SOCKET_MAX][SOCKET_BUFFER_MAX];
405         int recv_r_ptr[SOCKET_MAX], recv_w_ptr[SOCKET_MAX];
406 #endif
407         
408 public:
409         OSD()
410         {
411                 lock_count = 0;
412         }
413         ~OSD() {}
414         
415         // common
416         VM* vm;
417         
418         void initialize(int rate, int samples);
419         void release();
420         void power_off();
421         void suspend();
422         void restore();
423         void lock_vm();
424         void unlock_vm();
425         bool is_vm_locked()
426         {
427                 return (lock_count != 0);
428         }
429         void force_unlock_vm();
430         void sleep(uint32_t ms);
431         
432         // common console
433         void open_console(const _TCHAR* title);
434         void close_console();
435         unsigned int get_console_code_page();
436         bool is_console_active();
437         void set_console_text_attribute(unsigned short attr);
438         void write_console(_TCHAR* buffer, unsigned int length);
439         int read_console_input(_TCHAR* buffer);
440         bool is_console_key_pressed(int vk);
441         void close_debugger_console();
442         
443         // common input
444         void update_input();
445         void key_down(int code, bool repeat);
446         void key_up(int code);
447         void key_down_native(int code, bool repeat);
448         void key_up_native(int code);
449         void key_lost_focus()
450         {
451                 lost_focus = true;
452         }
453 #ifdef USE_MOUSE
454         void enable_mouse();
455         void disable_mouse();
456         void toggle_mouse();
457         bool is_mouse_enabled()
458         {
459                 return mouse_enabled;
460         }
461 #endif
462         uint8_t* get_key_buffer()
463         {
464                 return key_status;
465         }
466 #ifdef USE_JOYSTICK
467         uint32_t* get_joy_buffer()
468         {
469                 return joy_status;
470         }
471 #endif
472 #ifdef USE_MOUSE
473         int32_t* get_mouse_buffer()
474         {
475                 return mouse_status;
476         }
477 #endif
478 #ifdef USE_AUTO_KEY
479         bool now_auto_key;
480 #endif
481         
482         // common screen
483         int get_window_mode_width(int mode);
484         int get_window_mode_height(int mode);
485         void set_host_window_size(int window_width, int window_height, bool window_mode);
486         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);
487         int get_vm_window_width()
488         {
489                 return vm_window_width;
490         }
491         int get_vm_window_height()
492         {
493                 return vm_window_height;
494         }
495         int get_vm_window_width_aspect()
496         {
497                 return vm_window_width_aspect;
498         }
499         int get_vm_window_height_aspect()
500         {
501                 return vm_window_height_aspect;
502         }
503         scrntype_t* get_vm_screen_buffer(int y);
504         int draw_screen();
505 #ifdef ONE_BOARD_MICRO_COMPUTER
506         void reload_bitmap()
507         {
508                 first_invalidate = true;
509         }
510 #endif
511         void capture_screen();
512         bool start_record_video(int fps);
513         void stop_record_video();
514         void restart_record_video();
515         void add_extra_frames(int extra_frames);
516         bool now_record_video;
517 #ifdef USE_SCREEN_FILTER
518         bool screen_skip_line;
519 #endif
520         
521         // common sound
522         void update_sound(int* extra_frames);
523         void mute_sound();
524         void stop_sound();
525         void start_record_sound();
526         void stop_record_sound();
527         void restart_record_sound();
528         bool now_record_sound;
529         
530         // common video device
531 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
532         void get_video_buffer();
533         void mute_video_dev(bool l, bool r);
534 #endif
535 #ifdef USE_MOVIE_PLAYER
536         bool open_movie_file(const _TCHAR* file_path);
537         void close_movie_file();
538         void play_movie();
539         void stop_movie();
540         void pause_movie();
541         double get_movie_frame_rate()
542         {
543                 return movie_frame_rate;
544         }
545         int get_movie_sound_rate()
546         {
547                 return movie_sound_rate;
548         }
549         void set_cur_movie_frame(int frame, bool relative);
550         uint32_t get_cur_movie_frame();
551         bool now_movie_play, now_movie_pause;
552 #endif
553 #ifdef USE_VIDEO_CAPTURE
554         int get_cur_capture_dev_index()
555         {
556                 return cur_capture_dev_index;
557         }
558         int get_num_capture_devs()
559         {
560                 return num_capture_devs;
561         }
562         _TCHAR* get_capture_dev_name(int index)
563         {
564                 return capture_dev_name[index];
565         }
566         void open_capture_dev(int index, bool pin);
567         void close_capture_dev();
568         void show_capture_dev_filter();
569         void show_capture_dev_pin();
570         void show_capture_dev_source();
571         void set_capture_dev_channel(int ch);
572 #endif
573         
574         // common printer
575 #ifdef USE_PRINTER
576         void create_bitmap(bitmap_t *bitmap, int width, int height);
577         void release_bitmap(bitmap_t *bitmap);
578         void create_font(font_t *font, const _TCHAR *family, int width, int height, int rotate, bool bold, bool italic);
579         void release_font(font_t *font);
580         void create_pen(pen_t *pen, int width, uint8_t r, uint8_t g, uint8_t b);
581         void release_pen(pen_t *pen);
582         void clear_bitmap(bitmap_t *bitmap, uint8_t r, uint8_t g, uint8_t b);
583         int get_text_width(bitmap_t *bitmap, font_t *font, const char *text);
584         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);
585         void draw_line_to_bitmap(bitmap_t *bitmap, pen_t *pen, int sx, int sy, int ex, int ey);
586         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);
587         void draw_point_to_bitmap(bitmap_t *bitmap, int x, int y, uint8_t r, uint8_t g, uint8_t b);
588         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);
589 #endif
590         void write_bitmap_to_file(bitmap_t *bitmap, const _TCHAR *file_path);
591         
592         // common socket
593 #ifdef USE_SOCKET
594         int get_socket(int ch)
595         {
596                 return soc[ch];
597         }
598         void notify_socket_connected(int ch);
599         void notify_socket_disconnected(int ch);
600         void update_socket();
601         bool initialize_socket_tcp(int ch);
602         bool initialize_socket_udp(int ch);
603         bool connect_socket(int ch, uint32_t ipaddr, int port);
604         void disconnect_socket(int ch);
605         bool listen_socket(int ch);
606         void send_socket_data_tcp(int ch);
607         void send_socket_data_udp(int ch, uint32_t ipaddr, int port);
608         void send_socket_data(int ch);
609         void recv_socket_data(int ch);
610 #endif
611         
612         // win32 dependent
613         void invalidate_screen();
614         void update_screen(HDC hdc);
615         HWND main_window_handle;
616         HINSTANCE instance_handle;
617         bool vista_or_later;
618 };
619
620 #endif